动效给的效果是一个头耳朵话筒胳膊都在动的摇摆效果,这个不能传视频,大体图片展示如下
紧靠前端css实现这种动效比较难,因此决定采用Lottie实现。
后面才了解到,产品希望小猴子的脸是孩子的头像图片,于是修改了Lottie的json文件,将动效里面的头像换成自己的,但是实现效果如下
看了很多关于lottie的文章,查找每一个属性的作用,找到一个 tm(剪裁路径) 的属性,但是都仅仅是提到这个属性,具体怎么用完全不知道,看一下里面的json结构,想去实现剪裁效果简直一脸蒙。
只能另辟蹊径,有什么办法获取头像之后把它变成圆的呢?
- 后端处理返回圆形头像
- 前端剪裁头像,然后替换
后端处理的话,也不太现实,还要后端实现,而且会占用服务器处理。
前端处理,忽然想到之前用canvas生成海报图,那是否可以绘制圆形图片呢?搜了一下果然可以,大喜过望。
关键在于是clip()
API,这个API,可以用你指定的形状在画布上裁剪一部分出来,然后,接下来你在画布上的操作只有在该形状区域内可见,如果还有后续还有对画布的其他地方有操作,可以使用restore()
接口恢复,但是必须在使用clip接口前用 save()
接口保存canvas的状态。
实现圆角方案核心代码如下
<canvas id="canvas" style="border: 1px solid;"></canvas>
<script>
function circleImg(ctx, img, x, y, r) {
ctx.save();
var d =2 * r;
var cx = x + r;
var cy = y + r;
ctx.arc(cx, cy, r, 0, 2 * Math.PI); // 绘制圆形
ctx.clip(); // 从画布上剪裁圆形
ctx.drawImage(img, x, y, d, d);
ctx.restore();
}
var img = new Image();
img.src = 'xxx';
var canvas = document.querySelector("#canvas");
var context = canvas.getContext("2d");
circleImg(context, img, 100, 20, 50);
</script>
使用canvas的道路总是曲折的,刚准备运行看效果,就提示 Cannot read property 'getContext' of null"
大意就是canvas获取不到 getContext属性,所以只能等html加载完成后执行js代码,写在window.onload里即可。
绘制完成后,还需要将canvas转成图片,
canvas.toDataURL("image/png")
然而,又是一口老血... 控制台红红的提示,
**Uncaught DOMExc****eption: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
**
经google 发现原来是受限于 CORS 策略,会存在跨域问题,虽然可以使用图像(比如append到页面上)但是绘制到画布上会污染画布,一旦一个画布被污染,就无法提取画布的数据,比如无法使用使用画布toBlob(),toDataURL(),或getImageData()方法;当使用这些方法的时候 会抛出一个安全错误
这就简单了,给图片添加crossOrigin属性,
img.setAttribute("crossOrigin",'Anonymous')
然后将demo迁移到项目里运行,咦,其它图片路径怎么找不到了,多页面服务,根路径好像对不上
难道只能把所有图片上传到oss,然后替换成网络图片?这样维护起来就比较费劲了。
前端的魅力是无穷的,解析不了json文件路径,但是可以解析js路径啊,最后把整个json文件改成js,里面的图片都用require引入,最后export 出来,完美解决!
最终实现效果,so cool!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。