我搜索了一下,没有找到如何使用JavaScript在canvas中画出螺旋形的具体方法。
我认为可能可以使用bezier曲线实现,如果这种方式不行,就只能使用lineTo()
了,但那看起来更加困难。
此外,如果要这样做,我想必须要使用三角函数和极坐标图形,而这已经有一段时间没碰过了。如果是这种情况,您能否指导我一下这方面的数学知识。
我搜索了一下,没有找到如何使用JavaScript在canvas中画出螺旋形的具体方法。
我认为可能可以使用bezier曲线实现,如果这种方式不行,就只能使用lineTo()
了,但那看起来更加困难。
此外,如果要这样做,我想必须要使用三角函数和极坐标图形,而这已经有一段时间没碰过了。如果是这种情况,您能否指导我一下这方面的数学知识。
阿基米德螺线表达式为r=a+b(angle)
。将其转换为x、y坐标,可表示为x=(a+b*angle)*cos(angle)
,y=(a+b*angle)*sin(angle)
。接下来你可以在for循环中使用角度,并像这样执行:
for (i=0; i< 720; i++) {
angle = 0.1 * i;
x=(1+angle)*Math.cos(angle);
y=(1+angle)*Math.sin(angle);
context.lineTo(x, y);
}
注意上面的内容假设a = 1且b = 1。
这里是一个jsfiddle链接: http://jsfiddle.net/jingshaochen/xJc7M/
i+=.1
的值,否则它看起来像是多边形。 - qw3n这是一个稍作改动、转变成javascript的Java螺旋图,我曾经从这里借鉴。
它使用lineTo()
函数,不是很难。
<!DOCTYPE HTML>
<html><body>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #c3c3c3;"></canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var centerX = 150;
var centerY = 150;
cxt.moveTo(centerX, centerY);
var STEPS_PER_ROTATION = 60;
var increment = 2*Math.PI/STEPS_PER_ROTATION;
var theta = increment;
while( theta < 40*Math.PI) {
var newX = centerX + theta * Math.cos(theta);
var newY = centerY + theta * Math.sin(theta);
cxt.lineTo(newX, newY);
theta = theta + increment;
}
cxt.stroke();
</script></body></html>
阿基米德螺线是一种数学曲线。
CanvasRenderingContext2D.prototype.drawArchimedeanSpiral =
CanvasRenderingContext2D.prototype.drawArchimedeanSpiral ||
function(centerX, centerY, stepCount, loopCount,
innerDistance, loopSpacing, rotation)
{
this.beginPath();
var stepSize = 2 * Math.PI / stepCount,
endAngle = 2 * Math.PI * loopCount,
finished = false;
for (var angle = 0; !finished; angle += stepSize) {
// Ensure that the spiral finishes at the correct place,
// avoiding any drift introduced by cumulative errors from
// repeatedly adding floating point numbers.
if (angle > endAngle) {
angle = endAngle;
finished = true;
}
var scalar = innerDistance + loopSpacing * angle,
rotatedAngle = angle + rotation,
x = centerX + scalar * Math.cos(rotatedAngle),
y = centerY + scalar * Math.sin(rotatedAngle);
this.lineTo(x, y);
}
this.stroke();
}
如果你有Illustrator,那么有一个非常好用的免费工具可以帮助你,它就是ai2canvas。
它可以为你创建所有曲线的JavaScript和HTML画布标签!
(如果你正在寻找阿基米德螺旋线,那么你首先需要从CorelDRAW中获取它并将其复制到Illustrator中,因为默认的螺旋线工具会随着每个点而扩大角度。)
spiral(ctx, {
start: {//starting point of spiral
x: 200,
y: 200
},
angle: 30 * (Math.PI / 180), //angle from starting point
direction: false,
radius: 100, //radius from starting point in direction of angle
number: 3 // number of circles
});
螺旋绘图代码:
spiral = function(ctx,obj) {
var center, eAngle, increment, newX, newY, progress, sAngle, tempTheta, theta;
sAngle = Math.PI + obj.angle;
eAngle = sAngle + Math.PI * 2 * obj.number;
center = {
x: obj.start.x + Math.cos(obj.angle) * obj.radius,
y: obj.start.y + Math.sin(obj.angle) * obj.radius
};
increment = 2 * Math.PI / 60/*steps per rotation*/;
theta = sAngle;
ctx.beginPath();
ctx.moveTo(center.x, center.y);
while (theta <= eAngle + increment) {
progress = (theta - sAngle) / (eAngle - sAngle);
tempTheta = obj.direction ? theta : -1 * (theta - 2 * obj.angle);
newX = obj.radius * Math.cos(tempTheta) * progress;
newY = obj.radius * Math.sin(tempTheta) * progress;
theta += increment;
ctx.lineTo(center.x + newX, center.y + newY);
}
ctx.stroke();
};
function drawSpiral(ctx, centerx, centery, innerRadius, outerRadius, turns=2, startAngle=0){
ctx.save();
ctx.translate(centerx, centery);
ctx.rotate(startAngle);
let r = innerRadius;
let turns_ = Math.floor(turns*4)/4;
let dr = (outerRadius - innerRadius)/turns_/4;
let cx = 0, cy = 0;
let directionx = 0, directiony = -1;
ctx.beginPath();
let angle=0;
for(; angle < turns_*2*Math.PI; angle += Math.PI/2){
//draw a quarter arc around the center point (x, cy)
ctx.arc( cx, cy, r, angle, angle + Math.PI/2);
//move the center point and increase the radius so we can draw a bigger arc
cx += directionx*dr;
cy += directiony*dr;
r+= dr;
//rotate direction vector by 90 degrees
[directionx, directiony] = [ - directiony, directionx ];
}
//draw the remainder of the last quarter turn
ctx.arc( cx, cy, r, angle, angle + 2*Math.PI*( turns - turns_ ))
ctx.stroke();
ctx.restore();
}
结果: