JS 简单实现拖拽评星的示例代码

 更新时间:2023年05月06日 08:28:21   作者:头疼脑胀的代码搬运工  
本文主要介绍了JS 简单实现拖拽评星,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

废话开篇:通过 canvas 简单拖拽评星,主要是通过个人的理解去实现这样的一个效果。

一、实现效果

html

<div class="main">
        <div class="score_container">
          <canvas id="canvas" height="100"></canvas>
          <div id="score" class="score">评分:0</div>
        </div>
    </div>

css

.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;
}

js

// 星星数据对象
    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}){
            // 它对应的整数分数
            this.score = currentPentagramIndex + 1
            // 工具函数
            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) {
                    // 最右侧的点
                    this.minX = point[0]
                }
                if(index == 3) {
                    // 最左侧的点
                    this.maxX = point[0]
                }
            })
        }
    }
    // 星星管理器
    class PentagramManage{
        canvas = null//画板相关
        context = null
        pentagramNum = 1//星星个数
        isMouseDown = false//鼠标是否按下
        progress = 0//当前评分位置
        pentagramRadius = 15//星星半径
        pentagramSep = 10//星星间间隔
        pentagrams = []//记录每一个星星对象
        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)')
            })
        }
        // 绑定鼠标事件
        bindMouseEvent(){
            document.onmousemove = (event)=>{
                if(this.isMouseDown){
                    let { left } = this.getElementPosition(document.getElementById('canvas'))
                    this.progress = event.clientX - left
                    this.draw()
                    this.getCurrentScore()
                }
            }
            //鼠标按下事件
            document.onmousedown = (event)=>{
                this.isMouseDown = true             
                let { left } = this.getElementPosition(document.getElementById('canvas'))
                    this.progress = event.clientX - left
                    this.draw()
                    this.getCurrentScore()
            }
            //鼠标抬起事件
            document.onmouseup = ()=>{
                this.isMouseDown = false
            }
        }
        // 计算分数
        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)

二、总结与思考

上层无镂空

上层有镂空

通过 canvas 实现一层镂空五角星层,再在底层添加一个进度层,这样在拖动的时候就能通过拖拽的位置进行数据处理,从而计算出星级数。代码拙劣,大神勿笑 

到此这篇关于JS 简单实现拖拽评星的示例代码的文章就介绍到这了,更多相关JS拖拽评星内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

最新评论