[點(diǎn)晴永久免費(fèi)OA]JS利用canvas簡單實(shí)現(xiàn)拖拽評星
廢話開篇:通過 canvas 簡單拖拽評星,主要是通過個(gè)人的理解去實(shí)現(xiàn)這樣的一個(gè)效果。 一、實(shí)現(xiàn)效果上層無鏤空 上層有鏤空 通過 canvas 實(shí)現(xiàn)一層鏤空五角星層,再在底層添加一個(gè)進(jìn)度層,這樣在拖動(dòng)的時(shí)候就能通過拖拽的位置進(jìn)行數(shù)據(jù)處理,從而計(jì)算出星級數(shù)。 <div class="main"> <div class="score_container"> <canvas id="canvas" height="100"></canvas> <div id="score" class="score">評分:0</div> </div> </div> .main { display: flex; flex-direction: row; justify-content: start; align-items: flex-start; padding-top: 20px; padding-left: 20px; } .score_container { display: flex; flex-direction: column; justify-content: center; align-items: center; padding-top: 20px; } .score { margin-top: 20px; } // 星星數(shù)據(jù)對象 class Pentagram{ points = [] minX = 0 maxX = 0 deg = (Math.PI / 180) score = 0 constructor(index,r,center){ this.savePentagramData(index,r,center) }
// 繪制星星 savePentagramData(currentPentagramIndex,r,{x,y}){ // 它對應(yīng)的整數(shù)分?jǐn)?shù) this.score = currentPentagramIndex + 1 // 工具函數(shù) let cos = (d)=>{ return Math.cos(d * this.deg) } let sin = (d)=>{ return Math.sin(d * this.deg) } let tan = (d)=>{ return Math.tan(d * this.deg) } let square = (num)=> { return Math.pow(num,2) } // 外邊比例 let t = 1 / ((1 + square(tan(18))) / (3 - square(tan(18)))) this.points = [ [0,1], [t*cos(54),t*sin(54)], [cos(18),sin(18)], [t*cos(18),-t*sin(18)], [cos(54),-sin(54)], [0,-t], [-cos(54),-sin(54)], [-t*cos(18),-t*sin(18)], [-cos(18),sin(18)], [-t*cos(54),t*sin(54)], [0,1], ] this.points.forEach((point,index)=>{ point[0] = x + point[0] * (r / t) point[1] = y + point[1] * (r / t) if(index == 7) { // 最右側(cè)的點(diǎn) this.minX = point[0] } if(index == 3) { // 最左側(cè)的點(diǎn) this.maxX = point[0] } }) } } // 星星管理器 class PentagramManage{ canvas = null//畫板相關(guān) context = null pentagramNum = 1//星星個(gè)數(shù) isMouseDown = false//鼠標(biāo)是否按下 progress = 0//當(dāng)前評分位置 pentagramRadius = 15//星星半徑 pentagramSep = 10//星星間間隔 pentagrams = []//記錄每一個(gè)星星對象 constructor(pentagramNum){ this.pentagramNum = pentagramNum this.initData() this.draw() this.bindMouseEvent() } // 初始化 initData(){ this.canvas = document.getElementById('canvas') for(let i = 0;i < this.pentagramNum;i ++){ let pentagram = new Pentagram(i,this.pentagramRadius,{x:35 + i * (this.pentagramRadius * 2 + this.pentagramSep),y:(this.canvas.height / 2.0) }) this.pentagrams.push(pentagram) if(i == this.pentagramNum - 1){ this.canvas.width = pentagram.maxX + 20 } } this.context = this.canvas.getContext('2d'); this.context.fillStyle='white'; } //繪制 draw(){ this.context.clearRect(0,0,this.canvas.width,this.canvas.height); this.drawBottomPlate() let hook = ()=>{ this.pentagrams.forEach((pentagramItem)=>{ this.drawPentagram(pentagramItem) }) } this.drawHollowOut(hook) this.drawStrokeHollowOut(hook) } // 繪制底色 drawBottomPlate(){ this.context.save() this.context.fillStyle= 'rgb(247,190,80)'; this.context.beginPath(); this.context.rect(0, 0, this.progress, this.canvas.height); this.context.closePath(); this.context.fill(); this.context.restore() } // 繪制鏤空五角星 drawHollowOut(hook){ this.context.beginPath(); this.context.rect(0, 0, this.canvas.width, this.canvas.height); hook() this.context.closePath(); this.context.fill(); } // 繪制五星邊框 drawStrokeHollowOut(hook){ this.context.save(); this.context.strokeStyle = 'rgb(247,190,80)'; // this.context.stroke.width = 1 this.context.beginPath(); this.context.rect(0, 0, this.canvas.width, this.canvas.height); hook() this.context.closePath(); this.context.stroke(); this.context.restore(); } // 繪制星星 drawPentagram(pentagramItem){ pentagramItem.points.forEach((point,index)=>{ eval('this.context.' + (index == 0 ? 'moveTo(' : 'lineTo(') + '...point)') }) } // 綁定鼠標(biāo)事件 bindMouseEvent(){ document.onmousemove = (event)=>{ if(this.isMouseDown){ let { left } = this.getElementPosition(document.getElementById('canvas')) this.progress = event.clientX - left this.draw() this.getCurrentScore() } } //鼠標(biāo)按下事件 document.onmousedown = (event)=>{ this.isMouseDown = true let { left } = this.getElementPosition(document.getElementById('canvas')) this.progress = event.clientX - left this.draw() this.getCurrentScore() } //鼠標(biāo)抬起事件 document.onmouseup = ()=>{ this.isMouseDown = false } } // 計(jì)算分?jǐn)?shù) getCurrentScore(){ let score = 0 let firstPentagram = this.pentagrams.find((pentagram)=>{ return this.progress <= pentagram.maxX }) if(firstPentagram){ let float = (Math.floor(((this.progress - firstPentagram.minX) / (firstPentagram.maxX - firstPentagram.minX)) * 10)) / 10 float = float > 0 ? float : 0 score = (firstPentagram.score - 1) + float document.getElementById('score').innerHTML = "評分:" + score } else { document.getElementById('score').innerHTML = "評分:" + this.pentagrams.length } } // dom在瀏覽器的位置 getElementPosition(element){ let top = element.offsetTop let left = element.offsetLeft let width = element.offsetWidth let height = element.offsetHeight var currentParent = element.offsetParent; while (currentParent !== null) { top += currentParent.offsetTop left += currentParent.offsetLeft currentParent = currentParent.offsetParent } return {top,left,width,height} } } var pentagram = new PentagramManage(4) 該文章在 2023/8/28 9:22:42 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |