使用原生canvas做钟表实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>钟表</title>
<style>
canvas{
position: absolute;
left:10;
top:10;
}
</style>
</head>
<body>
<canvas id="dial_canvas"></canvas>
<canvas id="hand_canvas"></canvas>
<script>
var w = 800; //画布宽度
var h = 600; //画布高度
var r = 200; //表的半径
var dial_canvas = document.getElementById("dial_canvas"); //获取表盘canvasdom
var hand_canvas = document.getElementById("hand_canvas"); //获取指针canvasdom
dial_canvas.width = w;
dial_canvas.height = h;
hand_canvas.width = w;
hand_canvas.height = h;
var dial_cxt = dial_canvas.getContext("2d"); //获取表盘绘图环境
var hand_cxt = hand_canvas.getContext("2d"); //获取指针绘图环境
//绘制表盘
dial_cxt.beginPath();
dial_cxt.arc(w/2, h/2, r, 0, Math.PI*2);
dial_cxt.lineWidth = 10;
dial_cxt.strokeStyle = "#000";
dial_cxt.stroke();
//绘制刻度 小时 (大刻度)
drawScale(dial_cxt, w/2, h/2, r, r-20, 12, 10);
//绘制刻度 分钟(小刻度)
drawScale(dial_cxt, w/2, h/2, r, r-10, 60, 2);
//定时绘制指针
function run(){
var date = new Date(); //时间对象
//清空画布
hand_cxt.clearRect(0,0,w,h);
//获取秒
var seconds = date.getSeconds();
drawHand(hand_cxt, w/2, h/2, seconds / 60 * 360, 180, 2, "red");
//分针
var minutes = date.getMinutes() + seconds / 60;
drawHand(hand_cxt, w/2, h/2, minutes / 60 * 360, 150, 5, "#000");
//时针
var hours = date.getHours() % 12 + minutes / 60;
drawHand(hand_cxt, w/2, h/2, hours / 12 * 360, 120, 8, "#000");
setTimeout(run, 1000);
}
run();
/**
* 绘制指针
* @param object cxt 绘图环境
* @param number x 表中心的x坐标
* @param number y 表中心的y坐标
* @param number angle 指针旋转的角度
* @param number length 指针长度
* @param number lineWidth 指针宽度
* @param string strokeStyle 指针颜色
*/
function drawHand(cxt, x, y, angle, length, lineWidth=8, strokeStyle="#000") {
cxt.save(); //保存环境
cxt.beginPath(); //开启路径
cxt.translate(x, y);
cxt.rotate((angle - 90)/180 * Math.PI);
cxt.moveTo(-20, 0);
cxt.lineTo(length, 0);
cxt.lineWidth = lineWidth;
cxt.strokeStyle = strokeStyle;
cxt.stroke();
cxt.restore(); //恢复环境
}
/**
* 绘制刻度
* @param object cxt 绘图环境
* @param number x 圆心x坐标
* @param number y 圆心y坐标
* @param number innerRadius 内圆的半径
* @param number outerRadius 外圆的半径
* @param int number 刻度的个数
* @param number lineWidth 刻度的宽度
* @param string strokeStyle 刻度的颜色
*/
function drawScale(cxt,x,y,innerRadius,outerRadius, number = 12, lineWidth = 10, strokeStyle = "#000"){
var angle = 0;
var angleDiff = 360 / number; //间隔的度数
for (var i = 0; i < number; i ++) {
var x1 = Math.cos(angle / 180 * Math.PI) * outerRadius + w/2;
var y1 = Math.sin(angle / 180 * Math.PI) * outerRadius + h/2;
var x2 = Math.cos(angle / 180 * Math.PI) * innerRadius + w/2;
var y2 = Math.sin(angle / 180 * Math.PI) * innerRadius + h/2;
cxt.beginPath();
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.lineWidth = lineWidth;
cxt.strokeStyle = strokeStyle
cxt.stroke();
angle += angleDiff;
}
}
</script>
</body>
</html>
使用canvas库做钟表实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script src="../bower_components/konva/konva.min.js"></script>
<script>
//设置变量
var w = 800;
var h = 600;
var r = 200;
//创建舞台
var stage = new Konva.Stage({
width:w,
height:h,
container:"box"
})
//创建表盘层
var dialLayer = new Konva.Layer();
stage.add(dialLayer);
//绘制表盘
var dialCircle = new Konva.Circle({
x:w/2,
y:h/2,
radius:r,
stroke:"#000",
strokeWidth:10,
fill:"#eee"
})
dialLayer.add(dialCircle);
//绘制刻度
var bigDialScale = new DialScale({
x:w/2,
y:h/2,
outerRadius:r,
innerRadius:r-20,
stroke:"#000",
strokeWidth:10,
number:12
});
dialLayer.add(bigDialScale);
//绘制小刻度
var smallScale = new DialScale({
x:w/2,
y:h/2,
outerRadius:r,
innerRadius:r-10,
stroke:"#000",
strokeWidth:2,
number:60
});
dialLayer.add(smallScale);
//绘制
dialLayer.draw();
//创建指针层
var handLayer = new Konva.Layer();
stage.add(handLayer);
//秒针
var secondHand = new Konva.Line({
x:w/2,
y:h/2,
points:[-20,0,180,0],
stroke:"red",
strokeWidth:"2",
rotation:0
});
handLayer.add(secondHand);
//分针
var minuteHand = new Konva.Line({
x:w/2,
y:h/2,
points:[-20,0,150,0],
stroke:"#000",
strokeWidth:"5",
rotation:0
});
handLayer.add(minuteHand);
//时针
var hourHand = new Konva.Line({
x:w/2,
y:h/2,
points:[-20,0,120,0],
stroke:"#000",
strokeWidth:"8",
rotation:0
});
handLayer.add(hourHand);
var centerCirle = new Konva.Circle({
x:w/2,
y:h/2,
radius:10,
fill:"#000"
})
handLayer.add(centerCirle);
//绘制指针层
handLayer.draw();
function run(){
var date = new Date();
//秒针转动
var seconds = date.getSeconds();
secondHand.rotation(seconds/60 * 360 - 90);
//分针转动
var minutes = date.getMinutes() + seconds / 60;
minuteHand.rotation(minutes/60 * 360 - 90);
//时针转动
var hours = date.getHours() % 12 + minutes / 60;
hourHand.rotation(hours / 12 * 360 - 90);
handLayer.draw(); //重新绘制
setTimeout(run, 1000);
}
run();
/**
* 生成表盘刻度的构造函数
* @params object options 配置项
*/
function DialScale(options) {
options = options || {};
options.x = options.x || 0;
options.y = options.y || 0;
options.outerRadius = options.outerRadius || 0;
options.innerRadius = options.innerRadius || 0;
options.number = options.number || 12;
options.strokeWidth = options.strokeWidth || 10;
options.stroke = options.stroke || "#000";
//创建组
var group = new Konva.Group({
x:options.x,
y:options.y
});
//循环绘制刻度, 并且添加到组中
var angle = 0;
var angleDiff = 360 / options.number;
for (var i = 0; i < options.number; i ++) {
var line = new Konva.Line({
points:[Math.cos(angle / 180 * Math.PI) * options.outerRadius,
Math.sin(angle / 180 * Math.PI) * options.outerRadius,
Math.cos(angle / 180 * Math.PI) * options.innerRadius,
Math.sin(angle / 180 * Math.PI) * options.innerRadius
],
stroke:options.stroke,
strokeWidth:options.strokeWidth
});
group.add(line);
angle += angleDiff;
}
return group;
}
</script>
</body>
</html>
太阳系实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script src="../bower_components/konva/konva.js"></script>
<script>
var stage = new Konva.Stage({
container:"box",
width:window.innerWidth,
height:window.innerHeight
});
//定义变量
var cx = 400;
var cy = 400;
var bigRadius = 240;
var middleRadius = 160;
var centerRadius = 80;
//创建背景层
var bgLayer = new Konva.Layer();
stage.add(bgLayer);
//大圈
var bigCircle = new Konva.Circle({
x:cx,
y:cy,
radius:bigRadius,
stroke:"#ccc",
dash:[10,2]
});
bgLayer.add(bigCircle);
//中圈
var middleCircle = new Konva.Circle({
x:cx,
y:cy,
radius:middleRadius,
stroke:"#ccc",
dash:[10,2]
});
bgLayer.add(middleCircle);
//中心
var centerCircle = new CircleText({
x:cx,
y:cy,
innerRadius:centerRadius,
outerRadius:centerRadius+30,
innerFill:"#369",
outerFill:"#ddd",
text:"WEB前端",
fontSize:18,
fontWeight:"bold",
fontFill:"#fff",
fontX:-35,
fontY:-9
});
bgLayer.add(centerCircle);
bgLayer.draw();
//创建动画层
var layer = new Konva.Layer();
stage.add(layer);
//最外圈的小球
var bigCircleData = [
{
innerRadius:40,
outerRadius:50,
innerFill:"#5cb85c",
outerFill:"#ddd",
text:"HTML5",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
},
{
innerRadius:40,
outerRadius:50,
innerFill:"#5bc0de",
outerFill:"#ddd",
text:"CSS3",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
},
{
innerRadius:40,
outerRadius:50,
innerFill:"#f0ad4e",
outerFill:"#ddd",
text:"ECMA6",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
},
{
innerRadius:40,
outerRadius:50,
innerFill:"#d9534f",
outerFill:"#ddd",
text:"jQuery",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
},
{
innerRadius:40,
outerRadius:50,
innerFill:"#428bca",
outerFill:"#ddd",
text:"NodeJS",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
}
];
//创建一个组
var bigCircleGroup = new Konva.Group({
x:cx,
y:cy
});
layer.add(bigCircleGroup); //把组添加到层中
var angle = 0;
var angleDiff = 360 / bigCircleData.length;
bigCircleData.forEach(function(option, index){
option.x = Math.cos(angle / 180 * Math.PI) * bigRadius;
option.y = Math.sin(angle / 180 * Math.PI) * bigRadius;
var circleText = new CircleText(option);
bigCircleGroup.add(circleText); //添加到组中
angle += angleDiff;
});
//绘制 中间圈的小球
//定义数据
var middleCircleData = [
{
innerRadius:30,
outerRadius:40,
innerFill:"purple",
outerFill:"#ddd",
text:"VueJS",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
},
{
innerRadius:30,
outerRadius:40,
innerFill:"pink",
outerFill:"#ddd",
text:"Angle",
fontSize:14,
fontX:-20,
fontY:-7,
opacity:.7
}
]
//创建组
var middleCircleGroup = new Konva.Group({
x:cx,
y:cy
});
layer.add(middleCircleGroup);
//添加小圆圈
var angle1 = 0;
var angleDiff1 = 360 / middleCircleData.length;
middleCircleData.forEach(function(option, index){
option.x = Math.cos(angle1 / 180 * Math.PI) * middleRadius;
option.y = Math.sin(angle1 / 180 * Math.PI) * middleRadius;
var circleText = new CircleText(option);
middleCircleGroup.add(circleText); //添加到组中
angle1 += angleDiff1;
});
layer.draw();
//两个圈 要转
var angleSpeed = 60; //每秒钟转的角度
var animation = new Konva.Animation(function(frame){
var angleDiff = angleSpeed * frame.timeDiff / 1000;
//外圈转动
bigCircleGroup.rotate(angleDiff);
bigCircleGroup.getChildren().each(function(val, index){
val.rotate(-angleDiff);
})
//内圈转动
middleCircleGroup.rotate(-angleDiff);
middleCircleGroup.getChildren().each(function(val, index){
val.rotate(angleDiff);
})
}, layer);
animation.start();
//事件
bigCircleGroup.on("mouseenter", function(){
angleSpeed = 10;
}).on("mouseleave touchend", function(){
angleSpeed = 60;
})
/**
* 生成带文字的双层圆
*/
function CircleText(options) {
//配置项
options = options || {};
options.x = options.x || 0;
options.y = options.y || 0;
options.innerRadius = options.innerRadius || 0;
options.outerRadius = options.outerRadius || 0;
options.innerFill = options.innerFill || "red";
options.outerFill = options.outerFill || "#ddd";
options.text = options.text || "小萍萍";
options.fontFill = options.fontFill || "#fff";
options.fontSize = options.fontSize || 16;
options.fontWeight = options.fontWeight || "normal";
options.fontFamily = options.fontFamily || "MicrosoftYaHei";
options.fontX = options.fontX || 0;
options.fontY = options.fontY || 0;
options.opacity = options.opacity || 1;
//创建组
var group = new Konva.Group({
x:options.x,
y:options.y
})
//最中心的实心圆
var circle = new Konva.Circle({
x:0,
y:0,
radius:options.innerRadius,
fill:options.innerFill
});
group.add(circle);
//空心圆 圆环
var ring = new Konva.Ring({
x:0,
y:0,
innerRadius:options.innerRadius,
outerRadius:options.outerRadius,
fill:options.outerFill
});
group.add(ring);
//文字
var text = new Konva.Text({
x:options.fontX,
y:options.fontY,
text:options.text,
fill:options.fontFill,
fontSize:options.fontSize,
fontFamily:options.fontFamily,
fontWeight:options.fontWeight
});
group.add(text);
return group;
}
</script>
</body>
</html>
网友评论