Vue3で九公宝くじの効果を実感

序文

久しぶりに記事を書きました 前回記事を出したのは年末のまとめでした あっと言う間にもう一年ですね まとめたいと思うたびに 続きが気になりませんそれは難しいです。今回は、九公宝くじの小さなゲームを共有します. 起源は、会社が最近ポイント宝くじを行う必要があるということです. 宝くじの動的効果の要約を描き、宝くじのプロセスと注意点を実現します.最初から機能します。デモ関数コードは、主に結合 API を使用する vue3 を使用して実装されています. 単純なデモのみであるため、スキャフォールディングおよびパッケージング ツールは使用されません.

需要と効果

要件: 1. ギフトは背景の構成に従って生成されます 2. マーキーの回転効果 3. 結果はバックグラウンドで生成され、各ギフトの確率は異なります (確率についてはここでは説明しません)。

留意点: 1. レイアウトの組み方、走りに合わせて配置するか、上から下に左から右に配置するか 2. クリックボタンを挿入する方法、DOM 構造を生成する方法 3. を実現する方法競馬の効果と速度を制御する方法 4. インターフェースの処理方法 , インターフェースのエラー報告、特別な効果 5 をリクエストした場合の保留中、競馬後に選択した結果と一致するバックグラウンドの戻り結果など.

最終的なレンダリング:

注:写真はすべてBaiduの写真で見つかりました

機能実現

ステップ 1: レイアウトを実装する

アイデア: バックグラウンドで構成されたギフト リストをリクエストします.一般的には、参加していただきありがとうございますを含む 8 つのギフトが構成されます.最初の方法は、9 つ​​のギフト div タグを手動でレイアウトして書き込むことです.このようにして、開始ボタンを直接に書き込むことができますレイアウト。2 つ目はトラバースできます。ここではトラバース メソッドを使用しますが、ボタンをギフト リスト配列に挿入する必要があります。css コードはフレックス レイアウトを使用できます。3 行 3 列が適切であり、必要なスタイルを追加します。js 部分は主に splice() メソッドを使用して <start button> を挿入します。

コードの一部:

<body><div id="app" v-cloak><div class="container"><div :class="['item', {'active': currentIndex === index}]"v-for="(item, index) in prizeList"@click="start(index)"><img :src="item.pic" alt=""><p v-if="index !== 4">{
   
   { item.name }}</p></div></div></div>
</body> 
const state = reactive({prizeList: [{ name: '手机', pic: 'https://bkimg.cdn.bcebos.com/pic/3801213fb80e7bec54e7d237ad7eae389b504ec23d9e' },{ name: '手表', pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '苹果', pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG' },{ name: '棒棒糖', pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG' },{ name: '娃娃', pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG' },{ name: '木马', pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '德芙', pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '玫瑰', pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG' }], // 后台配置的奖品数据
})
const startBtn = { name: '开始按钮', pic: 'https://img2.baidu.com/it/u=1497996119,382735686&fm=253' }

onMounted(() => {// state.prizeList.forEach((item, index) => {//item.id = index// })state.prizeList.splice(4, 0, startBtn)console.log(state.prizeList)
}) 
第二段階:ダイナミックな効果を実感

アイデア マーキー効果の実現は、主に円で強調表示することです. ここでは、現在のギフト座標と、競馬で実行されたステップ数を 8 で割った残りの部分が同じであると考えることができます. ただし、レンダリングの順序ははギフト リストとは異なるため、競馬で実行されるギフト座標のシーケンス配列を定義できます。prizeSort = [0, 1, 2, 5, 8, 7, 6, 3]したがって、円で実行されます。次に、アニメーションがステップごとに実行される場合、タイマーを使用して、現在強調表示されている添字インデックス currentIndex に間隔ごとにターン数を変更させることができます. ターン数をカスタマイズできます. ここでは実行の合計数を使用します.計算するステップ。これは 8 の倍数でなければなりません。たとえば、毎回 4 回回転する必要がある場合、実行する基本的な合計ステップ数は 32 ステップであり、次の座標に基づいて実行するステップ数を計算します。バックグラウンドでのギフトに、競馬が実行する本部の数である 32 を加えたもの. 最初は速く、次に忙しい. タイマーの setTimeout() メソッドを使用すると、2 番目のパラメーターの待機時間が長くなり、総実行ステップ数が通常の 3 分の 2 を超えると、タイマー待ち時間が長くなり、次のステップの実行がますます遅くなると判断できます。

ステップ 3: バックグラウンドの抽選結果

アイデア: 宝くじの結果がバックグラウンドで返される場合、上記の 4 と 5 の問題が発生する可能性があります。たとえば、インターフェイス エラーの報告や長時間の待機などです。次のように処理できます。インターフェイスエラーレポートを直接表示することができ、長時間待つ方法、ロードプロンプトを追加することができ、これら2つの問題を基本的に解決することができます. バックグラウンドから返された結果とアニメーション効果の実行結果をどのように一致させるかという問題については、前述のように基本的な実行ステップ数があり、ギフトに応じて実行するステップ数を計算します。リクエスト結果の座標を取得し、その結果を上位に一致するように追加します。

コード
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style> * {margin: 0; padding: 0; box-sizing: border-box; }[v-cloak] {display: none;}.container {width: 450px;height: 450px;background: #98d3fc;border: 1px solid #98d3fc;margin: 100px auto;display: flex;flex-wrap: wrap;justify-content: space-around;align-items: center;}.item {width: 140px;height: 140px;border: 2px solid #fff;position: relative;}.item:nth-of-type(5) {cursor: pointer;}.item img {width: 100%;height: 100%;}.item p {width: 100%;height: 20px;background: rgba(0, 0, 0, 0.5);color: #fff;font-size: 12px;text-align: center;line-height: 20px;position: absolute;left: 0;bottom: 0;}.active {border: 2px solid red;box-shadow: 2px 2px 30px #fff;} </style>
</head>
<body><div id="app" v-cloak><div class="container"><div :class="['item', {'active': currentIndex === index}]"v-for="(item, index) in prizeList"@click="start(index)"><img :src="item.pic" alt=""><p v-if="index <img src="https://unpkg.com/vue@3/dist/vue.global.js"></script><script> const { createApp, onMounted, ref, reactive, toRefs, computed } = VuecreateApp({setup () {const state = reactive({prizeList: [{ name: '手机', pic: 'https://bkimg.cdn.bcebos.com/pic/3801213fb80e7bec54e7d237ad7eae389b504ec23d9e' },{ name: '手表', pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '苹果', pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG' },{ name: '棒棒糖', pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG' },{ name: '娃娃', pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG' },{ name: '木马', pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '德芙', pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '玫瑰', pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG' }], // 后台配置的奖品数据currentIndex: 0, // 当前位置isRunning: false, // 是否正在抽奖speed: 10, // 抽奖转动速度timerIns: null, // 定时器实例currentRunCount: 0, // 已跑次数totalRunCount: 32, // 总共跑动次数 8的倍数prizeId: 0, // 中奖id})const startBtn = { name: '开始按钮', pic: 'https://img2.baidu.com/it/u=1497996119,382735686&fm=253' }// 奖品高亮顺序const prizeSort = [0, 1, 2, 5, 8, 7, 6, 3]// 要执行总步数const totalRunStep = computed(() => {return state.totalRunCount + prizeSort.indexOf(state.prizeId)})onMounted(() => {// state.prizeList.forEach((item, index) => {//item.id = index// })state.prizeList.splice(4, 0, startBtn)console.log(state.prizeList)})// 获取随机数const getRandomNum = () => {// const num = Math.floor(Math.random() * 9)// if (num === 4) {//console.log(">>>>>不能为4")//return getRandomNum()// } else {//return num // }// 这里一次必然可以取到 时间为1次return prizeSort[Math.floor(Math.random() * prizeSort.length)]}const start = (i) => {if (i === 4 && !state.isRunning) {// 重置数据state.currentRunCount = 0state.speed = 100state.isRunning = trueconsole.log('开始抽奖,后台请求中奖奖品')// 请求返回的奖品编号 这里使用随机数 但不能为4// const prizeId = getRandomNum()// console.log('中奖ID>>>', prizeId, state.prizeList[prizeId])// state.prizeId = prizeId// 模拟接口延时返回 如果接口突然报错如何处理?直接调用stopRun()方法停止转动setTimeout(() => {const prizeId = getRandomNum()console.log('中奖ID>>>', prizeId, state.prizeList[prizeId])state.prizeId = prizeId}, 2000)startRun()}}const startRun = () => {stopRun()console.log(state.currentRunCount, totalRunStep.value)// 要执行总步数// 已走步数超过if (state.currentRunCount > totalRunStep.value) {state.isRunning = falsereturn}state.currentIndex = prizeSort[state.currentRunCount % 8]// 如果当前步数超过了2/3则速度慢下来if (state.currentRunCount > Math.floor(state.totalRunCount * 2 / 3)) {state.speed = state.speed + Math.floor(state.currentRunCount / 3)console.log('速度>>>>', state.speed)}state.timerIns = setTimeout(() => {state.currentRunCount++startRun()}, state.speed)}const stopRun = () => {state.timerIns && clearTimeout(state.timerIns)}return {...toRefs(state),start}}}).mount('#app') </script" style="margin: auto" />
</body>
</html> 

やっと

HTML、CSS、JavaScript、HTTP、TCPプロトコル、ブラウザ、VUE、React、データ構造やアルゴリズムなど、「フロントエンドメーカーインタビュー集」をまとめ、合計201問のインタビュー質問をまとめ、それぞれに回答を作成質問 答えて分析します。

困っている友達、記事の最後にあるカードをクリックしてこのドキュメントを受け取り、無料で共有できます

ドキュメントの一部は次のとおりです。



記事の長さには制限があり、次のコンテンツは順次表示されません

困っている友達は、下のカードをクリックして無料で入手できます

おすすめ

転載: blog.csdn.net/web22050702/article/details/128715834