LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

[点晴永久免费OA]JS利用canvas简单实现拖拽评星

freeflydom
2023年8月28日 9:22 本文热度 611

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

一、实现效果

上层无镂空

上层有镂空

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

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

}


// 星星数据对象

    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)


查看原文


该文章在 2023/8/28 9:22:42 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved