canvas位置判斷

效果圖
這裏寫圖片描述

功能點

  • 1.百分比字幕在屏幕中間
  • 2.百分比和圓環動態展示,互相關聯
  • 3.鼠標移入圓環時,圖標變成手;移出恢復
  • 4.鼠標移入圓環是點擊,百分比暫停&開始動態切換
  • 5.鼠標在圓環外無點擊效果
  • 6.鼠標在canvas內時動態顯示位置

    不足:鼠標點擊控制圓環播放時,第一幀總是從頭開始繪製,有閃爍的效果。

代碼如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            text-align: center;
        }
        #canvas {
            margin: 100px auto;
            background: #aaa;
        }
        .pointer {
            cursor: pointer;
        }
    </style>
</head>
<body>
<p id="message">x=0 ,y=0</p>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
    (function () {
        let startDeg = -90;
        let endDeg = -90;
        let canvas = document.getElementById('canvas');
        let ctx = canvas.getContext('2d');
        let isRotate = true;
        let t = null;
        let RotateStep = 5;
        initCircle(RotateStep);

        //初始化頁面
        function initCircle(step) {
            drawCircle(0,360,'#fff');
            drawPercent('0%','#f00');
            t = setInterval(function () {
                if(endDeg > 270){
                    endDeg = -90;
                    ctx.clearRect(0,0,600,600);
                    drawCircle(0,360,'#fff');
                }
                drawCircle(startDeg,endDeg,'#3BB5FF');
                let percent = Math.round((endDeg+90)/360*1000)/10+'%';
                drawPercent(percent);
                endDeg+=step;
            },50);
        }

        //畫圓函數
        function drawCircle(startDeg,endDeg,color) {
            ctx.beginPath();
            ctx.arc(300,300,200,startDeg*Math.PI/180,endDeg*Math.PI/180);
            ctx.lineWidth = 30;
            ctx.strokeStyle = color;
            ctx.stroke();
        }

        //畫百分比
        function drawPercent(txt,color) {
            let width = ctx.measureText(txt).width;
            //擴大清除範圍,徹底清除字符
            ctx.clearRect((300-width/2-50),(300-25),width+100,50);
            ctx.textBaseline = 'top';
            ctx.font = '50px SimHei';
            ctx.fillStyle = color;
            ctx.fillText(txt,(300-width/2),(300-25));
        }


        //得到鼠標位置
        function getLocation(x,y) {
            let box = canvas.getBoundingClientRect();
            return {
                x:(x-box.left) * (canvas.width/box.width),
                y: (y - box.top) * (canvas.height / box.height)
                /*
                * 此處不用下面兩行是爲了防止使用CSS和JS改變了canvas的高寬之後是表面積拉大而實際
                * 顯示像素不變而造成的座標獲取不準的情況
                x: (x - box.left),
                y: (y - box.top)
                */
            }
        }

        //判斷鼠標是否在園內
        function judgeArea(a,b,r,location) {
            let distance =(location.x-a)*(location.x-a) + (location.y-b)*(location.y-b);
            return (distance <= r*r) ? 1 : 0;
            /*
             *圓的數學公式(x-a)²+(y-b)²=r²
             */
        }

        //添加監聽事件,addEventListener可以對同一個元素添加多個監聽事件
        canvas.addEventListener('mousemove',function (e) {
            let location = getLocation(e.clientX,e.clientY);
            document.getElementById('message').innerHTML = `x=${location.x} ,y=${location.y}`;
            judgeArea(300,300,200,location) ? (canvas.className = 'pointer') : (canvas.className = '');
        },false);

        canvas.addEventListener('click',function (e) {
            let location = getLocation(e.clientX,e.clientY);
            if( judgeArea(300,300,200,location) ){
                if(isRotate){
                    clearInterval(t);
                    t=null;
                }else {
                    initCircle(RotateStep);
                }
                isRotate = !isRotate;
            }
        },false)
    })()
</script>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章