如何在不旋转整个画布的情况下旋转三角形?

时间:2016-07-07 05:47:27

标签: javascript html5 rotation html5-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;
}

该函数只能知道三角形的中心坐标和指向它的方向,而不是其他任何东西。

它目前成功地绘制了三角形但是&#34;点&#34;东

如何使用Orientation参数(度)旋转三角形而不像其他答案那样旋转整个画布?

5 个答案:

答案 0 :(得分:5)

这是一个绘制任何正多边形和指定角度的函数:

&#13;
&#13;
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);    }
&#13;
<canvas id="canvas" width=512 height=512></canvas>
&#13;
<canvas id="canvas" width=512 height=512></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:4)

请查看此fiddle。您可以将方向作为可选参数发送。它接受东部&#39;西部&#39;北部&#39;南部&#39;南部&#39;。请验证。

` function 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();

}`

答案 2 :(得分:2)

这里的数学很简单。我们在半径为 radius 的圆形等角点之间绘制线条(参见下面的参数)。另外,我们应该记住 SideLength 不是多边形的实际边长。我简化了初始代码并添加了图形旋转功能。结果函数和示例如下所示:

&#13;
&#13;
        /* 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);
        }
&#13;
canvas#demo
{
  border: thin solid green;
}
&#13;
<canvas id="demo" width="200" height="200">
    This browser or document mode doesn't support canvas
</canvas>
&#13;
&#13;
&#13;

答案 3 :(得分:2)

要仅旋转特定形状而不是整个画布 - 您应该手动旋转它所包含的每个点,然后使用旋转点绘制它。

检查我创建的这个示例,它不使用任何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>

答案 4 :(得分:1)

旋转三角形

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;
}