Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何实现html5画布的旋转方法_Javascript_Html_Canvas - Fatal编程技术网

Javascript 如何实现html5画布的旋转方法

Javascript 如何实现html5画布的旋转方法,javascript,html,canvas,Javascript,Html,Canvas,我已经使用javascript创建和创建了一些形状(看起来像吃豆人的对象),并且正在使用画布中内置的矩阵变换为它们设置动画。对象可以在四个方向(左、右、上、下)移动,形状基本上会在画布上来回移动,直到按下另一个按钮。当我使用内置的画布转换功能时,这些功能可以正常工作;然而,当我尝试实现自己的转换时,一些奇怪的事情正在发生 在正常情况下(当我使用画布转换时),我首先将画布原点转换为正在旋转的点,围绕此“新”原点执行旋转,然后将原点转换回之前的状态,如以下代码所示: function renderC

我已经使用javascript创建和创建了一些形状(看起来像吃豆人的对象),并且正在使用画布中内置的矩阵变换为它们设置动画。对象可以在四个方向(左、右、上、下)移动,形状基本上会在画布上来回移动,直到按下另一个按钮。当我使用内置的画布转换功能时,这些功能可以正常工作;然而,当我尝试实现自己的转换时,一些奇怪的事情正在发生

在正常情况下(当我使用画布转换时),我首先将画布原点转换为正在旋转的点,围绕此“新”原点执行旋转,然后将原点转换回之前的状态,如以下代码所示:

function renderContent(pm) {
            var t = new Transform();
            context.save();
            context.beginPath();
            context.fillStyle = "Yellow";
            context.strokeStyle = "Yellow";
            context.save();
            var tCopy1 = t;
            context.translate(pm.posX, pm.posY);
            context.rotate(-pm.direction * Math.PI / 180);
            context.translate(-pm.posX, -pm.posY);
            context.arc(pm.posX, pm.posY, pm.size, (pm.startAngle) * Math.PI, (pm.endAngle) * Math.PI);
            context.lineTo(pm.posX, pm.posY);
            context.stroke();
            context.fill();
            var m = t.m;
            t.transform(m);
            context.restore();
            context.restore();
        }
为了实现我自己的转换,我有一个带有以下函数的转换类:

function Transform() {
            this.identity();
        }
        Transform.prototype.identity = function () {
            this.m = [1, 0, 0, 1, 0, 0];
        };
        Transform.prototype.rotate = function (rad) {
            var c = Math.cos(rad);
            var s = Math.sin(rad);
            var m11 = this.m[0] * c + this.m[2] * s;
            var m12 = this.m[1] * c + this.m[3] * s;
            var m21 = this.m[0] * -s + this.m[2] * c;
            var m22 = this.m[1] * -s + this.m[3] * c;
            this.m[0] = m11;
            this.m[1] = m12;
            this.m[2] = m21;
            this.m[3] = m22;
        };
        Transform.prototype.translate = function (x, y) {
            this.m[4] += this.m[0] * x + this.m[2] * y;
            this.m[5] += this.m[1] * x + this.m[3] * y;
        };

        Transform.prototype.scale = function (sx, sy) {
            this.m[0] *= sx;
            this.m[1] *= sx;
            this.m[2] *= sy;
            this.m[3] *= sy;
        };
在renderContext()函数中,我对translate()和rotate()使用了基本相同的函数调用(这使pacman对象在碰到画布边界时能够掉头),但由于某种原因,在我的实现中,对象不会掉头(180度)

对于我的转换,我基本上实例化了一个转换对象,调用对象上的转换操作,制作转换矩阵的副本,然后使用转换的结果矩阵设置画布: 例如:


这可能需要看很多代码,但是实现旋转矩阵变换的正确方法是什么(因为canvas.rotate()正在工作)?

下面是pacman围绕方向角顺时针旋转

更新

现在以紫色显示变换错误。旋转看起来正确,但平移已关闭

更新2

我想我以前的考试不好。变换看起来很好,并且只有一些到_弧度的微小调整。新的测试显示了上下文翻译/旋转,然后是
Transform

var can=document.getElementById('can');
var context=can.getContext('2d');
var to_rad=Math.PI/180;//到弧度
函数main(){
context.fillStyle=“black”;
context.fillRect(0,0,can.width,can.height);
var pm={
方向:0,
posX:50,
波西:100,
尺码:20,
startAngle:45,
端角:315
};
var i=0;
函数循环测试(){
pm.direction=i*90;
pm.posX=50*(i+1);
渲染内容(pm);
setTimeout(函数(){
渲染内容2(下午);
}, 1000);
i++;
if(i<4){
setTimeout(loopTest,2000);
}
}
loopTest();
}
功能呈现内容(pm){
context.save();
context.beginPath();
context.fillStyle=“黄色”;
context.strokeStyle=“黄色”;
翻译(pm.posX,pm.posY);
旋转(pm.direction*至_rad);
context.translate(-pm.posX,-pm.posY);
弧(pm.posX,pm.posY,pm.size,pm.startAngle*到_rad,pm.endAngle*到_rad);
lineTo(pm.posX,pm.posY);
stroke();
context.fill();
context.fillStyle=“红色”;
context.font=“16px Arial”;
context.textAlign=“中心”;
填充文本(pm.direction、pm.posX、pm.posY+pm.size);
restore();
}
功能呈现内容2(pm){
var t=新变换();
context.save();
context.beginPath();
context.fillStyle=“#990099”;
context.strokeStyle=“#990099”;
t、 翻译(pm.posX,pm.posY);
t、 旋转(pm方向*至_rad);
t、 翻译(-pm.posX,-pm.posY);
context.transform.apply(context,t.m);
弧(pm.posX,pm.posY,pm.size,pm.startAngle*到_rad,pm.endAngle*到_rad);
lineTo(pm.posX,pm.posY);
stroke();
context.fill();
context.fillStyle=“白色”;
context.font=“16px Arial”;
context.textAlign=“中心”;
填充文本(pm.direction、pm.posX、pm.posY+pm.size);
restore();
}
函数变换(){
这个。身份();
}
Transform.prototype.identity=函数(){
this.m=[1,0,0,1,0,0];
};
Transform.prototype.rotate=函数(rad){
var c=数学cos(rad);
var s=数学sin(rad);
var m11=this.m[0]*c+this.m[2]*s;
var m12=this.m[1]*c+this.m[3]*s;
var m21=这个.m[0]*-s+这个.m[2]*c;
var m22=此.m[1]*-s+此.m[3]*c;
这个.m[0]=m11;
这个.m[1]=m12;
这个.m[2]=m21;
这个.m[3]=m22;
};
Transform.prototype.translate=函数(x,y){
this.m[4]+=this.m[0]*x+this.m[2]*y;
this.m[5]+=this.m[1]*x+this.m[3]*y;
};
Transform.prototype.scale=函数(sx,sy){
这个.m[0]*=sx;
this.m[1]*=sx;
这个.m[2]*=sy;
这个.m[3]*=sy;
};
main()
画布{
边框:3倍纯红;
}

提问者的本机画布(context.rotate)版本正在运行。我相信他们会问为什么他们自己的转换矩阵版本不起作用。我可能错了,因为我现在莫名其妙地困了-zAhh是的,你的回答是正确的@markE。我将看一看他的变换。@markE我使用
context.transform.apply(context,t.m)
将数组作为参数应用,它似乎工作得很好。
var t = new Transform();
var tCopy1 = t;
tCopy1.translate(pm.posX, pm.posY);
t.rotate(-pm.direction * Math.PI / 180);
t.translate(-pm.posX, -pm.posY);
...
var m = t.m;
t.transform(m);