最近一段時間,閒暇之餘玩了幾把鬥地主,惋惜的是本身沒錢買記牌器,腦子又記不住那麼多牌,常常翻車,震怒!遂寫記牌器,逆天改命!html
不用多說,確定是模仿鬥地主的記牌器最實用好看啦。
ps:這個是最終稿的截圖,前幾版還有一些按鈕,爲何去掉了能夠看後面。數組
首先,怎麼設計這個記牌器的交互纔是關鍵,由於咱們只能手動記牌,其餘牌友出了什麼牌,咱們就從一副牌裏減去出掉的牌。app
想法1:鍵盤輸入,回車|按鈕出牌ide
想法2:點擊選取,而後回車|按鈕出牌flex
想法3:點擊+滑動直接出牌,去除回車或者按鈕,右鍵撤回spa
很容易就能夠想出思路:設計
這裏實在太簡單,不想說了。你能夠手動寫十幾個div,也能夠用js動態添加。3d
咱們這裏應該分紅兩布,第一步是選,第二步是出牌。因此咱們能夠用一個數組來保存咱們已經選擇的牌的序號。code
左鍵點擊orm
滑動
mouseenter
,mouseleave
事件,鼠標通過的時候,就會觸發,就把出發的牌的序號添加進數組。這裏惟一要注意的是下面這個,首先屏蔽默認的右鍵事件。
document.oncontextmenu = function (event) { event.preventDefault(); if (event.button == 2) { addCardCount(event.target) } };
而後對event.target
進行處理就行了。
target
和currentTarget
的區別是:前者多是綁定事件元素下的子元素,後者是綁定事件元素自己。注意使用區別。
你看以前咱們的界面設計,當牌還有4個的時候是紅色加粗的,說明可能有炸彈;當沒有炸彈時是灰色的;當出完牌之後是帶透明的淡灰色。
這裏咱們只須要根據這個牌數來更改狀態就行了。關鍵是咱們怎麼改這個牌數會更方便呢?
你可能會使用innerHTML,innerText
?
CSS中的僞元素中的before
和after
裏面有個content
屬性,而這個屬性是能夠跟元素上的自定義屬性綁定的。好比說
.card::after { content: attr(count); position: absolute; bottom: 2px; right: 5px; color: #999; font-size: 18px; }
那麼這個content
的值就會跟隨元素的count屬性。因此咱們出牌的操做其實只須要更改這個屬性值就行了,而後根據值來作一些相應的類名添加和刪除便可。
使用這個記牌器之後,勝率並無高多少阿,淦!
我發現是運氣不行,別人把把超級加倍
打🔨啊,天天登錄就領幾千豆,一把歸西!
後續可能寫個運氣更改器
!
|
|
|
|
|
|
固然不可能啦。淦!
源碼中已經添加諸多備註。複製粘貼便可,後續可能會放到博客上提供下載連接,不用複製那麼辛苦啦。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>記牌器</title> <style> #box { display: flex; justify-content: center; align-items: stretch; user-select: none; } .card { position: relative; border-radius: 10px; width: 60px; margin-top: 20px; height: 100px; background-color: #f5f5f5; margin-right: 10px; box-shadow: 0 5px 5px 0 #c9c9c9; font-size: 28px; padding-left: 10px; } .card--empty { color: #c3c3c3; opacity: 0.8; } .card--chosen { margin-top: 0; } .card::after { content: attr(count); position: absolute; bottom: 2px; right: 5px; color: #999; font-size: 18px; } .card--warning::after { color: red; font-weight: bold; } #btn-box { text-align: center; margin-top: 30px; } button { padding: 10px 30px; border-radius: 60px; background-color: orangered; color: #fff; font-size: 32px; border: 0; cursor: pointer; transition: all ease .3s; margin-right: 20px; outline: none; } button:hover { background-color: red; transform: scale(1.1); } .info { font-size: 14px; margin-top: 70px; color: #999; } </style> </head> <body> <div id="box"></div> <div class="info"> <p>做者: <a href="http://www.leelei.info">leelei</a></p> <p>用法: 鼠標【點擊】直接出牌,或者【點擊滑動】出牌,右鍵單擊某張牌能夠增長牌數(用於防止點錯)</p> <p>適用於: 鬥地主新手,而且沒有錢買記牌器,而且常常開着電腦的時候順便手機玩鬥地主</p> </div> </body> <script> //常量 const arr = [3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', 2, '👻']; const nums = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2]; const TYPE_CHOSEN = ' card--chosen'; const TYPE_WARNING = ' card--warning'; const TYPE_EMPTY = ' card--empty'; //儲存已經選擇 let chosenArr = []; //添加類名 function addClass(e, name) { if (e.className.indexOf(name) == -1) { e.className += name; } } //移除類名 function removeClass(e, name) { e.className = e.className.replace(name, '') } //初始化卡片 function initCards() { let box = document.getElementById('box'); let frag = document.createDocumentFragment(); for (let i = 0; i < 14; i++) { let ele = document.createElement('div'); ele.className = 'card' + TYPE_WARNING; ele.innerText = arr[i]; ele.setAttribute('count', nums[i]); ele.setAttribute('index', i); frag.append(ele) } box.append(frag); } //初始化輸入 function initSlideInput() { let cards = document.getElementsByClassName('card'); //鼠標按下時註冊 box.addEventListener('mousedown', installSlideInput) //鼠標擡起卸載 box.addEventListener('mouseup', uninstallSlideInput) box.addEventListener('mouseleave', uninstallSlideInput) //註冊滑動輸入 function installSlideInput() { Array.from(cards).forEach((e) => { e.addEventListener('mouseenter', slideSelect) e.addEventListener('mouseleave', slideSelect) }) } //卸載滑動輸入 function uninstallSlideInput() { Array.from(cards).forEach((e) => { e.removeEventListener('mouseenter', slideSelect) e.removeEventListener('mouseleave', slideSelect) }) submit(); } //點擊輸入,一直有效 Array.from(cards).forEach((e) => { e.addEventListener('click', function (event) { slideSelect(event); submit(); }) }) //滑動輸入 function slideSelect(event) { let idx = event.currentTarget.getAttribute('index'); if (event.currentTarget.className.indexOf(TYPE_CHOSEN) == -1) { addClass(event.currentTarget,TYPE_CHOSEN) chosenArr.push(idx); } } } //重置所有牌的狀態,凸起->對齊 function reset() { chosenArr = []; let cards = document.getElementsByClassName('card'); Array.from(cards).forEach((v, i) => { removeClass(v,TYPE_CHOSEN) }); } //出牌 function submit() { let cards = document.getElementsByClassName('card'); chosenArr.forEach((v, i) => { cards[v].setAttribute('count', cards[v].getAttribute('count') - 1); removeClass(cards[v],TYPE_WARNING); if (cards[v].getAttribute('count') < 1) { //最小爲0,設置爲空狀態 cards[v].setAttribute('count', 0); addClass(cards[v],TYPE_EMPTY) } }); //重置狀態 reset(); } //右鍵加牌,防止出錯牌 function addCardCount(e) { if (e.getAttribute('count') != undefined) { e.setAttribute('count', e.getAttribute('count') - 0 + 1); } if (e.getAttribute('count') >= nums[e.getAttribute('index')]) { e.setAttribute('count', nums[e.getAttribute('index')]); addClass(e,TYPE_WARNING) } else if (e.getAttribute('count') > 0) { removeClass(e,TYPE_EMPTY); } } window.onload = function () { document.oncontextmenu = function (event) { event.preventDefault(); if (event.button == 2) { addCardCount(event.target) } }; initCards(); initSlideInput(); } </script> </html>