写一个圣诞帽小程序

2020-01-05  本文已影响0人  小白菜haha

原文地址

效果图

GIF


2020-01-0418.04.55.gif

微信小程序


gh_eff244ae7029_258.jpg

项目地址

源码

H5演示

主要实现

为了可以兼容多种小程序和h5,这里使用uni-app来开发

1.帽子标签

<view class='user-hat' 
  @touchstart='handleTouchStart' 
  @touchmove.stop='handleTouchMove' 
  @touchEnd='handleTouchEnd'
  :style='hatStyleStr'>
  <image class='hat' id='hat' src='/static/img/hat.png' :style='hatImgStyleStr'></image>
  <view class='rotate' id='rotate' :style='rotateStyleStr'>
    <image class='rotate-icon' id='rotate' src='/static/img/icon-rotate.png'></image>
  </view>
</view>

帽子的组成: class='hat' 的帽子图片和 class='rotate' 的帽子旋转按钮

2.绑定touch事件

1.touchstart 事件

handleTouchStart(e){
  // 当前帽子 top 值
  this.currentHatTop = this.hatTop  
  // 当前帽子 left 值
  this.currentHatLeft = this.hatLeft 
  // 当前旋转按钮 top 值
  this.currentRotateTop = this.rotateTop
  // 当前旋转按钮 left 值
  this.currentRotateLeft = this.rotateLeft
  // 当前target的id
  this.touchTarget = e.target.id
  // 当前touch的x值和y值
  this.currentPos = {x:e.touches[0].clientX,y:e.touches[0].clientY}
}

touchstart 中,首先获取帽子和旋转按钮的当前偏移值并赋值给相应变量,然后记录下当前 target 的 id 和当前 touch 事件的 XY 值

2.touchmove 事件

handleTouchMove(e){
  if(this.touchTarget){
    // 当前touch的x值和y值
    const pos = {x:e.touches[0].clientX,y:e.touches[0].clientY}
    // 对比touchstart时的x值的偏移量
    const moveX = pos.x - this.currentPos.x
    // 对比touchstart时的x值的偏移量
    const moveY = pos.y - this.currentPos.y
    // 如果移动的是帽子图片
    if(this.touchTarget === 'hat'){
      // 将帽子进行位移
      this.hatLeft = this.hatLeft + moveX
      this.hatTop = this.hatTop + moveY
    }
    // 如果移动的是旋转按钮
    else if(this.touchTarget === 'rotate'){
      // 将旋转按钮进行位移
      this.rotateLeft = this.rotateLeft + moveX
      this.rotateTop = this.rotateTop + moveY
      // 当前旋转按钮中心点相对于初始的帽子中心点的x偏移量
      const nowWidth = this.rotateLeft + this.hatHalfWidth
      // 当前旋转按钮中心点相对于初始的帽子中心点的y偏移量
      const nowHeight = this.rotateTop + this.hatHalfWidth
      // 当前旋转按钮中心点相对于初始的帽子中心点的直线距离(新的半径)
      const nowRadius = Math.sqrt(nowWidth * nowWidth + nowHeight * nowHeight)
      // 新的半径与旧的半径的比例
      this.hatScale = nowRadius / this.hatRadius
      // 当前的旋转按钮中心点与x轴的角度
      const nowAngel = Math.atan2(nowHeight,nowWidth) / Math.PI * 180
      // 这里this.beforeAngel默认设置为45
      this.hatRotate = nowAngel - this.beforeAngel + this.hatRotate
      // 重新赋值this.beforeAngel
      this.beforeAngel = nowAngel
    }
    // 重新赋值this.currentPos
    this.currentPos = pos
  }
}

touchmove 中,根据target的不同进行了不同的处理,旋转按钮move会对帽子进行一个旋转+放大的处理,其中放大计算主要是计算前后半径的比例。

3.保存图片

现在已经完成对帽子进行位移,旋转和放大了,最后只需要将变化后的图片进行保存。

const wrapperWidth = uni.getSystemInfoSync().windowWidth
const context = uni.createCanvasContext('avatarCanvas')
const hatSize = this.hatHalfWidth * 2 * this.hatScale
context.clearRect(0, 0, wrapperWidth, wrapperWidth)
context.drawImage(path, 0, 0, wrapperWidth, wrapperWidth)
context.translate(this.hatLeft + this.hatHalfWidth,this.hatTop + this.hatHalfWidth)
context.rotate(this.hatRotate * Math.PI / 180)
console.log(-hatSize/2)
context.drawImage("/static/img/hat.png", -hatSize/2, -hatSize/2, hatSize, hatSize)
context.draw()

canvas的处理比较简单,绘制图片并进行位移旋转和缩放即可,需要注意的是微信小程序中需要配置下安全域名,不然头像是无法绘制出来的。

其他关于授权等内容不同小程序平台也有一些差异,可以查看源码,这里就不详细描述了。

上一篇下一篇

猜你喜欢

热点阅读