最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

微信小程序canvas開發(fā)水果老虎機(jī)的思路詳解

 更新時(shí)間:2020年02月07日 11:40:39   作者:天天修改  
這篇文章主要介紹了微信小程序canvas開發(fā)水果老虎機(jī)的思路,本文通過(guò)思路代碼分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

在這個(gè)超長(zhǎng)假期中,無(wú)聊。。。,所以動(dòng)手做一個(gè)早就計(jì)劃要做的小玩意, 水果老虎機(jī) ,嗯,這是一個(gè)小程序而不是小游戲...

 

使用結(jié)構(gòu)還是canvas?

使用模板結(jié)構(gòu)(view)生成水果盤的好處一是用戶可自定義產(chǎn)出 n x n 的定制化老虎機(jī),二是容易通過(guò)算法樣式生成布局,三是通過(guò) wx.selectQueryAll 的方法能夠很方便的抓到定位數(shù)據(jù)。但,問題是動(dòng)畫性能過(guò)于孱弱,如圖構(gòu)建一個(gè) 7x7 的水果盤,動(dòng)畫性能估計(jì)會(huì)慘不忍睹,而且純粹模板結(jié)構(gòu)無(wú)論使用 animation 動(dòng)畫方法還是 css 的keyframe的動(dòng)畫方法得到的動(dòng)畫效果都非常差(測(cè)試過(guò)的結(jié)論),還有是已知的動(dòng)畫方法可控性很差

使用canvas來(lái)生成水果盤好處是動(dòng)畫性能很好(canvas2d),但是定制性和擴(kuò)展性比較差

so綜上考慮,使用模板(view)布局,使用canvas來(lái)實(shí)現(xiàn)動(dòng)畫。既保證了組件的性能,同時(shí)定制型,擴(kuò)展性也很好

準(zhǔn)備計(jì)時(shí)器方法

動(dòng)畫的生成離不開計(jì)時(shí)器方法,settimeout/setinterval這兩兄弟真的不夠看啊,問題還多,做過(guò)web開發(fā)的一定都知道 window.requestAnimationFrame ,這貨在小程序的計(jì)時(shí)器方法中不存在,好在 canvas2d 中可以使用 Canvas.requestAnimationFrame(function callback) 方法來(lái)實(shí)現(xiàn)

準(zhǔn)備運(yùn)動(dòng)算法

在水果老虎機(jī)中,激活狀態(tài)會(huì)沿著四方的水果盤做非線性運(yùn)動(dòng)(easeInOut比較好用),需要基礎(chǔ)的運(yùn)動(dòng)算法來(lái)計(jì)算實(shí)際的運(yùn)動(dòng)距離。在 animation 動(dòng)畫方法中,我們可以使用 ease-in/ease-out 等緩動(dòng)算法來(lái)實(shí)現(xiàn)動(dòng)畫效果,但在這里必須要借助 tween.js 中的緩動(dòng)算法來(lái)實(shí)現(xiàn)運(yùn)動(dòng)效果(因?yàn)樾枰刂七\(yùn)動(dòng)節(jié)點(diǎn))。

你會(huì)不會(huì)想到用css的keyframe動(dòng)畫來(lái)做這個(gè)運(yùn)動(dòng)效果,經(jīng)過(guò)我的測(cè)試,css的動(dòng)畫和animation的動(dòng)畫會(huì)在每一條邊上實(shí)現(xiàn)一次(ease)緩動(dòng)運(yùn)動(dòng)(很奇怪的效果)

推薦這篇文章

使用其中一個(gè),節(jié)省代碼量

/*
 * Tween.js
 * t: current time(當(dāng)前時(shí)間);
 * b: beginning value(初始值);
 * c: change in value(變化量);
 * d: duration(持續(xù)時(shí)間)。
 */
// Quart 四次方的緩動(dòng)
const easeInOutQuart = function (t, b, c, d) {
 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
 return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}

tween算法是以時(shí)間為基準(zhǔn)(時(shí)間比率 = 距離比率)來(lái)計(jì)算單位時(shí)間的實(shí)際運(yùn)動(dòng)距離

布局

以上面的圖為例,我們需要做一個(gè) 7 x 7 的水果盤,實(shí)際有效的獎(jiǎng)品格子數(shù)為 7*4-4 共24個(gè)有效格子

有效格子算法

js

// 0-6 第一行所有格子全部有效 
// 21-27 最后一行所有格子全部有效 
// 中間部分 i%7===0 和 i%7 === (7-1) 有效
// 算法源碼有點(diǎn)無(wú)聊,依據(jù)上述思路,即可遍歷28個(gè)格子并標(biāo)識(shí)獎(jiǎng)品格子valide=true
// 可以擴(kuò)展想一想 6x6 5x5,思路是一樣的

wxml

<view class="fruits-container" >
  <view class="fruits-table" >
    <block wx:for="{{ary}}" wx:key="index" >
      <view wx:if="{{item.valide}}" class="valide">{{item.title}}</view>
      <view wx:else class="in-valide"></view>
    </block>
  </view>
  <canvas type="2d" .... />
</view>

樣式

只節(jié)選關(guān)鍵樣式,目的是讓canvas覆蓋在水果盤上,長(zhǎng)寬一致

.fruits-container {
  position: relative;
  width: 400px;
  height: 400px;
  ...
}

.fruits-table {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  ...
}

抓取位置信息

canvas的繪制需要X軸, Y軸的精確信息,可以使用 wx.createSelectorQuery 方式抓取類名為‘valide'的 view (獎(jiǎng)品格子)的位置信息

let query = wx.createSelectorQuery().in(this)
query.selectAll(`.fruits-table .valide`).boundingClientRect(ret => {
  ....
  console.log(ret[0]) // top, left, right, bottom, width, height
  console.log(ret[1]) // top, left, right, bottom, width, height
  ...
  ...
  console.log(ret[23]) // top, left, right, bottom, width, height
})

得到每一個(gè)獎(jiǎng)品格子的位置信息后,就可以使用canvas的 fillRect 方法來(lái)繪制激活狀態(tài)了。

繪制一個(gè)激活狀態(tài)

let query = wx.createSelectorQuery().in(this)
query.selectAll(`.fruits-table .valide`).boundingClientRect(ret => {
  ....
  let {top, left, right, bottom, width, height} = ret[0]
  const canvasQuery = wx.createSelectorQuery()
  canvasQuery.select('#fruit-canvas')
  .fields({ node: true, size: true })
  .exec((res) => {
    const canvas = res[0].node
    const ctx = canvas.getContext('2d') 
    let x = top
    let y = left
    let dx = width
    let dy = height
    ctx.shadowOffsetX = 2
    ctx.shadowOffsetY = -2
    ctx.shadowColor = 'red'
    ctx.shadowBlur = 50
    ctx.lineWidth = 5
    ctx.strokeStyle = 'red'
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.strokeRect(x, y, dx, dy)
  })
})

跑起來(lái)

已經(jīng)繪制了一個(gè)激活狀態(tài),接下來(lái)使它能夠簡(jiǎn)單動(dòng)起來(lái)

// 抽象激活方法 
functon rect(point, canvas){
  let {x, y, dx, dy} = getPosition(point)
  ctx.shadowOffsetX = 2
  ctx.shadowOffsetY = -2
  ...
  ...
  ctx.clearRect(0, 0, canvas.width, canvas.height) // 擦除整個(gè)水果盤
  ctx.strokeRect(x, y, dx, dy) // 繪制激活區(qū)域
}

function run(){
  setTimeout(()=>{
    if (ret.length) {
      let point = ret.shift()
      rect(point, canvas)
      run()
    }
  }, 100)
}

執(zhí)行run方法后可以看到水果盤的激活狀態(tài)一步一步的往前走(100毫秒),拖拉機(jī)終于可以啟動(dòng)了

配上運(yùn)動(dòng)算法

經(jīng)過(guò)上面的試驗(yàn)我們終于可以看到基本的運(yùn)動(dòng)效果了,接下來(lái)配上運(yùn)動(dòng)算法和計(jì)時(shí)器方法

// Quart 四次方的緩動(dòng)
const easeInOutQuart = function (t, b, c, d) {
 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
 return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}

let start = 0 // 開始時(shí)間
let begin = 0 // 開始獎(jiǎng)品位置
let end = 23 // 終點(diǎn)位置,這里跑一圈
let during = 5000 // 運(yùn)動(dòng)總時(shí)間

// 1000/60 ≈ 17,
// 17毫秒即表示屏幕60幀刷新率每秒 ≈ requestAnimationFrame計(jì)數(shù)頻率(一般情況) 
const steper = () => {
 // left為位移距離
 // 老虎機(jī)的運(yùn)動(dòng)位移是節(jié)點(diǎn)位移,不是精確位移
 // 所以這里用parseInt處理,只取整數(shù)部分
 // 數(shù)據(jù)變化為 0,1,2,3,4,5...23
 // 間隔時(shí)間/距離由easeInOutQuart算法計(jì)算
 var left = easeInOutQuart(start, begin, end, during);
 let idx = parseInt(left)
 start = start + 17; 
 if (idx <= end) {
  let point = this.ret[idx] // 取節(jié)點(diǎn)位置信息
  this.rect(point) // 繪制
 }
 // 時(shí)間遞增
 if (start <= during) {
  this.ctx.requestAnimationFrame(steper); // 計(jì)時(shí)器
 } else {
  // 動(dòng)畫結(jié)束,這里可以插入回調(diào)...
  // callback()...
 }
};
steper(); // 啟動(dòng)

總結(jié)

以上所述是小編給大家介紹的微信小程序canvas開發(fā)水果老虎機(jī)的思路詳解,希望對(duì)大家有所幫助!

相關(guān)文章

  • JavaScript中的異步能省掉await嗎?

    JavaScript中的異步能省掉await嗎?

    這篇文章主要介紹了JavaScript中的異步能省掉await嗎?一直以來(lái),困擾我的一個(gè)問題是JavaScript中,能否實(shí)現(xiàn)不帶await的異步。今天我終于把這個(gè)問題想通了然后分享給大家,希望對(duì)大家的學(xué)習(xí)過(guò)程有所幫助
    2021-12-12
  • Cocos2d實(shí)現(xiàn)刮刮卡效果

    Cocos2d實(shí)現(xiàn)刮刮卡效果

    這篇文章主要為大家詳細(xì)介紹了Cocos2d實(shí)現(xiàn)刮刮卡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • js中對(duì)象與對(duì)象創(chuàng)建方法的各種方法

    js中對(duì)象與對(duì)象創(chuàng)建方法的各種方法

    這篇文章主要給大家介紹了關(guān)于js中對(duì)象與對(duì)象創(chuàng)建方法的各種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • js中用cssText設(shè)置css樣式的簡(jiǎn)單方法

    js中用cssText設(shè)置css樣式的簡(jiǎn)單方法

    下面小編就為大家?guī)?lái)一篇js中用cssText設(shè)置css樣式的簡(jiǎn)單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • 躲避這些會(huì)改變?cè)瓟?shù)組JavaScript數(shù)組方法讓開發(fā)流暢無(wú)阻

    躲避這些會(huì)改變?cè)瓟?shù)組JavaScript數(shù)組方法讓開發(fā)流暢無(wú)阻

    JavaScript中有些數(shù)組的操作方法并不符合我們預(yù)期,容易導(dǎo)致想象不到的結(jié)果,因此,為避免這種情況的發(fā)生,本文將介紹哪些原生數(shù)組方法能改變?cè)瓟?shù)組以及我對(duì)于如何更好地使用數(shù)組方法的建議
    2023-05-05
  • JS技巧之一行賦值語(yǔ)句能玩出多少花樣

    JS技巧之一行賦值語(yǔ)句能玩出多少花樣

    很多前端只會(huì)謝謝頁(yè)面,一讓他們接觸js,就非常害怕,下面這篇文章主要給大家介紹了關(guān)于JS技巧之一行賦值語(yǔ)句能玩出多少花樣的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • JavaScript中for循環(huán)的幾種寫法與效率總結(jié)

    JavaScript中for循環(huán)的幾種寫法與效率總結(jié)

    每個(gè)接觸JS的開發(fā)人員都不可避免的與for循環(huán)打交道,畢竟這是遍歷必不可少的工具之一。然而當(dāng)循環(huán)次數(shù)比較大時(shí),效率問題必須重視。下面這篇文章就主要介紹了JavaScript中幾種for循環(huán)的寫法與效率,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02
  • webpack的移動(dòng)端適配方案小結(jié)

    webpack的移動(dòng)端適配方案小結(jié)

    移動(dòng)端開發(fā)的過(guò)程中,一個(gè)最常見的問題就是適配不同的屏幕寬度。本文主要介紹了webpack的移動(dòng)端適配方案,感興趣的可以了解一下
    2021-07-07
  • js實(shí)現(xiàn)限定范圍拖拽的示例

    js實(shí)現(xiàn)限定范圍拖拽的示例

    這篇文章主要介紹了js實(shí)現(xiàn)限定范圍拖拽的示例,幫助大家更好的制作js特效,美化自己的網(wǎng)頁(yè),感興趣的朋友可以了解下
    2020-10-10
  • BootStrap中的表單大全

    BootStrap中的表單大全

    這篇文章主要介紹了BootStrap中的表單大全,包括基礎(chǔ)表單,內(nèi)聯(lián)表單和水平表單等知識(shí),本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09

最新評(píng)論

甘洛县| 韶关市| 定兴县| 桂阳县| 石林| 海淀区| 建德市| 淄博市| 监利县| 上高县| 平阳县| 义乌市| 虹口区| 洪洞县| 琼中| 普安县| 肃北| 酒泉市| 庄浪县| 凯里市| 封丘县| 丰城市| 阿城市| 丰镇市| 阿合奇县| 耿马| 腾冲县| 紫金县| 怀来县| 山阴县| 黄大仙区| 民乐县| 将乐县| 缙云县| 任丘市| 财经| 衡东县| 府谷县| 洮南市| 京山县| 隆子县|