如何在不旋转整个画布的情况下旋转三角形
How to rotate a triangle without rotating the entire canvas?
我是刚开始和<canvas>
一起工作的,在数学方面很糟糕。我正在画布上绘制一个简单的等边三角形,其中包含从其他人那里借用的代码(不要讨厌我):
drawTriangle(PosX, PosY, SideLength, Orientation) {
context.beginPath();
var sides = 3;
var a = ((Math.PI * 2) / sides);
context.moveTo(PosX + SideLength, PosY);
for (var i = 1; i < sides + 1; i++) {
context.lineTo(PosX + SideLength * Math.cos(a*i), PosY + SideLength * Math.sin(a*i));
}
context.closePath();
return true;
}
该函数只知道三角形的中心坐标和指向它的方向,没有别的。
它目前成功地绘制了三角形,但"指向"东。
如何使用 Orientation
参数(度)旋转三角形,而无需像其他答案建议的那样旋转整个画布?
下面是一个绘制任何常规多边形和指定角度的函数:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var sideCount=3;
var size=40;
var centerX=50;
var centerY=50;
var strokeWidth=4;
var strokeColor='purple';
var fillColor='skyblue';
var rotationDegrees=0;
var rotationIncrement=1;
var nextTime=0;
var delay=1000/60*1;
requestAnimationFrame(animate);
function animate(time){
if(time<nextTime){requestAnimationFrame(animate);return;}
nextTime=time+delay;
ctx.clearRect(0,0,cw,ch);
drawPolygon(centerX,centerY,sideCount,size,strokeWidth,strokeColor,fillColor,rotationDegrees);
rotationDegrees+=rotationIncrement;
requestAnimationFrame(animate);
}
function drawPolygon(centerX,centerY,sideCount,size,strokeWidth,strokeColor,fillColor,rotationDegrees){
var radians=rotationDegrees*Math.PI/180;
ctx.translate(centerX,centerY);
ctx.rotate(radians);
ctx.beginPath();
ctx.moveTo (size * Math.cos(0), size * Math.sin(0));
for (var i = 1; i <= sideCount;i += 1) {
ctx.lineTo (size * Math.cos(i * 2 * Math.PI / sideCount), size * Math.sin(i * 2 * Math.PI / sideCount));
}
ctx.closePath();
ctx.fillStyle=fillColor;
ctx.strokeStyle = strokeColor;
ctx.lineWidth = strokeWidth;
ctx.stroke();
ctx.fill();
ctx.rotate(-radians);
ctx.translate(-centerX,-centerY); }
<canvas id="canvas" width=512 height=512></canvas>
<canvas id="canvas" width=512 height=512></canvas>
请看这把小提琴。您可以将方向作为可选参数发送。它接受"东"、"西"、"北"、"南"。请验证。
'函数 drawTriangle(PosX, PosY, SideLength, Orientation) {
if (!Orientation) {
Orientation = 'east';
}
context.beginPath();
var sides = 3;
var a = ((Math.PI * 2) / sides);
// the components have negative contributions
if (Orientation === 'west' || Orientation === 'north') {
SideLength *= -1;
}
if (Orientation === 'east' || Orientation === 'west') {
context.moveTo(PosX + SideLength, PosY);
for (var i = 1; i < sides + 1; i++) {
context.lineTo(PosX + SideLength * Math.cos(a*i), PosY + SideLength * Math.sin(a*i));
}
}
else if (Orientation === 'south' || Orientation === 'north') {
context.moveTo(PosY, PosX + SideLength);
for (var i = 1; i < sides + 1; i++) {
context.lineTo(PosY + SideLength * Math.sin(a*i), PosX + SideLength * Math.cos(a*i));
}
}
context.stroke();
context.closePath();
}'
要仅旋转特定形状而不旋转整个画布 - 您应该手动旋转它所包含的每个点,然后用旋转的点绘制它。
检查我创建的这个例子,它不使用任何canvas API
函数进行旋转或平移,也绘制任何规则多边形。
var ctx = document.getElementById("cnv").getContext('2d');
var id = 0;
var Point2d = function(x, y) {
this.x = x || 0;
this.y = y || 0;
}
Point2d.prototype.set = function(x, y) {
this.x = x;
this.y = y;
};
Point2d.prototype.translate = function(p) {
this.x += p.x;
this.y += p.y;
return this;
};
//rotation around origin
Point2d.prototype.rotate = function(phi) {
this.set(
this.x*Math.cos(phi) - this.y*Math.sin(phi),
this.x*Math.sin(phi) + this.y*Math.cos(phi)
);
return this;
};
function getRegularPolygonPoints(center, numSides, sideLength) {
var points = [];
var alpha = 2*Math.PI / numSides;
for (var i = 0; i < numSides; i++) {
points.push(new Point2d(
center.x + sideLength*Math.cos(alpha*i),
center.y + sideLength*Math.sin(alpha*i))
)
}
return points;
}
function drawPolygon(points) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.lineTo(points[0].x, points[0].y);// close the shape
ctx.lineWidth = 1;
ctx.fillStyle = "#899";
ctx.fill();
ctx.stroke();
ctx.closePath();
}
function rotatePolygon(polygonPoints, phi, pointAround) {
var pointAroundInv= new Point2d(-pointAround.x, -pointAround.y);
for (var i = 0; i < polygonPoints.length; i++) {
polygonPoints[i].translate(pointAroundInv);// translate to origin
polygonPoints[i].rotate(phi);// rotate
polygonPoints[i].translate(pointAround);// translate back to it's original position
}
}
var center = new Point2d(250, 120);
var regPolPoints = getRegularPolygonPoints(center, 3, 50);
var currentFrame = (new Date).getTime();
var lastFrame = currentFrame;
var dt = 0;
var render = function() {
ctx.clearRect(0, 0, 400, 400);
currentFrame = (new Date).getTime();
dt = currentFrame - lastFrame;
lastFrame = currentFrame;
rotatePolygon(regPolPoints, -dt/600, center);
drawPolygon(regPolPoints);
id = requestAnimationFrame(render);
}
id = requestAnimationFrame(render);
<canvas id="cnv" width="400" height="400"></canvas>
这里的数学非常简单。我们正在从半径半径的圆中提取的等角点之间绘制直线(见下面的参数)。另外,我们应该记住,边长不是多边形的实际边长。我简化了初始代码并添加了图形旋转功能。结果函数和示例如下所示:
/* here, radius means the radius of circle, inside of which polygon is drawn */
function drawTriangle(context, PosX, PosY, radius, rotate) {
context.beginPath();
/* number of vertices for polygon */
var sides = 3;
/* angle between vertices of polygon */
var a = ((Math.PI * 2) / sides);
for (var i = 0; i < sides; i++) {
context.lineTo(PosX + radius * Math.cos(a*i+rotate), PosY + radius * Math.sin(a*i+rotate));
}
context.closePath();
context.stroke();
return true;
}
var canvas = document.getElementById("demo")
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var PosX = 50;
var PosY = 50;
var radius = 40;
drawTriangle(ctx, PosX, PosY, radius, Math.PI / 4);
}
canvas#demo
{
border: thin solid green;
}
<canvas id="demo" width="200" height="200">
This browser or document mode doesn't support canvas
</canvas>
旋转三角形
drawTriangle(PosX, PosY, SideLength, Orientation) {
context.setTransform(1,0,0,1,PosX,PosY); // Set position
context.rotate(Orientation); // set rotation in radians
context.beginPath();
var sides = 3;
var a = ((Math.PI * 2) / sides);
context.moveTo(SideLength,0);
for (var i = 1; i < sides + 1; i++) {
context.lineTo(SideLength * Math.cos(a*i), SideLength * Math.sin(a*i));
}
context.closePath();
context.fill()
context.setTransform(1,0,0,1,0,0);// reset the transform
return true;
}
相关文章:
- 如何在未直接触发的情况下停止事件
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 在不使用jquery的情况下查找页面中的所有锚点并附加函数
- 在不打开聊天屏幕的情况下制作Zopim-ding代理
- 在不阻止默认行为的情况下检测IE10中的缩放
- 如何在不传递此信息的情况下查找被调用的元素
- 如何在不刷新页面的情况下更新显示框
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- JavaScript-在手机上不工作的情况下,在外部单击时隐藏元素
- 在我的情况下,如何进行http请求
- 在不知道深度或父属性的情况下从对象中删除属性
- 在不破坏未定义函数的情况下,对多个视图使用单个js文件
- ROR:如何在不重新加载浏览器的情况下从控制器获取参数
- 在不旋转元素尺寸的情况下旋转图像
- 在给定 2D 方向矢量的情况下,如何计算沿 y 轴的旋转
- 在JQuery不工作的情况下旋转和移动
- 在不施加力的情况下,使用p2旋转约束连接2个相位器精灵
- HTML5文本画布旋转的情况下,文本宽度大于最大宽度允许
- 如何在不旋转图像的情况下以圆形移动图像
- 如何在不旋转整个画布的情况下旋转三角形