试图旋转画布,有什么问题 [英] Trying to rotate canvas, something is going wrong

查看:164
本文介绍了试图旋转画布,有什么问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我想为了文档目的(跟踪电话分机,端口号等),在HTML5中创建我的办公室的一个漂亮的交互式地图,并且由于我们的很多办公室和隔间都是一样的,我想我应该只有一种类型的办公室,然后只是复制它匹配的所有办公室。我唯一的问题是,我不能正确旋转画布。我遵循了所有的教程,但由于某种原因,我的形象不断被切断。我不能找到问题的根源。



任何想法?



到目前为止:



http://jsfiddle.net/ pmcDw / 1 /

 <!DOCTYPE HTML> 

 < head> 
< title>测试交互式Office示意图< / title>
< style>
html,body {
margin:0px;
padding:0px;
}
< / style>
< / head>

< body>
< script>
function addOffice(type,id,occupentName){

var canvas = document.createElement('canvas');
canvas.id = id;
canvas.style.position =absolute;
canvas.style.left =20px;
canvas.style.class =office
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(0,0);
if(type == 1){
canvas.width = 80;
canvas.height = 80;
context.lineTo(2,0);
context.lineTo(2,20);
context.quadraticCurveTo(22,20,22,0);
context.lineTo(60,0);
context.lineTo(60,80);
context.lineTo(0,80);
context.lineTo(0,0);
}
context.lineWidth = 2;
context.strokeStyle ='black';
context.stroke();
context.textBaseline =Alphabetic;
context.textAlign =center;
context.fillText(occupentName,canvas.width / 2,canvas.height / 2);
document.body.appendChild(canvas);
canvas = document.getElementById(1);
context = canvas.getContext('2d');
var tempCanvas = document.createElement(canvas),
tempCtx = tempCanvas.getContext(2d);
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
tempCtx.drawImage(canvas,0,0,canvas.width,canvas.height);
context.clearRect(0,0,canvas.width,canvas.height);
context.save();
context.translate(canvas.width / 2,canvas.height / 2);
context.rotate(180 * Math.PI / 180);
context.drawImage(tempCanvas,0,0,80,80,40,40,80,80);
context.restore();
}
addOffice(1,1,test);
< / script>
< / body>

解决方案>

在翻译和旋转上下文之后,您需要翻译回:

  context.translate 2,canvas.height / 2); 
context.rotate(180 * Math.PI / 180);

/// here,translate back:
context.translate(-canvas.width / 2,-canvas.height / 2);

context.drawImage(tempCanvas,0,0);

(如果目标大小相同,则不需要剪辑和/作为源大小)。



但是如果你只想翻转图像或旋转180,你可以使用 scale 画布而不是使用负值 - 只是记住颠倒坐标(这里是这个技术的演示):

  context.scale(-1,-1); 
context.drawImage(tempCanvas,-tempCanvas.width,-tempCanvas.height);



更多关于转换的更深入的更新



为了更好地解释变换的工作原理,我们将介绍各个阶段。



Origo href =http://en.wiktionary.org/wiki/origo =nofollow noreferrer>见这里的定义)始终是坐标系中的点[0,0]其中轴线交叉)。当你使用转换时,这是在canvas的上下文中被转换的点。



这也是为什么你操作上下文一个不是直接的画布直接作为转换应用于上下文而不是元素(否则元素将应用一个旋转变换它本身,你可以通过CSS做)。



最初,坐标系统看起来像这样(白色混合是画布的不可见区域,中心正方形是画布,蓝色网格是上下文和当前坐标系):



(注意:忽略负Y轴 - 我在绘制图形时忽略了细节 - y轴当然是垂直向下的)。





如果我们现在翻译画布3.5 3.5点,以获得 origo 中心的上下文和坐标系现在将是这样:





如果我们现在想申请点将发生在 origo 点的旋转。这就是为什么我们需要在旋转之前进行翻译,因为当应用旋转时,我们得到这个结果:





如果我们现在只是绘制图像,它将不会居中导致 drawImage 从图像的左上角绘制图像。这意味着它看起来像这样:





这是为什么我们需要翻译回 origo ,以便我们补偿图像角。 p>

但是,由于我们也应用了旋转,origo也会相对于当前系统方向移动。



我们转换回(图像大小的一半,以获得图像的中心点在上一个 origo 点) - 旋转保持不变:





现在我们可以调用 drawImage ,现在你可以看到 origo 似乎在这个操作的正确位置:




So I'm trying to make a nice interactive map of my office in HTML5 for documentation purposes(tracking phone extensions, port numbers, etc), and since a lot of our offices and cubicles are the same, I figure I should have just one of each type of office, then just duplicate it for all of the offices it matches. My only issue is, I can't rotate the canvas properly. I've followed all the tutorials, but for some reason, my image keeps getting cut off. I can't seem to locate the source of the problem.

Any ideas?

Here is my code so far:

http://jsfiddle.net/pmcDw/1/

<!DOCTYPE HTML>

<head>
    <title>Test Interactive Office Schematic</title>
    <style>
        html, body {
            margin: 0px;
            padding: 0px;
        }
    </style>
</head>

<body>
    <script>
        function addOffice(type, id, occupentName) { 

            var canvas = document.createElement('canvas');
            canvas.id = id;
            canvas.style.position = "absolute";
            canvas.style.left = "20px";
            canvas.style.class = "office";
            var context = canvas.getContext('2d');
            context.beginPath();
            context.moveTo(0, 0);
            if (type == 1) {
                canvas.width = 80;
                canvas.height = 80;
                context.lineTo(2, 0);
                context.lineTo(2, 20);
                context.quadraticCurveTo(22, 20, 22, 0);
                context.lineTo(60, 0);
                context.lineTo(60, 80);
                context.lineTo(0, 80);
                context.lineTo(0, 0);
            }
            context.lineWidth = 2;
            context.strokeStyle = 'black';
            context.stroke();
            context.textBaseline = "Alphabetic";
            context.textAlign = "center";
            context.fillText(occupentName, canvas.width / 2, canvas.height / 2);
            document.body.appendChild(canvas);
            canvas = document.getElementById("1");
            context = canvas.getContext('2d');
            var tempCanvas = document.createElement("canvas"),
                tempCtx = tempCanvas.getContext("2d");
            tempCanvas.width = canvas.width;
            tempCanvas.height = canvas.height;
            tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height);
            context.clearRect(0, 0, canvas.width, canvas.height);
            context.save();
            context.translate(canvas.width / 2, canvas.height / 2);
            context.rotate(180 * Math.PI / 180);
            context.drawImage(tempCanvas, 0, 0, 80, 80, 40, 40, 80, 80);
            context.restore();
        }
        addOffice(1, 1, "test");
    </script>
</body>

解决方案

After you have translated and rotated the context you need to translate back:

context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(180 * Math.PI / 180);

/// here, translate back:
context.translate(-canvas.width / 2, -canvas.height / 2);

context.drawImage(tempCanvas, 0, 0);

(you don't need to clip and/or specify width and height if destination size is the same as source size).

But if you simply want to flip the image or rotate it 180 you can instead use scale the canvas instead using a negative value - just remember to reverse the coordinates (here's a demo of this technique):

context.scale(-1, -1);
context.drawImage(tempCanvas, -tempCanvas.width, -tempCanvas.height);

More in-depth on transformation in general (update)

To better explain how transformations works lets go through the various stages.

Origo (see definition here) is always point [0, 0] in a coordinate system (or more accurately the point where the axis crosses). When you use transformations this is the point that gets translated in a context for a canvas.

This is also the reason why you manipulate the context an not the canvas directly as the transformations are applied to context and not the element (otherwise the element would be rotated itself when you applied a rotate transformation to it - which you can do by CSS).

Initially the coordinate system looks like this (white blended is non-visible areas of the canvas, the center square is canvas and the blue grid is the context and the current coordinate system):

(Note: ignore the negative Y axis - I somehow managed to overlook that detail when making the graphics - the y axis is of course positive vertically down).

If we now translate the canvas 3.5 by 3.5 points to get origo at center the context and coordinate system will now look like this:

If we now wanted to apply rotation that will happen at the origo point. This is why we need to translate before rotate as when rotate is applied we get this result:

If we now just draw the image it will not be centered cause drawImage draws an image from the image's upper left corner. Which means it would look like this:

This is why we need to translate back origo so that we compensate for the image corner.

However, since we also have rotation applied the origo will be moved relative to the current systems orientation as well.

We translate back (half the size of the image to get the image's center point at the previous origo point) - the rotation remains the same:

Now we can call the drawImage as now you can see the origo seem to be in the correct position for this operation:

这篇关于试图旋转画布,有什么问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆