xuhao 发布的文章

一、背景

最近,工作项目中需要用到指定区域截图的功能,我们常见的方式有HtmlToCanvas这种方式,但是在实现的过程中,发现由于HtmlToCanvas这种第三方库对于一些样式的支持还不够友好,因此带来了一些新的问题,且这些问题并不很好解决。于是,我决定盘点下截图的所有流行方式。并做下对比,从中选出效果最好的方案来。Come on!

二、解决方案对比

1、HtmlToCanvas

众所周知,HtmlToCanvas这种方案也是属于很常见的方式,目前Git上已经迭代至1.6版本了。但是对于由Element-UI库的组件去截图,会有一些棘手的问题。

(1)在新的生成截图的效果中,类型为textarea的Input控件,会出现不支持折行,多行数据只显示一行的问题,超出区域的数据不能被显示的问题。

htmltocanvas缺陷1.png

(2)在新的生成截图的效果中,Select控件,会出现数据偏移,行高显示异常问题。

htmltocanvas缺陷2.png

(3)在新的生成截图的效果中,Data-Picker控件,会出现数据偏移,行高显示异常问题。

htmltocanvas缺陷3.png

(4)在新的生成截图的效果中,类型为Number的Input控件,会出现数据偏移,行高显示异常问题。

htmltocanvas缺陷4.png

2、DomToImage

3、Puppeteer

4、调用浏览器/系统自带的截图方法

三、具体实现方案细节

1、HtmlToCanvas的实现

/*
 * @Description: Html生成Img工具
 * @Date: 2022-05-24 17:08:18
 * @FilePath: src/utils/htmlToImg.js
*/
import html2Canvas from 'html2canvas';

/**
 * @description base64转图片文件
 * @param {String} dataurl 图片数据(base64格式)
 * @param {String} type 文件类型
 * @return {File} File 图片二进制流
 */
const base64ImgtoFile = function(dataurl, type) {
    let binary = atob(dataurl.split(',')[1]);
    let array = [];
    for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], { type: type });
}

/**
 * @description 根据Dom区域生成图片
 * @param {String} ref Dom区域ref
 * @param {String} name 图片名称
 * @return {File} File 图片文件
 */
export default {
    install(Vue) {
        Vue.prototype.createImg = async function (dom) {
            return await html2Canvas(dom, {
                useCORS: true,
                allowTaint: false,
                logging: false,
                letterRendering: true
            }).then(canvas => {
                this.posterImg = canvas.toDataURL('image/png');
                return base64ImgtoFile(this.posterImg, 'image/jpeg');
            })
        }
    }
}

2、DomToImage的实现

/*
 * @Description: Html生成Img工具
 * @Date: 2022-08-01 17:24:38
 * @FilePath: src/utils/domToImg.js
*/

import domToImage from 'dom-to-image';

/**
 * @description base64转图片文件
 * @param {String} dataurl 图片数据(base64格式)
 * @param {String} type 文件类型
 * @return {File} File 图片二进制流
 */
const base64ImgtoFile = function(dataurl, type) {
    let binary = atob(dataurl.split(',')[1]);
    let array = [];
    for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], { type: type });
}

/**
 * @description 根据Dom区域生成图片
 * @return {File} File 图片文件
 */
export default {
    install(Vue) {
        Vue.prototype.screenShot = async function (dom) {
            return await domToImage
                .toPng(dom, {bgcolor: '#fff'})
                .then((dataUrl) => {
                    //输出图片的Base64, dataUrl
                    return base64ImgtoFile(dataUrl, 'image/png');
                })
                .catch(function (error) {
                    console.error('oops, something went wrong!', error)
                })
        }
    }
}

相信大家一定都经常看视频,尤其是年轻人最爱的B站或者爱奇艺,腾讯等等长短视频。是当下民众快消文化的一种体现。 近期有时间,给大家分享下智能防挡弹幕的实现及原理。希望大家能喜欢。

揭秘B站智能防挡弹幕的原理与实现_01.png 揭秘B站智能防挡弹幕的原理与实现_02.png 揭秘B站智能防挡弹幕的原理与实现_03.png 揭秘B站智能防挡弹幕的原理与实现_04.png 揭秘B站智能防挡弹幕的原理与实现_05.png 揭秘B站智能防挡弹幕的原理与实现_06.png 揭秘B站智能防挡弹幕的原理与实现_07.png 揭秘B站智能防挡弹幕的原理与实现_08.png 揭秘B站智能防挡弹幕的原理与实现_09.png 揭秘B站智能防挡弹幕的原理与实现_10.png 揭秘B站智能防挡弹幕的原理与实现_11.png 揭秘B站智能防挡弹幕的原理与实现_12.png 揭秘B站智能防挡弹幕的原理与实现_13.png 揭秘B站智能防挡弹幕的原理与实现_14.png 揭秘B站智能防挡弹幕的原理与实现_15.png 揭秘B站智能防挡弹幕的原理与实现_16.png 揭秘B站智能防挡弹幕的原理与实现_17.png 揭秘B站智能防挡弹幕的原理与实现_18.png 揭秘B站智能防挡弹幕的原理与实现_19.png 揭秘B站智能防挡弹幕的原理与实现_20.png 揭秘B站智能防挡弹幕的原理与实现_21.png 揭秘B站智能防挡弹幕的原理与实现_22.png 揭秘B站智能防挡弹幕的原理与实现_23.png 揭秘B站智能防挡弹幕的原理与实现_24.png 揭秘B站智能防挡弹幕的原理与实现_25.png 揭秘B站智能防挡弹幕的原理与实现_26.png 揭秘B站智能防挡弹幕的原理与实现_27.png

一、安装homebrew遇到的问题及解决办法?

1. 遇到的问题:

mac中安装homebrew,根据homebrew官网给出的链接在终端输入,报错 curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to raw.githubusercontent.com:443

2、解决办法:

利用国内源【1、中科大下载源 2、清华大学下载源 3、北京外国语大学下载源 4、腾讯下载源(不推荐) 5、阿里巴巴下载源(不推荐 缺少cask源) 】完成下载 在终端输入以下命令执行完成即可。

/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

二、安装nvm遇到的问题及解决办法?

1、安装nvm遇到的问题

通常安装都会使用如下命令

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

但是过程中都会出现443超时的问题 "fatal: unable to access 'https://github.com/creationix/nvm.git/': Failed to connect to github.com port 443: Operation timed out" 【注:出于政策考虑,国外源被禁】 且mac使用curl安装其他的包也有可能会出现这个问题;尝试了设置代理、下载bash运行、clone包都没有解决这个问题。

2、解决办法步骤:

(1)安装之前卸载已有的nodenode模块(清理环境)

npm ls -g --depth=0                             # 查看已经安装在全局的模块,以便删除这些全局模块后再按照不同的 node 版本重新进行全局安装
sudo rm -rf /usr/local/lib/node_modules         # 删除全局 node_modules 目录
sudo rm /usr/local/bin/node                     # 删除 node
cd  /usr/local/bin && ls -l | grep "../lib/node_modules/" | awk '{print $9}'| xargs rm       #删除全局 node 模块注册的软链

如出下下方信息,则说明完成清除node和其模块。

node -v
zsh: command not found : node

(2)安装nvm(使用gitee镜像安装nvm到本地)

git clone https://gitee.com/mirrors/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags` 

如果提示带有版本号,则说明成功安装了nvm

(3)配置nvm环境变量

经过了上一步nvm还暂时不能使用;当终端关闭之后再打开将nvm失效;nvm仍然不可用;需要添加nvm环境变量;进入.bash_profile文件设置环境变量;如果没有这个文件;则需要创建文件创建 .bash_profile 文件

// 进入(i编辑 esc退出 :wq保存)如果没有 用touch建立下该文件
vim ~/.bash_profile    

// 复制下面的两行粘贴并且保存
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm

// 保存退出后执行生效命令
source ~/.bash_profile

如果使用的是zsh环境的话,还需要单独设置 .zshrc文件;

vim ~/.zshrc    // 进入(i编辑 esc退出 :wq保存)如果没有 用touch建立下该文件

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

保存退出后执行生效命令
source ~/.zshrc

(4)查看安装

经过上面三个步骤,现在不管是新开命令行窗口还是当前;都可以查看nvm的安装情况了!出现如下信息,证明nvm已经安装成功

cmmand -v nvm
// nvm
nvm -v
// 0.39.0

三、【Mac m1芯片版本】nvm安装成功后,安装不同版本的node时,应注意什么?

如果在m1芯片的mac电脑中通过nvm安装node 在安装nvm的时候必须进入Rosetta 2模式!!!否则安装node的时候会报错,报错如 "nvm: install vx.x.x failed!" 执行如下命令进入Rosetta 2,才能执行nvm install

// 进入Rosetta2 模式
arch -x86_64 zsh

// 进行正常安装
nvm install vx.x.x