代码:
<!DOCTYPE html>
<html>
<head lang="zh-CN">
<meta charset="UTF-8">
<title>canvas</title>
<style>
#box{
width: 600px;
height: 600px;
position: relative;
margin-left: 100px;
}
#hover{
width: 100px;
height: 35px;
text-align: center;
line-height: 35px;
font-size: 22px;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #000;
background-color: #f1f100;
position: absolute;
top: 10px;
right: 10px;
}
#click{
width: 100px;
height: 35px;
text-align: center;
line-height: 35px;
font-size: 22px;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #000;
background-color: #00ffff;
position: absolute;
top: 10px;
left: 10px;
}
</style>
</head>
<body>
<div id="box">
<canvas id="clock" width="600px" height="600px">您的浏览器不支持canvas</canvas>
<div id="hover">0.0</div>
<div id="click">0.0</div>
</div>
<script type="text/javascript">
var clock = document.getElementById("clock");
clock.style.backgroundColor = "black";
var graph = null;
var outside_circle_r = 300;/*外圆半径*/
var inside_circle_r = 230;/*内圆半径*/
if (clock.getContext) {
drawClock();
}
function drawClock() {
graph = clock.getContext("2d");
/*先清除整个图*/
graph.clearRect(0, 0, clock.width, clock.height);
graph.strokeStyle = "black";
graph.save();
graph.beginPath();
//画圆
graph.strokeStyle = "white";
graph.moveTo(550,300);
graph.arc(300,300,inside_circle_r,0,2*Math.PI,false);
graph.stroke();
//画大刻度
var hour_len = 20;//刻度长度
var hourAngleArray = [];
for(let i = 0;i < 10;i++){
hourAngleArray.push(i*Math.PI/18);
}
drawHourAndMinuteLine(hourAngleArray,hour_len);
//画小刻度
var minuteAngleArray = [];
var minute_len = 10;//刻度长度
for(let i = 0;i < 360;i++){
minuteAngleArray.push(i*Math.PI/90);
}
drawHourAndMinuteLine(minuteAngleArray,minute_len);
//画刻度文本值
// x = 圆心x + r * Math.cos( Math.PI / 180 * angle)
// y = 圆心y + r * Math.sin(Math.PI / 180 * angle)
for (let index = 0; index < 360; index+=10) {
const angle = index - 90
const x1 = 300 + inside_circle_r * Math.cos(Math.PI / 180 * angle)
const y1 = 300 + inside_circle_r * Math.sin(Math.PI / 180 * angle)
const x = x1+Math.cos(2*Math.PI/360*angle)*40
const y = y1+Math.sin(2*Math.PI/360*angle)*40
drawText("white","bold 16px Arial","center","middle",index,x,y);
}
// 画之前点击的线
if(localStorage.getItem("clickLineX") && localStorage.getItem("clickLineY")){
drawClickLine(localStorage.getItem("clickLineX"),localStorage.getItem("clickLineY"))
}
// 画仰度的点
drawCricle()
}
function drawText(fillStyle,font,textAlign,textBaseline,size,x,y){
graph.fillStyle = fillStyle;
graph.font = font;
graph.textAlign = textAlign;
graph.textBaseline = textBaseline;
graph.fillText(size,x,y);
}
/*画一条线段的函数*/
function drawStraightLine(color,X,Y,toX,toY){
graph.beginPath();
graph.strokeStyle = color;
graph.moveTo(X,Y);
graph.lineTo(toX,toY);
graph.stroke();
}
/*画出时间刻度*/
function drawHourAndMinuteLine(timeType,len){
for(let i = 0;i < timeType.length;i++){
let x = outside_circle_r+inside_circle_r*Math.cos(timeType[i]);
let y = outside_circle_r-inside_circle_r*Math.sin(timeType[i]);
let toX = x+len*Math.cos(timeType[i]);
let toY = y-len*Math.sin(timeType[i]);
let toXLeftTop = outside_circle_r-inside_circle_r*Math.cos(timeType[i])-len*Math.cos(timeType[i]);
let toYRightBottom = outside_circle_r+inside_circle_r*Math.sin(timeType[i]);
drawStraightLine("white",x,y,toX,toY);//右上刻度
drawStraightLine("white",outside_circle_r-inside_circle_r*Math.cos(timeType[i]),y,toXLeftTop,toY);//左上刻度
drawStraightLine("white",x,toYRightBottom,toX,toYRightBottom+len*Math.sin(timeType[i]));//右下刻度
drawStraightLine("white",outside_circle_r-inside_circle_r*Math.cos(timeType[i]),toYRightBottom,toXLeftTop,toYRightBottom+len*Math.sin(timeType[i]));//左下刻度
}
}
window.onload=function(){
// 鼠标悬停事件
clock.onmousemove=function(e){
// 0-180度的角度
if(e.offsetY<=600&&e.offsetY>=300){
const angle1 = Math.atan((e.offsetX-outside_circle_r)/(e.offsetY-outside_circle_r))*180/Math.PI
document.getElementById("hover").textContent = (90-angle1 +90).toFixed(1)
const follwLineX = 300 + inside_circle_r * Math.cos( Math.PI / 180 * (90-angle1))
const follwLineY = 300 + inside_circle_r * Math.sin( Math.PI / 180 * (90-angle1))
drawClock();
drawFollwLine(follwLineX,follwLineY)
}else{
// 180-360的角度
const angle1 = Math.atan((e.offsetX-outside_circle_r)/(e.offsetY-outside_circle_r))*180/Math.PI
const temp = 270-angle1
if(temp >= 180 && temp < 270){
document.getElementById("hover").textContent = (temp +90).toFixed(1)
}else{
document.getElementById("hover").textContent = (temp-270).toFixed(1)
}
const follwLineX = 300 + inside_circle_r * Math.cos( Math.PI / 180 * (270-angle1))
const follwLineY = 300 + inside_circle_r * Math.sin( Math.PI / 180 * (270-angle1))
drawClock();
drawFollwLine(follwLineX,follwLineY)
}
}
// 鼠标点击
clock.onclick=function(e){
// 0-180度的角度
if(e.offsetY<=600&&e.offsetY>=300){
const angle1 = Math.atan((e.offsetX-outside_circle_r)/(e.offsetY-outside_circle_r))*180/Math.PI
document.getElementById("click").textContent = (90-angle1 +90).toFixed(1)
const follwLineX = 300 + inside_circle_r * Math.cos( Math.PI / 180 * (90-angle1))
const follwLineY = 300 + inside_circle_r * Math.sin( Math.PI / 180 * (90-angle1))
localStorage.setItem("clickLineX",follwLineX);
localStorage.setItem("clickLineY",follwLineY);
drawClock();
drawClickLine(follwLineX,follwLineY)
}else{
// 180-360的角度
const angle1 = Math.atan((e.offsetX-outside_circle_r)/(e.offsetY-outside_circle_r))*180/Math.PI
const temp = 270-angle1
if(temp >= 180 && temp < 270){
document.getElementById("click").textContent = (temp +90).toFixed(1)
}else{
document.getElementById("click").textContent = (temp-270).toFixed(1)
}
const follwLineX = 300 + inside_circle_r * Math.cos( Math.PI / 180 * (270-angle1))
const follwLineY = 300 + inside_circle_r * Math.sin( Math.PI / 180 * (270-angle1))
localStorage.setItem("clickLineX",follwLineX);
localStorage.setItem("clickLineY",follwLineY);
drawClock();
drawClickLine(follwLineX,follwLineY)
}
}
}
// 跟随线
function drawFollwLine(follwLineX,follwLineY){
graph.save();//保存新的圆点
graph.beginPath();
graph.strokeStyle = "#f1f100";
graph.moveTo(follwLineX, follwLineY);
graph.lineTo(300, 300);
graph.stroke();
graph.stroke();
}
//点击线
function drawClickLine(follwLineX,follwLineY){
graph.save();//保存新的圆点
graph.beginPath();
graph.strokeStyle = "#00ffff";
graph.moveTo(follwLineX, follwLineY);
graph.lineTo(300, 300);
graph.stroke();
graph.stroke();
}
// 根据刻度打点
// x = 圆心x + r * Math.cos( Math.PI / 180 * angle)
// y = 圆心y + r * Math.sin(Math.PI / 180 * angle)
function drawPoint(direction,jantho,rgba){
// 幅度计算透明度
const opacity = rgba/100
const rgba1 = 'rgba(225,0,0,'+opacity+')'
const angle = direction - 90
// 通过半径和仰角,计算在圆上的斜边长度
const proportion = (inside_circle_r * jantho) / 90
// 计算刻度在圆上的位置
const x1 = 300 + inside_circle_r * Math.cos(Math.PI / 180 * angle)
const y1 = 300 + inside_circle_r * Math.sin(Math.PI / 180 * angle)
// 计算 根据仰度绘制的三角形的对边和临边的长度
const angle1 = 90-(direction - 90)
const x2 = x1- Math.sin(Math.PI / 180 * angle1)*proportion
const y2 = y1- Math.cos(Math.PI / 180 * angle1)*proportion
// 画圆
graph.fillStyle = rgba1;
graph.moveTo(x2+5,y2);
graph.arc(x2,y2,5,0,2*Math.PI,false);
graph.fill();
}
function drawCricle(){
const dataArray = [
[126,10,53],
[125,10,72],
[123,10,55],
[126,10,85],
[122,10,85],
[125,10,100],
[128,10,90],
[128,10,80],
[126,10,70],
[124,10,10],
[190,10,0],
[210,10,50],
[230,10,100],
[300,10,40],
[30,10,50],
[124,10,60]
]
let index = 0
const timeout = setInterval(()=>{
if(index<dataArray.length){
drawPoint(dataArray[index][0],dataArray[index][1],dataArray[index][2])
index++
}else{
clearInterval(timeout);
}
},200)
}
</script>
</body>
</html>
效果: