美文网首页
写一个圣诞帽小程序

写一个圣诞帽小程序

作者: 小白菜haha | 来源:发表于2020-01-05 00:08 被阅读0次

    原文地址

    效果图

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

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

    相关文章

      网友评论

          本文标题:写一个圣诞帽小程序

          本文链接:https://www.haomeiwen.com/subject/jbqqactx.html