I have a canvas:
<canvas id="canvas" width="400" height="400"/>
that I want to be able to scale dynamically using javascript, so I want to use scale(). But this is not working:
document.getElementById("canvas").getContext('2d').scale(2, 2);
The canvas remains at 400x400, even though I want it to be 800x800.
Live demo at https://jsfiddle.net/c8sjpr37/3/ using vue. Why doesn't it work?
The scale command is an internal canvas command. It changes the scale at which things are drawn. For example:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.strokeRect(5, 5, 25, 15);
ctx.scale(2, 2);
ctx.strokeRect(5, 5, 25, 15);
<div id="app">
<canvas id="canvas" width="400" height="400"/>
</div>
This snippet displays a rectangle, and then another rectangle twice the size of the first one and twice the distance from the translation point, because all of the pixel values were doubled with the .scale() command. I don't think this is what you wanted.
There is a way to edit the height and width styling, though. Canvases are picky, so if you change one, the other will change to match the initial ratio, but you can do this with something like:
document.getElementById("canvas").style.height = "800px";
Related
I'm trying to zoom in or out my canvas drawing, but if I only scale the context nothing happens.Do I need to re-draw it after the scale? Is there any method to scale directly the context without drawing it every time I try to zoom in or out?
PS: I want to zoom in and out with an HTML5 <input type="range"> controlled by a script, and that's already working.
Like Mike said, the best solution is to redraw it.
Zooming in with css is a solution, but there's a big loss in quality.
I'm copying my answer from another question I already answered today..
Canvas is like an image. It has it's own physical dimensions but can still be scaled with CSS. Use the width and height attributes to set the physical dimensions and then use CSS to scale it with a % to make it responsive zoom it.
Example...
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.rect(20, 20, 150, 100);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="width:100%;"></canvas>
Here is an overly simplified example: https://jsfiddle.net/43ejq0op/
I'm trying to place text on sqlare rotated 45 degrees. The problem is my text is under the rectangle shape. Can I change position of text?
my code is like
var c = document.getElementById("myCanvas");
var square= c.getContext("2d");
var text= c.getContext("2d");
text.fillStyle = "red";
text.fillText("1", 40, 50);
text.fillStyle = "#000000";
square.rotate(Math.PI / 4);
square.fillRect(50, 0, 50, 50);
jsfiddle
You're drawing the text first, then the rectangle, and then wondering why the text is behind the rectangle?
Firstly, you only need to getContext once, not twice.
Second, draw things in the right order: background first, then foreground.
It appears you may have a misconception about how the canvas context works.
You see, you only need one instance of the context, which you can then use to create all your shapes, paths and even write text on the canvas.
Also, you are drawing the text before the rectangle, which would cover it up.
With that in mind, I've created a new JSFiddle where you can check out a correct approach to do this.
HTML
<canvas id="myCanvas" width="300" height="150">
Your browser does not support the HTML5 canvas tag.
</canvas>
JavaScript
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d"); //we get the canvas context
ctx.save(); //save context properties
ctx.rotate(Math.PI / 4);
ctx.fillRect(50, 0, 50, 50);
ctx.restore(); //restore saved properties
ctx.fillStyle = "red";
ctx.fillText("1", 40, 50);
As you can see, we only take one instance of the context, and we draw from there.
The context save() and restore() functions help prevent the rotation from affecting the text. You could also rotate the same amount in the opposite direction.
Hope it helps!
I am working on HTML5 canvas with image manipulation. In my canvas I have number of images. When I want to clip the images individually. But when I clip one image by creating a shape and use clip() function, it is working fine. But the problem arise when I try to clip another image using the same method. As the canvas stored the previous shape it will concatenate with the new one and clip the second image accordingly. I want destroy the previous shape. Please note that I can't use the clearRect() to clear the canvas as my previous clipped image is there.
Please ref the link :
Demo Problem
In the link drag the image into canvas predefined layer and drag the image around. You can clearly see that the image got clipped properly if it try to go out of the border.
Now drag another image into the canvas in a different box. Now you can see the clipping is not functioning properly.
Here what I have done in the script :
JS Script
Here the JSFiddle Link
JSFiddle Link
Can you help me to fix this issue?
It will be helpful if you find another way to clear the previous shape.
Thanks in advance.
I have fix the issue by own. The canvas doesn't provide the multiple image clip option. So if you want to clip multiple image in your canvas you have to use your own clip function. Just clear the area by clearRect() of the canvas outside your selection. Iterate this process for each image and you are done !
Solution Link :
Solution Demo
JS Script Link :
JS Script
Thanks.
The best solution I could find is to use a hidden canvas, and draw to that, then use the putImageData method onto your main canvas.
var c = document.getElementById("myCanvas");
var ctemp = document.getElementById("myCanvasTemp");
var ctx = c.getContext("2d");
var ctxTemp = ctemp.getContext("2d");
ctxTemp.fillStyle = "red";
ctxTemp.fillRect(10, 10, 50, 50);
ctxTemp.fillStyle = "blue";
ctxTemp.fillRect(20, 20, 50, 50);
function copy() {
var imgData = ctxTemp.getImageData(10, 20, 50, 10);
ctx.putImageData(imgData, 10, 10);
}
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<canvas id="myCanvasTemp" width="300" height="150" style="display:none;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br /><br />
<br />
<button onclick="copy()">Copy</button>
I've got a canvas on which I can add multiple layers (text and images), I use this to make templates. What I am trying to achieve at the end is that when I add a layer there will be a block of HTML/CSS created that contains the properties of the layer, these properties are:
X
Y
Width
Height
Font
Font-size
Font-Color
Angle
Content
In the end I want to achieve that when I add a layer a block of code will be created and when I change any of the layers properties by for example moving it then the code should be changed aswell and when I change the code then the layer should change accordingly on the canvas.
I have searched alot for something like this but I wasn't able to find anything. If someone knows how I can do this (if it's even possible) it would be great!
A working example of my canvas can be found here:
http://codepen.io/anon/pen/HvLDs (If it doesnt do anything when you've added a layer try refreshing)
Pastebins of the codes:
http://pastebin.com/uRqiKzGd
http://pastebin.com/CXF6DtyC
You are using the wrong technology. HTML5 Canvas doesn't record the elements you add in the DOM, it's more of a 'Fire and Forget' technology. Once you've rendered it, you've lost it essentially.
If you look at SVG on the otherhand, each SVG item has a DOM representation that you can clearly see, manipulate and style using CSS. Layering SVG would be a much more appropriate approach to this problem than trying to use Canvas.
To illustrate, here's some example code to render a Canvas circle:
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
</script>
The resultant DOM however just looks like:
<canvas id="myCanvas" width="578" height="200"></canvas>
If you compare this to SVG, you've got the actual circle within the DOM:
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
I have a very simple code that should draw a circle, but its not looking like one, and not at the right position The coordinates are all somewhat shifted. The canvas is set to style="width: 600px; height: 600px;". I tried it on chrome and safari - looks the same so it's not a browser bug.
So my questions are (there is probably one answer for both):
If I am putting the center at (100, 100), why is the circle not at an equal distance from the left border, that it is from the top border?
Why is the (300, 300) point out of the canvas, and not in the center?
The code:
var context = document.getElementById('c').getContext("2d");
context.fillStyle = 'black';
context.fill();
context.beginPath();
context.arc(100, 100, 30, 0, 2 * Math.PI, true);
context.stroke();
How it looks:
Edit
According to the comment I found out that writing <canvas id="myCanvas" style="width: 578px; height: 200px;"></canvas> is causing this problem, and writing <canvas id="myCanvas" width="578" height="200"></canvas> solves it. Anyone knows why?
This is documented in the HTML5 Canvas spec.
The HTML attributes width="x" height="y" describe the drawing area of the canvas and default to 300 × 150 px. As a side-effect, they describe the default visible size of the canvas.
The CSS properties width: x; height: y; set on the canvas can stretch/compact that drawing area, but they don't change its size.
In your case, the browser stretches the default drawing area (300 × 150 px) to meet the given CSS of 600 × 600 px.
This example shows how to draw a circle on canvas: http://www.html5canvastutorials.com/tutorials/html5-canvas-circles/
Also, you need to set the width and height attributes on the canvas element rather as a style attribute like so:
<canvas id="c" width="600" height="600" style="background-color:yellow;"></canvas>