效果圖
功能點
- 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>