模板效果
![](https://i-blog.csdnimg.cn/blog_migrate/3e8531160f31c72bc1aab3950a3aae45.gif)
模板代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>中秋画圆,比一比谁画的圆 | 公众号:HTML5 WEB前端分享</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="yes" name="apple-touch-fullscreen" />
<meta content="telephone=no,email=no" name="format-detection" />
<link rel="stylesheet" type="text/css" href="http://css.h5course.cn/reset-1.0.0.css">
<script src="http://js.h5course.cn/jquery-1.11.3.min.js"></script>
<script src="http://js.h5course.cn/paper-full.min.js"></script>
<style type="text/css">
html,
body {
height: 100%;
background-color: #000;
}
canvas[resize] {
width: 100%;
height: 100%;
}
.btn {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
color: #fff;
font-size: 18px;
text-align: center;
line-height: 50px;
background-color: #009dec;
}
</style>
</head>
<body ontouchmove="event.preventDefault();" data-info="公众号:HTML5 WEB前端分享">
<canvas id="myCanvas" resize hidpi="on"></canvas>
<div class="btn">点击重新开始</div>
</body>
<script type="text/paperscript" canvas="myCanvas">
var vw = view.viewSize.width;
var vh = view.viewSize.height;
var vw2 = vw / 2;
var vh2 = vh / 2;
var vwMax = Math.max(vw, vh);
var vwMin = Math.min(vw, vh);
// 定义绘制的状态
var drawStatus = 1;
// 定义绘制路径对象
var drawPath = null;
// 填充旋转角度
var fillRotateDeg = 0;
// 填充线的集合
var fillLines = [];
// 最终的画的圆
var resultCircle = null;
// 默认完美度0
var perfect = 100;
var showResult = false;
// 视图中心点
var centerPoint = new Point(vw2, vh2);
var circleRadius = vwMin / 2 - 40;
// 绘制提示的圆形
var tipCircle = new Path.Circle(centerPoint, circleRadius);
tipCircle.strokeColor = '#fff';
tipCircle.strokeWidth = 3;
// 绘制提示的半径
var tipRadiusLine = new Path.Line(centerPoint, new Point(vw2 - circleRadius, vh2));
tipRadiusLine.strokeColor = '#fff';
tipRadiusLine.rotate(110, centerPoint);
// 填充线的起始线(先不设置颜色,隐藏起来)
var fillLongLine = new Path.Line(centerPoint, new Point(vh2 - vwMax, vh2));
fillLongLine.rotate(110, centerPoint);
/**
* 动画处理函数
* @param {[type]} event [description]
* @return {[type]} [description]
* @author 懂点君 公众号:HTML5 WEB前端分享
*/
function onFrame(event) {
// event.delta:自上一帧事件以来经过的时间(以秒为单位)
event.delta = (event.delta > 0.2) ? 0.2 : event.delta;
// 准备开始绘制
if(drawStatus === 1) {
// 隐藏提示的圆形
if (tipCircle.visible) {
var opacity = tipCircle.opacity - 1 * event.delta;
// 防止透明度值变成负数
if (opacity < 0) {
opacity = 0;
tipCircle.visible = false;
}
tipCircle.opacity = opacity;
}
// 绘制结束
} else if(drawStatus === 2) {
// 设置提示的圆形可见
if (!tipCircle.visible) {
tipCircle.visible = true;
}
// 缓慢显示提示的圆形
if(tipCircle.opacity < 1) {
opacity = tipCircle.opacity + 1 * event.delta;
// 防止透明度值超过1
if (opacity > 1) {
opacity = 1;
}
tipCircle.opacity = opacity;
// 填充中间的线
} else {
if(fillRotateDeg < 360) {
var rotateDeg = event.delta * 150;
fillRotateDeg += rotateDeg;
// 防止超出360度
if(fillRotateDeg > 360) {
rotateDeg = 360 - fillRotateDeg + rotateDeg;
fillRotateDeg = 360;
}
// 提示的线旋转
tipRadiusLine.rotate(rotateDeg, centerPoint);
// 填充的线旋转
fillLongLine.rotate(rotateDeg, centerPoint);
// 获取填充线与用户绘制线的交集点
var intersectionsDraw = fillLongLine.getIntersections(drawPath);
// 获取填充线与提示圆形的交集点
var intersectionsCircle = fillLongLine.getIntersections(tipCircle);
// 填充线的起点
var point1 = centerPoint;
if (intersectionsDraw.length) {
point1 = intersectionsDraw[0].point;
}
// 填充线的终点
var point2 = point1;
if (intersectionsCircle.length) {
point2 = intersectionsCircle[0].point;
}
// 绘制填充线
var fillLine = new Path.Line(point1, point2);
// fillLines用于再次重新开始绘制
fillLines.push(fillLine);
fillLine.strokeWidth = 2.5;
fillLine.strokeColor = '#fff';
// 最终画的圆(最终形成用户画的圆形)
if(!resultCircle) {
resultCircle = new Path();
resultCircle.visible = false;
}
// 把起点连接起来(最终形成用户画的圆形)
resultCircle.add(point1);
// 判断画的好不好
var distance = point1.getDistance(point2);
// 每一条填充线的长度接近0的话,这个圆就画的很圆
perfect -= (distance / circleRadius * rotateDeg / 360) * 100;
// 防止分数出现负数
if (perfect < 0) {
perfect = 0;
}
console.log(perfect);
} else {
if(!resultCircle.visible) {
// 关闭路径
resultCircle.closed = true;
// 平滑的路径
resultCircle.smooth();
resultCircle.strokeColor = '#FFEB3B';
resultCircle.strokeWidth = 3;
resultCircle.opacity = 0;
resultCircle.visible = true;
} else {
if(resultCircle.opacity < 0.75) {
var opacity = resultCircle.opacity + 1 * event.delta;
// 防止透明度超出
if (opacity > 1) {
opacity = 1;
}
// 显示最终绘制的圆
resultCircle.opacity = opacity;
// 隐藏绘制的线
drawPath.opacity = 1 - opacity;
} else {
// 弹出分数
if(!showResult) {
alert(parseInt(perfect) + '分');
showResult = true;
}
}
}
}
}
}
// 每秒最多调用60次;执行onFrame函数后,视图将自动重新绘制;
console.log('动画执行啦');
}
/**
* 鼠标按下触发
* @param {[type]} event [description]
* @return {[type]} [description]
* @author 懂点君 公众号:HTML5 WEB前端分享
*/
function onMouseDown(event) {
if(drawStatus === 1 && !drawPath) {
drawPath = new Path({
segments: [event.point],
strokeColor: '#fff',
});
drawPath.strokeWidth = 6;
}
console.log('鼠标按下啦');
}
/**
* 鼠标拖拽触发
* @param {[type]} event [description]
* @return {[type]} [description]
* @author 懂点君
*/
function onMouseDrag(event) {
if(drawStatus === 1) {
drawPath.add(event.point);
}
console.log('鼠标拖拽啦');
}
/**
* 鼠标抬起触发
* @param {[type]} event [description]
* @return {[type]} [description]
* @author 懂点君 公众号:HTML5 WEB前端分享
*/
function onMouseUp(event) {
if(drawStatus === 1 && drawPath) {
// 绘制结束
drawStatus = 2;
}
console.log('鼠标抬起啦');
}
$('.btn').click(function() {
// 移除图形
tipCircle.remove();
tipRadiusLine.remove();
fillLongLine.remove();
resultCircle.remove();
drawPath.remove();
fillLines.forEach(function (line) {
line.remove();
})
// 绘制提示的圆形
tipCircle = new Path.Circle(centerPoint, circleRadius);
tipCircle.strokeColor = '#fff';
tipCircle.strokeWidth = 3;
// 绘制提示的半径
tipRadiusLine = new Path.Line(centerPoint, new Point(vw2 - circleRadius, vh2));
tipRadiusLine.strokeColor = '#fff';
tipRadiusLine.rotate(110, centerPoint);
// 填充线的起始线(先不设置颜色,隐藏起来)
fillLongLine = new Path.Line(centerPoint, new Point(vh2 - vwMax, vh2));
fillLongLine.rotate(110, centerPoint);
// 定义绘制的状态
drawStatus = 1;
// 定义绘制路径对象
drawPath = null;
// 填充旋转角度
fillRotateDeg = 0;
// 填充线的集合
fillLines = [];
// 最终的画的圆
resultCircle = null;
// 默认完美度0
perfect = 100;
showResult = false;
});
</script>
</html>
![](https://i-blog.csdnimg.cn/blog_migrate/243a7e0f1b8a8e13434298bc3e109dc7.png)