我正在将flash动画转换为javascript / html5。我的动画看起来非常相似,但是,我正在努力完成我在html5画布上绘制的星星上的旋转。我使用的是该网站代码的变体:http://programmingthomas.wordpress.com/2012/05/16/drawing-stars-with-html5-canvas/作为参考,我已粘贴下面的相关代码。
function star(ctx, x, y, r, p, m)
{
ctx.save();
ctx.beginPath();
ctx.translate(x, y);
ctx.moveTo(0,0-r);
for (var i = 0; i < p; i++)
{
ctx.rotate(Math.PI / p);
ctx.lineTo(0, 0 - (r*m));
ctx.rotate(Math.PI / p);
ctx.lineTo(0, 0 - r);
}
ctx.fill();
ctx.restore();
}
我已经想出如何通过插入ctx.rotate()
来调整围绕其中心的星星,如下所示:
...beginPath();
ctx.translate(x, y);
ctx.rotate(radianOffset);
ctx.moveTo(0,0-r);
for (var i = 0...
是否有人有任何线索如何围绕其中一个点旋转恒星?我一直在阅读有关旋转功能的内容,但无法弄清楚如何使其与星形函数一起使用。
答案 0 :(得分:1)
只需转换到您想要旋转的点,旋转然后平移回来继续绘制星星。
然而,使用你正在使用的功能可能会变得比仅仅更复杂,因为你需要星点“尖峰”的点的绝对位置。
这是我写的一个替代实现来处理这个问题。在这里,我们调用一个函数来获取带有点的数组,以便构建一个星。
然后我们可以使用该点阵列来选择旋转的枢轴点以及渲染星本身。该函数如下所示:
// cx = center x
// cy = center y
// r1 = outer radius
// r2 = inner radius
// spikes = number of star "spikes"
function getStarPoints(cx, cy, r1, r2, spikes) {
var i = 0,
deltaAngle = (2 * Math.PI) / spikes,
x, y,
points = [];
// calc rest of points
for (; i < spikes; i++) {
points.push(
{
x: cx + r2 * Math.cos(deltaAngle * i), // calc inner point
y: cy + r2 * Math.sin(deltaAngle * i)
}, {
x: cx + r1 * Math.cos(deltaAngle * i + deltaAngle * 0.5), // outer point
y: cy + r1 * Math.sin(deltaAngle * i + deltaAngle * 0.5)
}
);
}
return points;
}
现在我们需要做的就是从数组中选取一个点作为点对象,并将其用于旋转中心,这里点索引1:
ctx.translate(points[1].x, points[1].y); // translate to origin for rotation
ctx.rotate(angle); // rotate angle (radians)
ctx.translate(-points[1].x, -points[1].y); // translate back
然后渲染星星
ctx.beginPath(); // start a new path
ctx.moveTo(points[0].x, points[0].y); // starting point
for(var i = 1, p; p = points[i++];)
ctx.lineTo(p.x, p.y); // add points to path
ctx.fill(); // close and fill
注意:如果你想抚摸星星,你需要在抚摸之前使用closePath()
。
就是这样。请参阅下面的代码段,了解此动画版本以及完整来源。
性能方面,这将更快,我们只计算一次星,并且在这种情况下,我们不使用动画的保存/恢复(这是一些成本高昂的操作)。
希望这有帮助!
var ctx = document.getElementById('canvas').getContext('2d'),
points = [],
angleStep = 0.025;
ctx.fillStyle = 'orange';
// draw first star at angle 0 and get point array
points = getStarPoints(150, 90, 80, 40, 5);
// now that we know the point for each part, lets animate
loop();
function loop() {
// clear canvas
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// rotate around one of the points (or anywhere if wanted..)
ctx.translate(points[1].x, points[1].y);
ctx.rotate(angleStep);
ctx.translate(-points[1].x, -points[1].y);
// draw start
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for(var i = 1, p; p = points[i++];) ctx.lineTo(p.x, p.y);
ctx.fill();
requestAnimationFrame(loop);
}
// Star by Ken Fyrstenberg/CC3.0-Attr
// cx = center x
// cy = center y
// r1 = outer radius
// r2 = inner radius
// spikes = number of star "spikes"
function getStarPoints(cx, cy, r1, r2, spikes) {
var i = 0,
deltaAngle = (2 * Math.PI) / spikes,
x, y,
points = [];
// calc rest of points
for (; i < spikes; i++) {
points.push(
{
x: cx + r2 * Math.cos(deltaAngle * i),
y: cy + r2 * Math.sin(deltaAngle * i)
}, {
x: cx + r1 * Math.cos(deltaAngle * i + deltaAngle * 0.5),
y: cy + r1 * Math.sin(deltaAngle * i + deltaAngle * 0.5)
}
);
}
return points;
}
<canvas id="canvas" width=350 height=180></canvas>