When programming in HTML canvas, the js dimensions of the canvas don't always match the css dimensions.
Why is this happening and how can I fix this?
I've found the problem. I was setting the dimensions of the using CSS, when you actually have to set the width and height attributes. This was causing it to be stretched/skewed.
var canvas = $('<canvas/>').attr({width: cw, height: ch}).appendTo('body');
http://jsfiddle.net/h2yJn/66/
You can try to set the width and height of the canvas to be equal to the dimensions of the window object:
function createCanvas() {
var ctx = //the canvas context;
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
//your code
}
In addition, it is a good idea to set the body and html tags to the full width of the window:
body, html{
height: 100%;
width: 100%;
}
You can also do this by using pure javascript and set the dimensions of the canvas in javascript depending on your CSS values:
//Get Canvas
var canvas = document.getElementById("canv");
// Get computed style of the canvas element.
var cstyle = window.getComputedStyle(canvas);
// Returns the width as str in px: e.g. 600px.
// Parse resolves that issue.
canv.width = parseInt(cstyle.width);
canv.height = parseInt(cstyle.height);
Demo:
https://jsfiddle.net/ofaghxfq/2/
Related
I am currently having an issue when setting width and height of a svg object in fabricjs. I tried setting it like this
svg.width = 100;
svg.height = 100;
But I am not getting the result I expected. It just crops the svg instead of scaling it. So, how can I set its width and height properly?
Any help will be appreciated. Thanks!
Use scaleToWidth() and scaleToHeight() method to properly set SVG object*'s* width and height respectively.
:-: working example :-:
var canvas = new fabric.Canvas('fabric-canvas');
fabric.loadSVGFromURL('http://cdn.shopify.com/s/files/1/0496/1029/files/Freesample.svg?5153', function(objects, options) {
var svg = fabric.util.groupSVGElements(objects, options);
svg.left = 50;
svg.top = 50;
svg.scaleToWidth(100);
svg.scaleToHeight(100);
canvas.add(svg);
canvas.renderAll();
});
canvas{border:1px solid #ccc}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.13/fabric.min.js"></script>
<canvas id="fabric-canvas" width="200" height="200"></canvas>
Is there a native solution that provides a handle in the corner of my HTML5 canvas similar to that in a default <textarea> element.
<textarea>resizeable</textarea>
I assume this will clear the canvas and will require a redraw as this is the case when resizing the canvas programmatically with canvas.width and canvas.height.
I looked around and found nothing, but wanted to check before rolling my own. If anyone is sure that there is no "easy" way, then that is a perfectly acceptable answer. Thanks!
The best I could come up with was use jQueryUI Resizable like so
jsFiddle : https://jsfiddle.net/n24dbaw9/
Html
<div class="resizable">
<canvas id="myCanvas"></canvas>
</div>
CSS
.resizable{
width: 400px;
height: 400px;
}
#myCanvas{
width: 100%;
height: 100%;
}
Javascript
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#777";
$(function() {
$(".resizable").resizable();
});
setInterval(function(){ ctx.fillRect(0, 0, 400, 400); }, 3);
Basically I have styled the canvas to fit inside of the "resizble" div, which is set to 400 by 400 at default. The canvas has a style which is 100% width and height so when the user resizes the "resizble" div the canvas will then just stretch out.
You will want to put the canvas into a JavaScript draw() function:
function draw() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
and your body element in css should have height and width set to 100%
I am looking for an easy solution to resize a canvas element (a chart) automatically once the parent div size changes (= browser size changes). At the moment my Canvas element only fits perfectly into the parent div when the page is loaded.
This is what I've done so far and what I've tried:
<div class="panel-body">
<canvas id="userlogins"></canvas>
<script type="text/javascript">
jQuery(document).ready(function($)
{
var ctx = $("#userlogins").get(0).getContext("2d");
var myLineChart = new Chart(ctx).Line(data, options);
});
function fitToContainer(canvas){
// Make it visually fill the positioned parent
canvas.style.width ='100%';
// ...then set the internal size to match
canvas.width = canvas.offsetWidth;
}
var canvas = document.querySelector('canvas');
fitToContainer(canvas);
jQuery( window ).resize(function() {
fitToContainer(canvas);
redraw();
});
</script>
</div>
When I resize my browser the canvas chart disappears. The parent div fit on page load works well.
Edit: The approaches in the given "duplicates" doesn't work for me! Here is what I have tried given from the "duplicate question":
jQuery( window ).resize(function() {
clearTimeout(timerID);
timerID = setTimeout(function() {
var cnvs = $("#userlogins")[0]; // cache canvas element
var rect = cnvs.getBoundingClientRect(); // actual size of canvas el. itself
cnvs.width = rect.width;
cnvs.height = rect.height;
redraw();
});
});
It looks like you're using ChartJS. If yes, it has a property you can set to make the chart responsive to resizing.
Chart.defaults.global.responsive = true;
Changing the canvas element width or height clears the canvas. In fact, it's often used as a way of clearing it on purpose. So this line:
canvas.width = canvas.offsetWidth;
clears your canvas. After that, you can either:
redraw the chart
or remove that line and rely on the CSS transformations, which can ruin the proportions of your canvas
No matter what I try, I can't figure out why does drawImage vertically stretch a picture. Here is the code:
<canvas id="canvas" style="padding:0;border:0;margin:0 auto;
width:320px;height:456px;z-index:0;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var d = new Image
d.src = './images/portadilla.jpg';
d.onload = function a(){context.drawImage(d, 0, 0);}
</script>
My image is 456px high and 320px wide, same as the canvas. I've tried using different images and formats, but the problem remains. How would you solve this?
Because you're not setting the size of the canvas correctly. Don't use CSS/style to set the size but use its attributes:
<canvas id="canvas" width=320 height=456 style="..."></canvas>
Your image is stretched because the default size of the bitmap for a canvas element is 300x150 pixels so if you don't set the size properly the canvas bitmap will be stretched to fit the element size set with CSS.
You can also set the size using JavaScript:
var canvas = document.getElementById('canvas');
canvas.width = 320;
canvas.height = 456;
How can I dynamically set the image size ratio depending on the returned image in raphael?
Here is some code to give you an idea:
var viewer = Raphael(0,0,scrWidth, scrHeight);
viewer.image(dynamicUrl, 140, 140,300, scaledHeight);
Thank you
You can load the image outside the DOM and get its dimensions... You can put this inside a function:
var myImg = new Image();
myImg.src = dynamicUrl;
myImg.onload = function() {
var width = myImg.width;
var height = myImg.height;
var scale = 0.5; // for example
var viewer = Raphael(0,0,width, height); // or whatever other size
viewer.image(dynamicUrl, 0, 0, width*scale, height*scale); // scale image
// after the image is in the viewer you can use .scale()
}
jsFiddle
Now you can divide or multiply both width and height to scale. Make sure you pay attention to the timing.
Also, once the image is in Raphael, you can use .scale()