gpt4 book ai didi

JavaScript:在 Canvas 中旋转对象

转载 作者:行者123 更新时间:2023-12-03 00:18:08 25 4
gpt4 key购买 nike

过去三周我正在创建一个 Canvas 引擎,上周我试图解决在 Canvas 中旋转对象的一个​​问题。我尝试了很多解决方案,但都没有成功。在大多数情况下,代码会旋转 Canvas 的整个内容,或者什么也不显示(就像现在一样(但如果删除 .save().restore(),则一切将旋转))。我希望这可以避免对代码进行重大更改,因为这是我编写的最大代码(并且我不想进行太多更改)。代码片段如下,感谢您的帮助。 (如果想看完整代码,可以去here)

//Functions.js File
function degToRad(int) {
return int * Math.PI / 180;
}

//Init.js File
var fps = 0;
var objects = new Array();
var ctx_real = {
context: undefined,
width: 0,
height: 0,
init: function () {
this.context = this.DOM.getContext("2d");
this.width = this.DOM.width;
this.height = this.DOM.height;
},
clear: function () {
this.context.clearRect(0, 0, this.width, this.height);
}
};
const proXy_ctx = {
get: function (target, prop) {
return target.hasOwnProperty(prop) ? target[prop] : ctx_real.context; //=> ctx.SomeAtributeThatNotExists = ctx.context
}
};
const ctx = new Proxy(ctx_real, proXy_ctx);

function init() {
ctx.DOM = document.getElementById("ctx");
ctx.init();
setLayout("Game");
setLayout("Test2");
setInterval(frameUpdate, 1);
}

//Script.js File
async function frameUpdate() {
ctx.clear();
clearObjects = false;
for (var tmp0 = 0 in objects) {
var object = objects[tmp0];
var id = object[0];
var type = object[1];
var x = object[2];
var y = object[3];
var color = object[4];
ctx.context.strokeStyle = color;
ctx.context.fillStyle = color;
var arg0 = object[5];
var arg1 = object[6];
var arg3 = object[8];
var arg4 = object[9];
switch (type) {
case "Rct":
var translateX = x + (arg0 / 2);
var translateY = y + (arg1 / 2);
if (typeof arg3 == "number" && arg3 != 0) {
ctx.context.save();
ctx.context.translate(translateX, translateY);
ctx.context.rotate(degToRad(arg3));
}
if (arg4) {
ctx.context.fillRect(x, y, arg0, arg1);
} else {
ctx.context.strokeRect(x, y, arg0, arg1);
}
if (typeof arg3 == "number") {
ctx.context.restore();
}
break;
}
}
if (clearObjects) {
objects = objects.filter(Boolean);
}
fps++;
setTimeout(function () { fps--; }, 1000);
ctx.context.fillStyle = "black";
ctx.context.font = "10px Verdana";
ctx.context.fillText(fps, 10, 10);
}

function setLayout(layoutName) {
switch (layoutName) {
case "Game":
createObject(["SomeId", "Rct", 0, ctx.height - 30, "green", ctx.width, 30, , , true]);
createObject(["SomeId", "Rct", 0, ctx.height - 30, "#402a25", ctx.width, 3, , , true]);
break;
case "Test2":
createObject(["SomeRotatedEl", "Rct", ctx.width / 2, ctx.height / 2, "red", 50, 50, , 90, true]);
break;
}
}

function createObject(object) {
objects.push(object);
}
html,
body,
canvas {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow-x: hidden;
overflow-y: hidden;
}
<!DOCTYPE html>
<html>
<body onLoad="init()">
<canvas id="ctx">You can simple download e.g. Chrome or what?!!!</canvas>
</body>
</html>

最佳答案

如果不“旋转”所有 Canvas ,就无法在 Canvas 上绘制旋转的对象。

不幸的是,这就是 Canvas 的工作原理。这么想一下:

您只能在空间中的单个点{x:0,y:0}进行绘制,并且 Canvas 位于该点的正下方,就像一张物理纸一样。

然后,如果您想在 {x:0,y:10} 处绘制,请将所有 Canvas 向上移动 10px,因此现在您绘制的点变为 {x:0 ,y:10}(如果从 Canvas 的顶部/左侧开始计数),但用于绘图的是 {x:0,y:0}

// red rect at {x:0,y:40}
ctx.fillStyle = "rgba(255,0,0,0.3)";
ctx.translate(0, 40) // means that {x:0,y:10} "is new" {x:0,y:0}
ctx.fillRect(0, 0, 40, 20);

如果你想旋转,你可以旋转 Canvas ,这样你想要绘制的东西就会在旋转时出现:

// reset all transformations
ctx.setTransform(1, 0, 0, 1, 0, 0);
// green rect at {x:0,y:0} rotated 45deg
ctx.fillStyle = "rgba(0,255,0,0.3)";
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(0, 0, 40, 20);

但是它绕着它的左上角/左上角旋转。我猜这就是你的问题?

要正确旋转对象(以中心为旋转轴),您需要放置 Canvas ,使对象的中心变为{x:0,y:0}。然后旋转并绘制对象,使其中心位于 {x:0,y:0},对于大多数对象来说,这意味着您将它们绘制在 {x:-width/2, y:-高度/2}.

例如,如果您想要 {x:50,y:50} 处的蓝色矩形旋转 45 度,{width:40,height:20}

// reset all transformations
ctx.setTransform(1, 0, 0, 1, 0, 0);

// blue rect at {x:50,y:50} rotated 45deg
var rectWidth = 40;
var rectHeight = 20;
ctx.fillStyle = "rgba(0,0,255,0.3)";
ctx.translate(50, 50);
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(-rectWidth/2, -rectHeight/2, rectWidth, rectHeight);

完整示例请参见:https://codepen.io/anon/pen/QYGXzp?editors=0010

关于JavaScript:在 Canvas 中旋转对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54448011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com