蹭热点,请给我一面国旗@微信官方


思否
微信 Canvas

转载自 SegmentFault

今天下午微信朋友圈炸了,所有人都在要国旗。迎国庆换新颜活动 | 腾讯新闻的合成服务 微信中打开。 我们呢,也来蹭蹭热度,聊聊其中的技术。

猜测如何实现

  • 授权-获取用户头像

  • 载入图片

  • 手势操作-移动缩放

  • 合成图片

  • 下载图片

求证如何实现

当然,上面只是我以为。通过观察分析节点,我发现

  • 的确是载入图片了。地址为blob:开头

  • 但是并无canvas操作,而且基于DOM,用scale、translatetransfrom来支持

  • 合成依赖html2canvas

  • 下载基于长按图片。

自己动手实现

因为我的公众号是个人号,没权限。所以我们稍微的改一下。 对不起父老乡亲们,昨天我没写完就下班了。测试地址,终于写完了。下面说说关键点

上传图片 使用FileAPI获取文件,URL.createObjectURL(file)file转换url

     // 上传头像功能块
     uploadInput.addEventListener('change', function(){
         if(this.files.length){
             var file = this.files[0];
             avatarView.style.backgroundImage = 'url('+URL.createObjectURL(file)+')';
             // avatarView.src=URL.createObjectURL(file)
         }
     })

手势操作 e.touches里面会有当前触发点。通过transfrom来合成,当然因为多个值会造成坐标系偏移,我使用多层来处理。

 <div class="avatarViewScale" id="avatarViewScale" style="transform: scale(1,1)">
  <div class="avatarViewTranslate" id="avatarViewTranslate" style="transform: translate(0,0)">
   <div class="avatar avatarView" src="https://www.lilnong.top/static/img/avator/avator-14.jpg" id="avatarView"></div>
  </div>
 </div>

移动是比较touchstart记录点与touchmove记录点的插值。比较好算

  • 缩放是也是比较记录点,但是需要用勾股定理计算比例

  • 合成图片 通过cavnasdrawImage来合成。我觉得偏移量应该要注意一下。

  • 下载图片 通过 canvas.toDataURL('image/jpeg') 来生成base64url然后放入img。通过微信自带的长按下载来实现

总结

太忙了。好不容易写完。感觉实现上还是蛮简单的,做好就不容易了。

  • 毛边问题

  • 图片预加载策略

  • 旋转的算法

  • 自定义素材

更新时间 2019年9月26日11:34:54 https://www.lilnong.top/stati

  • 放大了一下倍图片解决毛边

增加了旋转功能


ctx.translate(widthHeight / 2, widthHeight / 2)
ctx.transform.apply(ctx, getComputedStyle(avatarViewRotate).transform.match(/-?[\d.]+/g))
ctx.translate(-1 * widthHeight / 2, -1 * widthHeight / 2);

更新时间 2019年9月26日13:47:19 https://www.lilnong.top/stati

  • 兼容pc

  • 修改转换优先级

更新时间 2019年10月9日09:08:37

  • 只考虑技术实现,未生成大图(已修复 750*750)

微信公众号:前端linong


原文:SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。