繁体   English   中英

在自身中心旋转一个三角形

[英]Rotate a triangle in the cente of itself

我想在其中心旋转一个三角形。 我有这个脚本:

 var ctx = canvas.getContext('2d'); var angle = 30; setInterval(rotate, 50); function rotate() { ctx.fillStyle = "white"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.translate(150, 150); // x, y ctx.rotate(angle * Math.PI / 180) ctx.fillStyle = "yellow"; var path=new Path2D(); path.moveTo(-50+50,-25); path.lineTo(-50,-50-25); path.lineTo(-50-50,-25); ctx.fill(path); ctx.restore(); angle++; }
 <canvas id="canvas" width="1800" height="700"></canvas>

它旋转它,但不在中心。 我希望它看起来像这样:

 var ctx = canvas.getContext('2d'); setInterval(rotate, 50); var angle = 30; function rotate() { ctx.fillStyle = "white"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.translate(50, 50); ctx.rotate(angle * Math.PI / 180) ctx.fillStyle = "green"; ctx.fillRect(-25, -25, 50, 50); ctx.restore(); angle++; }
 <canvas id="canvas" width="1800" height="700"></canvas>
我想,我只需要得到三角形的宽度和高度并将其除以 2,但我不知道该怎么做。 谢谢每一个答案!

你想要的是你的形状的质心

 var ctx = canvas.getContext('2d'); var angle = 30; var points = [ {x:0, y:-25}, {x:-50, y:-75}, {x:-100, y:-25} ]; // first sum it all var sums = points.reduce( (sum, point) => { sum.x += point.x; sum.y += point.y; return sum; }, {x:0, y:0}); // we want the mean var centroid = { x: sums.x / points.length, y: sums.y / points.length }; rotate(); function rotate() { ctx.setTransform(1,0,0,1,0,0); ctx.fillStyle = "white"; ctx.fillRect(0, 0, canvas.width, canvas.height); // general position in canvas ctx.translate(100, 100); // move to centroid of our triangle ctx.translate(centroid.x, centroid.y); // x, y // rotate ctx.rotate(angle * Math.PI / 180) // go back to our initial position ctx.translate(-centroid.x, -centroid.y); // x, y ctx.fillStyle = "yellow"; var path=new Path2D(); path.moveTo(points[0].x, points[0].y); path.lineTo(points[1].x, points[1].y); path.lineTo(points[2].x, points[2].y); ctx.fill(path); // demo only ctx.beginPath(); ctx.arc(centroid.x, centroid.y, 50, 0, Math.PI*2) ctx.stroke(); angle++; requestAnimationFrame( rotate ); }
 <canvas id="canvas" width="1800" height="700"></canvas>

创建路径一次

您正在使用可重复使用的 Path2D object。

如果您创建已经以其原点(或任何路径)为中心的三角形,那么旋转它是微不足道的。

如果要渲染很多内容,重用路径 object 也会快很多。

function 从一组点创建路径。 它自动将路径居中到它自己的原点(由它的点的平均值定义)

const point = (x, y) => ({x, y});
function createPath(...points) {
    var cx = 0; cy = 0;
    for (const p of points) {
        cx += p.x;
        cy += p.y;
    }
    cx /= points.length;
    cy /= points.length;

    const path = new Path2d;
    for (const p of points) { path.lineTo(p.x - cx, p.y - cy); }
    path.closePath();
    return path;
}

创建三角形

const triangle = createPath(point(0,-25), point(-50,-75), point(-100,-25));

然后你可以渲染它围绕它自己的原点旋转

function drawPath(path, x, y, angle) {
     ctx.setTransform(1, 0, 0, 1, x, y);
     ctx.rotate(angle);
     ctx.stroke(path);
}

例子

展示如何创建以它们的手段为中心的各种形状。 每个形状都是一次创建的路径,然后根据需要进行渲染。

 const point = (x, y) => ({x, y}); const triangle = createPath(point(0,-25), point(-50,-75), point(-100,-25)); const rectangle = createPath(point(0,-25), point(-50,-25), point(-50,-125), point(0,-125)); const thing = createPath(point(0,-12), point(-25,-12), point(-25,-62), point(0,-62), point(22,-35)); function drawPath(path, x, y, angle) { ctx.setTransform(1, 0, 0, 1, x, y); ctx.rotate(angle); ctx.stroke(path); } function drawPath_V2(path, x, y, scale, angle, strokeStyle, fillStyle) { ctx.setTransform(scale, 0, 0, scale, x, y); ctx.rotate(angle); fillStyle && (ctx.fillStyle = fillStyle, ctx.fill(path)); strokeStyle && (ctx.strokeStyle = strokeStyle, ctx.stroke(path)); } function renderLoop(time) { ctx.clearRect(0, 0, can.width, can.height); const scale = Math.sin(time / 500) * 0.2 + 1.0; const scale2 = Math.cos(time / 1000) * 0.4 + 1.0; drawPath(triangle, 75, 74, time / 1000 * Math.PI); //360 every 2 second // scale path drawPath_V2(rectangle, 125, 125, scale, time / 2000 * Math.PI, "black"); //360 every 4 second // fill scale path drawPath_V2(thing, 125, 100, scale2, time / 3000 * Math.PI, "", "black"); ctx.setTransform(1, 0, 0, 1, 0, 0); requestAnimationFrame(renderLoop); } requestAnimationFrame(renderLoop); const can = Object.assign(document.createElement("canvas"), {width: 200, height: 200}); document.body.appendChild(can); const ctx = can.getContext("2d"); function createPath(...points) { var cx = 0; cy = 0; for (const p of points) { cx += px; cy += py; } cx /= points.length; cy /= points.length; const path = new Path2D; for (const p of points) { path.lineTo(px - cx, py - cy); } path.closePath(); return path; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM