我有一个html5 canvas
显示,我想在用户点击后旋转。我试图找出允许动画生效的最佳方法。我希望旋转平滑,无论用户点击所选面板的哪个位置都会旋转到顶部。
我不确定最好的方法,因为这是我的第一个画布项目,我想我会为你们所有人开场。
这是一个小提琴:http://jsfiddle.net/JRgtg/
提前感谢您的帮助!
答案 0 :(得分:2)
你的任务相当复杂:
点击金弧之前和之后的弧位置图示。
金弧旋转到顶部:
注释示例代码和演示:http://jsfiddle.net/m1erickson/ZUtL8/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
// canvas and context reference variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
// save PI to variables since they are used often
var PI=Math.PI;
var PI2=Math.PI*2;
// animation variables
var rotation;
var desiredRotation;
var deltaRotation=PI/120; // rotate at about 360 degrees over 2 seconds
// define a color for each segment
var colors=["red","green","blue","gold","purple"];
var topAngle=clampAngle(PI*3/2-(PI2/colors.length)/2);
var gapAngle=2*PI/180; // 3 degree gap between arcs
// hold the arc objects in an arcs[] array
var arcs=createArcs(150,150,50,75,colors);
// draw the arcs
for(var i=0;i<arcs.length;i++){
drawArc(arcs[i],true);
}
// listen for mouse events
$("#canvas").mousedown(function(e){handleMouseDown(e);});
// utility function
// make sure angles are expressed between 0 & 2*PI
function clampAngle(a){
return((a+PI2*2)%PI2);
}
// create arc objects for each color
function createArcs(cx,cy,insideRadius,outsideRadius,colors){
var arcs=[];
for(var i=0;i<colors.length;i++){
var a1=clampAngle(i*PI2/colors.length+topAngle);
var a2=clampAngle(a1+PI2/colors.length-gapAngle);
arcs.push({
segment:i,
x:cy,
y:cy,
r1:insideRadius,
r2:outsideRadius,
a1:a1,
a2:a2,
color:colors[i],
rotation:0
});
}
return(arcs);
}
// draw one arc
function drawArc(arc,draw){
var x = arc.x + arc.r1 * Math.cos(arc.a2);
var y = arc.y + arc.r1 * Math.sin(arc.a2);
// define
ctx.beginPath();
ctx.arc(arc.x,arc.y,arc.r2,arc.a1,arc.a2);
ctx.lineTo(x, y);
ctx.arc(arc.x,arc.y,arc.r1,arc.a2,arc.a1,true);
ctx.closePath();
//
if(draw){
ctx.fillStyle=arc.color;
ctx.fill();
}
}
// handle mouse events
function handleMouseDown(e){
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// hit test each arc
var hit=-1;
for(var i=0;i<arcs.length;i++){
// define the target arc
drawArc(arcs[i]);
if(ctx.isPointInPath(mouseX,mouseY)){
hit=i;
}
}
// if use clicked on arc, rotate it to the top
if(hit>=0){
rotation=0;
desiredRotation=clampAngle(topAngle-arcs[hit].a1);
animate();
}
}
// animate the rotation of the clicked arc
function animate(){
// stop animating if the arc has been rotated to the top
if(rotation<=desiredRotation){ requestAnimationFrame(animate); }
if(rotation>desiredRotation){ rotation=desiredRotation; }
// clear the canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
// add a rotation increment to each arc
for(var i=0;i<arcs.length;i++){
var arc=arcs[i];
arc.a1=clampAngle(arc.a1+deltaRotation);
arc.a2=clampAngle(arc.a2+deltaRotation);
drawArc(arc,true);
}
// increase the rotation angle by the rotation increment
rotation=clampAngle(rotation+deltaRotation);
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Click on a color-arc and it will rotate to top.</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>