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:
<!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>
The image won't show because you're drawing it outside of the canvas. Try this:
After you have translated and rotated the context you need to translate back:
(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):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 theorigo
seem to be in the correct position for this operation: