寫一個(gè)圣誕帽小程序

原文地址

效果圖

GIF


2020-01-0418.04.55.gif

微信小程序


gh_eff244ae7029_258.jpg

項(xiàng)目地址

源碼

H5演示

主要實(shí)現(xiàn)

為了可以兼容多種小程序和h5慕淡,這里使用uni-app來開發(fā)

1.帽子標(biāo)簽

<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' 的帽子旋轉(zhuǎn)按鈕

2.綁定touch事件

1.touchstart 事件

handleTouchStart(e){
  // 當(dāng)前帽子 top 值
  this.currentHatTop = this.hatTop  
  // 當(dāng)前帽子 left 值
  this.currentHatLeft = this.hatLeft 
  // 當(dāng)前旋轉(zhuǎn)按鈕 top 值
  this.currentRotateTop = this.rotateTop
  // 當(dāng)前旋轉(zhuǎn)按鈕 left 值
  this.currentRotateLeft = this.rotateLeft
  // 當(dāng)前target的id
  this.touchTarget = e.target.id
  // 當(dāng)前touch的x值和y值
  this.currentPos = {x:e.touches[0].clientX,y:e.touches[0].clientY}
}

touchstart 中,首先獲取帽子和旋轉(zhuǎn)按鈕的當(dāng)前偏移值并賦值給相應(yīng)變量在跳,然后記錄下當(dāng)前 target 的 id 和當(dāng)前 touch 事件的 XY 值

2.touchmove 事件

handleTouchMove(e){
  if(this.touchTarget){
    // 當(dāng)前touch的x值和y值
    const pos = {x:e.touches[0].clientX,y:e.touches[0].clientY}
    // 對(duì)比touchstart時(shí)的x值的偏移量
    const moveX = pos.x - this.currentPos.x
    // 對(duì)比touchstart時(shí)的x值的偏移量
    const moveY = pos.y - this.currentPos.y
    // 如果移動(dòng)的是帽子圖片
    if(this.touchTarget === 'hat'){
      // 將帽子進(jìn)行位移
      this.hatLeft = this.hatLeft + moveX
      this.hatTop = this.hatTop + moveY
    }
    // 如果移動(dòng)的是旋轉(zhuǎn)按鈕
    else if(this.touchTarget === 'rotate'){
      // 將旋轉(zhuǎn)按鈕進(jìn)行位移
      this.rotateLeft = this.rotateLeft + moveX
      this.rotateTop = this.rotateTop + moveY
      // 當(dāng)前旋轉(zhuǎn)按鈕中心點(diǎn)相對(duì)于初始的帽子中心點(diǎn)的x偏移量
      const nowWidth = this.rotateLeft + this.hatHalfWidth
      // 當(dāng)前旋轉(zhuǎn)按鈕中心點(diǎn)相對(duì)于初始的帽子中心點(diǎn)的y偏移量
      const nowHeight = this.rotateTop + this.hatHalfWidth
      // 當(dāng)前旋轉(zhuǎn)按鈕中心點(diǎn)相對(duì)于初始的帽子中心點(diǎn)的直線距離(新的半徑)
      const nowRadius = Math.sqrt(nowWidth * nowWidth + nowHeight * nowHeight)
      // 新的半徑與舊的半徑的比例
      this.hatScale = nowRadius / this.hatRadius
      // 當(dāng)前的旋轉(zhuǎn)按鈕中心點(diǎn)與x軸的角度
      const nowAngel = Math.atan2(nowHeight,nowWidth) / Math.PI * 180
      // 這里this.beforeAngel默認(rèn)設(shè)置為45
      this.hatRotate = nowAngel - this.beforeAngel + this.hatRotate
      // 重新賦值this.beforeAngel
      this.beforeAngel = nowAngel
    }
    // 重新賦值this.currentPos
    this.currentPos = pos
  }
}

touchmove 中,根據(jù)target的不同進(jìn)行了不同的處理焦人,旋轉(zhuǎn)按鈕move會(huì)對(duì)帽子進(jìn)行一個(gè)旋轉(zhuǎn)+放大的處理别凹,其中放大計(jì)算主要是計(jì)算前后半徑的比例。

3.保存圖片

現(xiàn)在已經(jīng)完成對(duì)帽子進(jìn)行位移昔园,旋轉(zhuǎn)和放大了,最后只需要將變化后的圖片進(jìn)行保存闹炉。

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的處理比較簡單蒿赢,繪制圖片并進(jìn)行位移旋轉(zhuǎn)和縮放即可,需要注意的是微信小程序中需要配置下安全域名渣触,不然頭像是無法繪制出來的。

其他關(guān)于授權(quán)等內(nèi)容不同小程序平臺(tái)也有一些差異壹若,可以查看源碼嗅钻,這里就不詳細(xì)描述了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末店展,一起剝皮案震驚了整個(gè)濱河市养篓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赂蕴,老刑警劉巖柳弄,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡碧注,警方通過查閱死者的電腦和手機(jī)嚣伐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萍丐,“玉大人轩端,你說我怎么就攤上這事∈疟洌” “怎么了基茵?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壳影。 經(jīng)常有香客問我拱层,道長,這世上最難降的妖魔是什么宴咧? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任舱呻,我火速辦了婚禮,結(jié)果婚禮上悠汽,老公的妹妹穿的比我還像新娘箱吕。我一直安慰自己,他們只是感情好柿冲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布茬高。 她就那樣靜靜地躺著,像睡著了一般假抄。 火紅的嫁衣襯著肌膚如雪怎栽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天宿饱,我揣著相機(jī)與錄音熏瞄,去河邊找鬼。 笑死谬以,一個(gè)胖子當(dāng)著我的面吹牛强饮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播为黎,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼邮丰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了铭乾?” 一聲冷哼從身側(cè)響起剪廉,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炕檩,沒想到半個(gè)月后斗蒋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年泉沾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捞蚂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爆哑,死狀恐怖洞难,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情揭朝,我是刑警寧澤队贱,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站潭袱,受9級(jí)特大地震影響柱嫌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屯换,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一编丘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彤悔,春花似錦嘉抓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杨赤,卻和暖如春敞斋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疾牲。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工植捎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阳柔。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓焰枢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盔沫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子医咨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 我為什么決定開始寫?點(diǎn)子是突發(fā)奇想架诞,出發(fā)點(diǎn)不是,寫文章這種事情好像都是心思細(xì)膩的人才會(huì)才能做的事情干茉,不過我就是這樣...
    野子zii閱讀 356評(píng)論 0 0
  • 初讀此文谴忧,頭腦中一片空白,不知道在講些什么。 更不明白老師為什么要布置這個(gè)作業(yè)沾谓,看文章似魯迅給許廣文的回信委造,回答一...
    風(fēng)云_簡書閱讀 468評(píng)論 0 0
  • 聶魯達(dá)說昏兆,愛是那么短,遺忘是那么長妇穴。 在周杰倫的演唱會(huì)上爬虱,一個(gè)姑娘點(diǎn)歌《算什么男人》送給...
    巫小皇閱讀 204評(píng)論 0 2