I'm using Easel JS to develop Canvas based Solitaire game.
TODO: Set height for canvas and draw all elements inside of that.
Issue: EaselJS change the canvas height automatically.
References:
How I set the height:
var gameBoard = document.getElementById("board");
gameBoard.style.height = window.innerHeight+"px";
gameBoard.height = gameBoard.offsetHeight;
gameBoard.style.height = "auto";
Without knowing what your goals are, it's hard to tell what the problem is exactly... but setting the CSS "canvas.style.height" property to "auto" seems to be the problem. The width and height properties (not CSS) are still what you set them to originally (1300 x 501).
Remove this line and you will be left with a canvas that is the size of the window when the page is loaded.
gameBoard.style.height = "auto";
If you want your canvas to have as many pixels as there are in the window, you will need to listen for the "resize" event and apply the values back to your canvas.
window.addEventListener("resize", function(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
Related
I'm developing a drawing app, and I've encountered a problem which I have been trying to solve but I haven't found a reliable solution yet:
Sketches have an original resolution of 1280 x 720, and I would like to resize the canvas when the page is opened to the maximum size possible (given the screen dimensions minus a toolbar I have put on the upper side of the page) keeping the 1280 x 720 aspect ratio.
The canvas needs to be centered in the screen and black stripes will cover the rest: when the the browser window dimensions relation is less than the sketch original w/h relation there will be horizontal black stripes (fig 1), and when it is bigger, vertical black stripes (fig 2).
I've tried using javascript applying to the canvas the offsetWidth and offsetHeight of a div containing an auxiliar invisible image which I generate programatically with the original sketch dimensions, but doesn't seem to be a robust way to do this. Most of the time the offset properties aren't ready when the page is loaded and I have to wait for them using a timer (or mutation observers).
Some images of what I'm trying to do:
I've spend much time on this little thing and is driving me crazy, because every solution I found is way too hacky or unreliable. Any help will be very appreciated.
I'm using Angular + Ionic 4.
If I'm understanding you correctly, you want to dynamically change the size of your canvas based on how big the window is. The one stipulation is that it must maintain the 1280 x 720 (1:0.5625) ratio.
I'm going to attempt to provide a solution that will also listen for resizing of the window after it's been loaded. Keep in mind that this means you'll need to redraw everything on the canvas from there.
HTML
<body>
<canvas id="canvas"></canvas>
</body>
CSS
body {
background-color: black;
}
JavaScript:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
startListening();
function startListening() {
// resize the canvas every time the window is adjusted
window.addEventListener('resize', resizeCanvas, false);
// manually call the resizeCanvas() function as the window loads with it's starting dimensions (before a resize has happened)
resizeCanvas();
}
function resizeCanvas() {
// if the canvas height isn't maxed out, match it to the width of the page at the correct aspect ration (1:0.5625)
if(canvas.height < window.innerHeight){
canvas.width = window.innerWidth;
canvas.height = canvas.width * 0.5625;
}
// if the canvas height is maxed out, stop widening the canvas and lock the canvas height at 0.5625 of that locked height
if(canvas.height >= window.innerHeight){
canvas.height = canvas.width * 0.5625;
}
// lastly, if we are shrinking the width back down, readjust both the width and height to match
if(canvas.width > window.innerWidth){
canvas.width = window.innerWidth;
canvas.height = canvas.width * 0.5625;
}
// redraw the canvas with our newly calculated dimensions
redraw();
}
function redraw() {
ctx.fillStyle = "#FF0000";
// Draw the canvas in the center of the screen at the height and width calculated above in the resizeCanvas() function
ctx.fillRect((window.innerWidth - canvas.width) / 2, (window.innerHeight - canvas.height) / 2, canvas.width, canvas.height);
}
i use phantomjs to make a pdf out of the content on my site. And it looks great with canvas as the exception.
in my print.css / media css i have the canvas to 100%
canvas {
height : 100%!important;
width : 100%!important;
}
the canvas / content of canvas (which is a chart generated by chart.js) looks stretched / out of focus.
From reading various post i noticed that setting sizing through css is a no go, and i instead have to have it in-tag or set it through javascript directly on the canvas element.
however, thats not really an option since its already scaled/sized perfectly on the site. If i dont have the 100% height width, the canvas dont get jagged, but its WAY too big for my pdf format.
Whats the right way to go about fixing this, getting a crisp canvas for my screen capture which is sized for A4 / Standard pdf format?
Thanks in advance.
When dealing with a canvas the css 'height' and 'width' element determine the size of the literal DOM element <canvas> NOT the size of the display within. In order to set this try something like this:
// grab canvas attribute
var canvas = document.getElementById('canvas');
// size the display appropriately
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// don't forget to account for the window size changing later on
window.addEventListener('resize', function(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}, false);
When using the HTML5 drag and drop API, it would appears though the .width property on has no impact on the width of an image being used as an icon for dragging. Take this fiddle for example: http://jsfiddle.net/cnAHv/7/. You can set dragIcon.width to anything you want, and it will not change the actual width of the icon.
Most of the resources on the web seem to arbitrarily set dragIcon.width to 100. Is this just a matter of people copying eachother's code without checking functionality?
So...
Is the width property on an image variable actually something that setDragImage() will accept?
If not, how would you set the width of the icon without manually changing sizing the image in a program like photoshop?
When you use an <img> in setDragImage Javascript will just use the actual image bitmap data, ignoring other attributes like width. Check the specs.
However if you do something like this:
function handleDragStart(e) {
var dragIcon = document.createElement('img');
dragIcon.src = 'http://jsfiddle.net/favicon.png';
dragIcon.width = '100';
var div = document.createElement('div');
div.appendChild(dragIcon);
document.querySelector('body').appendChild(div);
e.dataTransfer.setDragImage(div, -10, -10);
}
http://jsfiddle.net/cnAHv/9/
You will see the drag shadow now contains the bigger image. It occurs because when we use other visible HTML elements (that's why I appended the DIV to the body), the browser will use its rendered view as a drag image.
This answer might be a bit late but you can also use a canvas to scale your original image.
function handleDragStart(e) {
var dragIcon = document.createElement('img');
dragIcon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC';
var width = 100;
var height = width * (3/4); // The height must be set explicitly. I'm assuming the image is 4:3 for this example
var c = document.createElement("canvas");
c.width = width;
c.height = height;
var ctx = c.getContext('2d');
ctx.drawImage(dragIcon,0,0,width,height);
dragIcon.src = c.toDataURL();
e.dataTransfer.setDragImage(dragIcon, -10, -10);
}
http://jsfiddle.net/cnAHv/138/
The only downside to this is that the canvas may be tainted if the image doesn't come from the same origin. More on tainted canvases here
Without the use of jquery (ie only using old javascript), how can I set all canvas's in the html document to the document's width and height?
Note: Both Chief's and Naelio's answers are technically incorrect.
Naelio:
Changing the canvas's style will change the canvas's CLIENT WIDTH and CLIENT HEIGHT not the actual width and height so the content of the canvas will end up being scaled / stretched.
Example of this problem here: http://jsfiddle.net/AnLCw/1/ (note how the black 50x50 square is stretched using the style approach)
Chief17:
You can't specify the width and height of a canvas in percentages. Example of the problem here: http://jsfiddle.net/Sg7cb/2/ (note that no canvas shows up when width and height are percentages)
So here is the actual solution:
You need to set the canvas's style to be: width: 100% and height: 100%
canvas.style.width = "100%"
canvas.style.height = "100%"
and then do:
canvas.width = canvas.clientWidth
canvas.height = canvas.clientHeight
Working example here: http://jsfiddle.net/acYdc/1/ (Notice how the black square draws correctly and the canvas fills the area.)
Another solution is just to set
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
but the canvas.width = canvas.clientWidth approach is more flexible.
I've created a jsFiddle here: http://jsfiddle.net/ZrfeV/
You will need to give the document a height so the canvas knows how big to expand to, otherwise it will expand to whatever height the document gains by the internal height of its child elements.
var canvases = document.getElementsByTagName('canvas');
for (var i = 0; i < canvases.length; i++) {
canvases[i].style.width = '100%';
canvases[i].style.height = '100%';
canvases[i].width = canvases[i].clientWidth;
canvases[i].height = canvases[i].clientHeight;
}
I'm trying to allow the user to draw a rectangle on the canvas (like a selection box). I'm getting some ridiculous results, but then I noticed that even just trying the code from my reference here, I get huge fuzzy lines and don't know why.
it's hosted at dylanstestserver.com/drawcss. the javascript is inline so you can check it out. I am using jQuery to simplify getting the mouse coordinates.
The blurry problem will happen if you use css to set the canvas height and width instead of setting height and width in the canvas element.
<style>
canvas { height: 800px; width: 1200px; } WRONG WAY -- BLURRY LINES
</style>
<canvas height="800" width="1200"></canvas> RIGHT WAY -- SHARP LINES
For some reason, your canvas is stretched. Because you have its css property width set to 100%, it is stretching it from some sort of native size. It's the difference between using the css width property and the width attribute on the <canvas> tag. You might want to try using a bit of javascript to make it fill the viewport (see jQuery .width()):
jQuery(document).ready(function(){
var canvas = document.getElementById('drawing');
canvas.width(($(window).width()).height($(window).height());
var context = canvas.getContext('2d');
//...
The way I do it is to set the canvas element to a width and height in the css, and then set the canvas.width = canvas.clientWidth and canvas.height = canvas.clientHeight
var canvas = document.getElementById("myCanvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var context = canvas.getContext("2d");
You haven't indicated canvas size in pixels, so it is scaled up. It is 300x150 here. Try setting the width, height
On retina displays you also need to scale (in addition to the accepted answer):
var context = canvas.getContext('2d');
context.scale(2,2);
The css sizing issue mentioned in these comments is correct, but another more subtle thing that can cause blurred lines is forgetting to call make a call to context.beginPath() before drawing a line. Without calling this, you will still get a line, but it won't be smoothed which makes the line looks like a series of steps.
I found the reason mine was blurry was that there was a slight discrepancy between the inline width and the CSS width.
I have both inline width/height parameters AND css width/height assigned to my canvas, because I need to keep its physical dimensions static, while increasing its inline dimensions for retina screens.
Check yours are the same if you have a situation like mine.