PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛
春节 海报
介绍
这个是关于 春节 海报 生成的项目,通过 html2canvas 这个关键库 来操作的。
技术:通过 Vite2,Vue3 快速搭建一个项目。通过鼠标的点击事件来产生烟花爆炸效果,及 html2canvas 来进行海报的一个生成。
项目演示:
技术
-
创建项目,输入命令后,选择vue,清空页面里的无关东西
npm init @vitejs/app -
页面布局
整体的页面效果 及 爆炸效果,是按照 上面两篇文章 春节 打工计时 和 春节祝福语,不来瞧瞧? 来写的。并新添加了一张 fixed 固定定位 将其放置在页面最顶端的一张 外链图。外链图的链接 是通过百度搜索,随便找的。
-
html2canvas
html2canvas 这个库,还是先看下 文档 的介绍。我们知道它是一个可以 直接在用户浏览器上对网页或其部分进行“截图” 的一个功能库。
但是它会有跨域的一个限制,跨域的元素或者内容 将是一种污染,也是一种脏数据,它会导致 html2canvas 无法对其截图。
-
安装
npm install --save-dev html2canvas -
使用
在所需截图位置的 最外层 获取当前的标签,以及创建点击 事件
<div class="bg" ref="contentRef" @click="posterImage"></div>const contentRef = ref(null)将选取的标签 进行处理,获取 dom 元素的宽高,并创建 canvas 画布,定义 canvas 的宽高及缩放比例
const htmlContainer = contentRef.value const width = htmlContainer.offsetWidth const height = htmlContainer.offsetHeight const canvas = document.createElement('canvas') const scale = 1 canvas.width = width * scale canvas.height = height * scale canvas.getContext('2d').scale(scale, scale) -
配置项
html2canvas 有很多的 配置项,而且有一些配置项的作用很关键。
定义 html2canvas 的配置项 options ,这里有两个关键的配置项,关于跨域问题的处理
const options = { useCORS: true, // 开启跨域配置 allowTaint: true // 开启画布污染 } -
生成海报 并 下载
用 js 创建一个 a 元素标签 ,将 容器 及 配置项 传入 html2canvas, 之后再通过它的 then 方法中可以获取到绘制好的 canvas 对象,之后再通过调用 canvas 对象的 toDataURL 方法就可以将其转换成海报图片。
const aLink = document.createElement('a') html2canvas(htmlContainer, opts).then((canvas) => { const context = canvas.getContext('2d') const event = new MouseEvent('click') // 创建一个鼠标事件的实例 aLink.download = '虎年大吉.png' // 设置要下载的图片的名称 aLink.href = canvas.toDataURL('image/jpeg') // 将图片的URL设置到超链接的href中 aLink.dispatchEvent(event) // 触发超链接的点击事件 }) -
忽略元素
在所需要忽略的 任意标签元素的位置处 添加 data-html2canvas-ignore 这个属性,例如下面这个 xxx.png 就不会在海报中显示
<img src="xxx.png" data-html2canvas-ignore></img>
-
-
注意
此次是在 dev 环境上进行,没有问题。
但是 生产 环境上可能会出现跨域问题,这个跨域问题的话,多半就是图片跨域污染的。
-
我们可以通过创建一个 Image 对象,并将这个 Image 对象支持跨域。
-
再将海报里的跨域的图片的src 指向这个创建的对象
-
并通过 canvas 进行 base64 的一个处理
-
再让这个海报里的跨域的图片 重新指向 新生成的图片即可
const image = new Image() image.crossOrigin = '*' // 支持跨域图片 image.src = img.src image.onload = () => { img.src = getBase64Img(image) }注意 drawImage 这个 API 的使用,很关键。
const getBase64Img = (img) => { const canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, canvas.width, canvas.height) return canvas.toDataURL('image/png') } -
总结
通过 春节 海报 这个项目总结了 canvas 的一些常用API的使用,以及最主要的 html2canvas 库的使用,以及跨域问题如何处理。
最后 2022 祝大家 虎年快乐