写一个圣诞帽小程序

原文地址

效果图

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 我为什么决定开始写?点子是突发奇想,出发点不是,写文章这种事情好像都是心思细腻的人才会才能做的事情,不过我就是这样...
    野子zii阅读 347评论 0 0
  • 初读此文,头脑中一片空白,不知道在讲些什么。 更不明白老师为什么要布置这个作业,看文章似鲁迅给许广文的回信,回答一...
    风云_简书阅读 452评论 0 0
  • 聂鲁达说,爱是那么短,遗忘是那么长。 在周杰伦的演唱会上,一个姑娘点歌《算什么男人》送给...
    巫小皇阅读 199评论 0 2