javascript - HTML 5 Canvas - 围绕自己的原点旋转多个对象

标签 javascript canvas graphics 2d

我正在尝试创建一个 JavaScript 对象,该对象具有一个允许矩形在 rAF 回调期间围绕其自身原点旋转的方法。

我做过的事情:

  • 计算 Canvas 空间内对象的原点。
  • 使用 ctx.save()ctx.restore() - 这就是我出现问题的地方。

当我使用 save()restore() 方法在不同对象的方法调用中推送和弹出已保存的状态时,它不会改变任何内容,或停止整个动画。

我的示例中的旋转似乎全局应用于 Canvas (这就是 MDN 上指定功能的方式)。我正在尝试围绕多个实例围绕原点进行翻译。我花了几个小时在这上面。

JavaScript 中的继承机制是否发生了某些情况,导致代码示例中的矩形对象的不同实例没有重置我的转换?

// author: Nicholas Fazzolari

var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var xCenterCanvas = innerWidth/2;
var yCenterCanvas = innerHeight/2;

// custom rectangle object
function RectangleCustom(x, y, w, h, color) {
    this.w = w;
    this.h = h;
    this.x = x;
    this.y = y;
    this.color = color;
    this.radians = (Math.PI/180) * 2; // change the last value to change speed
 
    // draws a rectangle at given coordinates
    this.draw = function() {
        ctx.save();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.w, this.h);
        ctx.restore();
    }
    
    // rotates the rectangle around it's center relative to a given xy position
    this.rotateRect = function() {
        ctx.save();
        ctx.translate(this.x + this.w * 0.5, this.y + this.h * 0.5);
        ctx.rotate(this.radians);
        ctx.translate(-this.x -this.w * 0.5, -this.y - this.h * 0.5);
        //ctx.restore()
    }
}

// singleton rectangles
var bkgRectangle = new RectangleCustom(0, 0, innerWidth, innerHeight, "#212121");
var redRectangle = new RectangleCustom(xCenterCanvas - 64, yCenterCanvas - 64, 128, 128, "#F44336");

// main animation loop
function mainAnimationLoop() {
    // runs animation and clears the canvas each call
    requestAnimationFrame(mainAnimationLoop);
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    
    bkgRectangle.draw();
    redRectangle.draw();
    redRectangle.rotateRect();
}

mainAnimationLoop();

我尝试使用 save()restore() 在不同位置绕其自身原点旋转多个矩形,而不使用动画 - 这有效。

此外,我尝试将旋转方法移到绘制方法内,结果是相同的。我的理由是旋转将作为 draw() 中的函数调用应用 - 这个理由显然是错误的。

任何对解决方案的见解都会非常有帮助。我在 codepen 上添加了钢笔的链接看看这个概念的运作。

最佳答案

您可以在 0,0 处绘制矩形并将其转换为 (this.x, this.y)<,而不是在 (this.x, this.y) 处绘制矩形。/;

// author: Nicholas Fazzolari

var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var xCenterCanvas = innerWidth/2;
var yCenterCanvas = innerHeight/2;

// custom rectangle object
function RectangleCustom(x, y, w, h, color) {
    this.w = w;
    this.h = h;
    this.x = x;
    this.y = y;
    this.color = color;
    this.radians = (Math.PI/180) * 2; // change the last value to change speed
    this.rotation = 0;
 
    // draws a rectangle at given coordinates
    this.draw = function() {
        this.rotation += this.radians;
        ctx.save();
        ctx.fillStyle = this.color;
        ctx.translate(this.x, this.y);
        ctx.rotate(this.rotation);
        ctx.fillRect(0,0, this.w, this.h);
        ctx.restore();
    }
    
    
    this.update = function() {
         // animation updates
     }
}

// singleton rectangles
var bkgRectangle = new RectangleCustom(0, 0, innerWidth, innerHeight, "#212121");
var redRectangle = new RectangleCustom(xCenterCanvas - 64, yCenterCanvas - 64, 128, 128, "#F44336");

// main animation loop
function mainAnimationLoop() {
    // runs animation and clears the canvas each call
    requestAnimationFrame(mainAnimationLoop);
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    
    bkgRectangle.draw();
    redRectangle.draw();
    
}

mainAnimationLoop();
<canvas></canvas>

关于javascript - HTML 5 Canvas - 围绕自己的原点旋转多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55018507/

相关文章:

javascript - JavaScript 宿主对象是如何实现的?

javascript - 为什么我的处理网页游戏只能在 Chrome 中运行?

c# - 在 MonoGame 中绘制绘图的子图像

c++ - 使用 Eigen 的网格:MatrixX3f 或 std::vector<Vector3f>?

javascript - 获取CKEditor中选择的坐标

javascript - 内容页面中的 jquery 不起作用(asp.net)

javascript - 如何使用 canvas.toDataURL() 将 Canvas 保存为图像?

javascript - 设置 Canvas 文本的字体粗细

Java 图形在连续的函数调用中不显示,为什么?

javascript - CSS Sprite 和背景定位