Incorrect canvas width value - javascript

So I thought that the code
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Log Canvas Width</title>
<style>
#canvas {
background: #888888;
width: 600px;
height: 600px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
document.write(canvas.width);
}
</script>
</head>
<body onload="draw();">
<canvas id='canvas'>
Canvas not supported
</canvas>
</body>
</html>
prints 300 rather than 600 because <body onload="draw();"> makes the script run at page loading, and at that time the canvas has not yet caught the revised value (600).
But then I modify the code to:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Log Canvas Width</title>
<style>
#canvas {
background: #888888;
width: 600px;
height: 600px;
}
</style>
</head>
<body>
<canvas id='canvas'>
Canvas not supported
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
document.write(canvas.width);
</script>
</body>
</html>
Now I'm imagining that the script runs after the canvas has taken the attribute from the embedded style and that I will see 600. Not true. I still get 300, even though the canvas duly has width = 600. What is happening?

Default width of canvas is 300 x 150 [Ref]. Canvas does not consider css defined with. Either you defined width/heigh attributes or assign those values as properties of canvas element.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
alert(canvas.width);
<canvas id='canvas' width='600'>
Canvas not supported
</canvas>
OR
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = 600;
alert(canvas.width);
<canvas id='canvas'>
Canvas not supported
</canvas>

canvas.width and canvas.style.width are two different things. In most of the cases, they should be equal, but they can also be different for achieving various effects. 300 you're getting is the canvas default width.
canvas.width is the actual number of pixels that are available inside the canvas, while canvas.style.width is the width of the HTML element, thus you can see stretching, pixelation, etc, if the two numbers are different.
Here are a couple of answers that describe the issue in more detail:
https://stackoverflow.com/a/28142612/965907
https://stackoverflow.com/a/34539170/965907
https://stackoverflow.com/a/28879318/965907

I found that setting the canvas width and height equal to the style width and height helped me with the calculations later.
Like:
canvas.width = canvas.getBoundingClientRect().width;
canvas.height = canvas.getBoundingClientRect().height;

Related

SVG quality loss during scaling

I'm using fabricjs to add an animated sprite to my canvas. Unlike in the demo on the fabricjs website I am using an .svg sprite not .png, so it should scale without quality loss.
However when I try and scale up the svg sprite the quality loss is huge. I have tested the sprite as a static object and it scales without any issues with the quality.
Video: https://streamable.com/ya5a
Here's an example, the top image is the sprite with it's default size and below that I have increased it's size and you can see the edges are nasty.
What could be causing the svg to have quality issues when scaling as an animated sprite?
Here is the sprite (crude test image) http://imgh.us/sprite1_2.svg
HTML/JS
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="http://fabricjs.com/lib/fabric.js"></script>
<script src="http://fabricjs.com/js/sprite.class.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<canvas id="canvas" width="500" height="300" style="border:1px solid #444;"></canvas>
<div id="add">Click here to add Animated SVG sprite</div>
<script>
var canvas = this.__canvas = new fabric.Canvas('canvas');
var src1 = "img/sprite1_2.svg";
$("#add").click(function(){
fabric.Sprite.fromURL(src1, createSprite(1),{"width":50,"height":72});
});
function createSprite(i) {
return function(sprite) {
sprite.set({
left: i * 100 + 50,
top: i * 100 + 50,
hasBorders: false,
padding: 0,
});
canvas.add(sprite);
setTimeout(function() {
sprite.play();
}, fabric.util.getRandomInt(1, 10) * 100);
};
}
(function render() {
canvas.renderAll();
fabric.util.requestAnimFrame(render);
})();
</script>
</body>
</html>
(I've found the only way I can get this demo to work is in FF and if the svg is hosted locally, due to SecurityError. Which stopped me making a working fiddle/jsbin)

drawing a triangle on canvas

I am having trouble drawing a triangle on a canvas. Triangle: equilateral triangle with 2 points on the x-axis. So what I was thinking: I start in the bottom right corner, move up to the next point, and then move to the last point in the lower left. Here is what I have:
<!doctype html>
<html lang="en">
<head>
<meta charset= "UTF-8">
<script type="text/JavaScript">
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var sWidth = screen.width;
var sHeight = screen.height;
var path=new Path2D();
path.moveTo((sWidth/2)+50,sHeight/2);
path.lineTo((sWidth/2),(sHeight/2)-50);
path.lineTo((sWidth/2)-50,sHeight/2);
ctx.fill(path);
}
}
</script>
</head>
<body onload="draw();">
<div align = "center">
<canvas id = "canvas">
</canvas>
</div>
</body>
</html>
Nothing gets drawn. I read: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes, but I'm not sure what I messed up.
You need to give a size to your canvas. Either with CSS, HTML or in JavaScript
Here is a snippet that works :
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var sWidth = canvas.width;
var sHeight = canvas.height;
var path=new Path2D();
path.moveTo((sWidth/2)+50,sHeight/2);
path.lineTo((sWidth/2),(sHeight/2)-50);
path.lineTo((sWidth/2)-50,sHeight/2);
ctx.fill(path);
}
}
draw();
<!doctype html>
<html lang="en">
<head>
<meta charset= "UTF-8">
<style>canvas { width: 200px; height: 200px; border: 1px solid red; }</style>
</head>
<body>
<canvas id="canvas">
</canvas>
</body>
</html>

minimize image size in canvas

i wanted to add a image on my canvas .the width and height of the canvas is 400X400.and size of the image is 298x300.i want it to have the size of 30x30 when it will be drawn on the canvas.so i gave it width and height inside script tag.but it is not affecting the original size of the image .it covers up the whole canvas(even only half of it is shown).how can i fix this?
![<html>
<head>
<style>
#mycanvas{
width:400;
height:400;
border:1px solid black;
}
</style>
</head>
<body>
<script>
function draw(){
var canvas=document.getElementById("mycanvas");
var ctx=canvas.getContext('2d');
var img=new Image();
img.src="lol1.jpg";
img.style.width="30px";
img.style.height="30px";
ctx.drawImage(img,0,0);
}
window.onload=draw;
</script>
<canvas id="mycanvas"></canvas>
</body>
</html>]
Just use:
ctx.drawImage(img,0,0,30,30);
4th parameter is width, 5th is height.

Making a canvas as a background doesn't perform as anticipated

So in this question I was under the impression that using a canvas as a background was faster,or the same speed as using a canvas tag. I currently have a rather bulky script running for a simulator. For some javaScripting reasons I cannot make the menu using JavaScript without detracting from the simulation so I had planned to use HTML to make a menu swipe from the side of the screen. As I was working on that I stumbled on the above link; however when I run the program using the background method it runs much slower. Is there any reason for this, and is there any solution?
Here are the relevant portions of code:
HTML
<html>
<head>
<title>Curtain Sim 2013 </title>
<link href="global.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="fabric.js"></script>
<script type="text/javascript" src="background.js"></script>
<script type="text/javascript" src="savDat.js"></script>
</head>
<div id = "canvas" style="width:100%; height:100%; background: -webkit-canvas(curSim2013); "></div>
<!--<body>
<canvas id="curSim2013">
Your Browser does not support HTML5 </canvas>
</body>-->
</html>
Javascript from main.js which runs it (there are some artifacts commented out from my experimenting)
function init()
{
//Grab the Canvas tag from index.html
canvas = document.getElementById('canvas');
//Create an interface for interacting with canvas in 2D
//context = canvas.getContext('2d');
//var ctx = document.getCSSCanvasContext("2d", "squares", w, h);
//Set the dimensions of the canvas to match the broser window
//Note that global.css helps make this possible
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
context = document.getCSSCanvasContext("2d", "curSim2013", canvas.width, canvas.height);
//Erase the contents of the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
. . .
CSS (nothing much)
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
So what I ended up doing (I don't know HTML at all) was changing the css to look like this:
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
canvas {
position:absolute;
left:0px;
top:0px;
z-index:-1;
}
div {
position:absolute;
left:0px;
top:0px;
z-index:1;
color:rgb(255,0,255);
}
and used the canvas method. This works perfectly and the speed isn't effected.
New HTML
<html>
<head>
<title>Curtain Sim 2013 </title>
<link href="global.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="fabric.js"></script>
<script type="text/javascript" src="background.js"></script>
<script type="text/javascript" src="savDat.js"></script>
</head>
<!--<div id = "canvas" style="width:100%; height:100%; background: -webkit-canvas(curSim2013); position: absolute;"></div>-->
<body>
<div>
<p>
hi
</p>
</div>
<canvas id="canvas">
Your Browser does not support HTML5 </canvas>
</body>
</html>
new Javascript
function init()
{
//Grab the Canvas tag from index.html
canvas = document.getElementById('canvas');
//Create an interface for interacting with canvas in 2D
context = canvas.getContext('2d');
//var ctx = document.getCSSCanvasContext("2d", "squares", w, h);
//Set the dimensions of the canvas to match the broser window
//Note that global.css helps make this possible
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
. . .

Display whole image in circulr shape using Javascript or HTML5

How can I display whole image in circulr shape using Javascript or HTML5. I tried the code below but with this code only part of the image will be converted into circular shape. How can I make the whole display in circular shape?
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style>
<script type="text/javascript" >
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<div id="myCanvas"></div>
<script>
var ctx = document.getElementById('myCanvas').getContext("2d");
ctx.arc(100,100, 50, 0, Math.PI*2,true); // you can use any shape
ctx.clip();
var img = new Image();
img.addEventListener('load', function(e) {
ctx.drawImage(this, 0, 0, 200, 300);
}, true);
img.src="images/hospital_review_profile_placeholder.png";
</script>
</body>
</html>
Instead of using ctx.clip(), you would resize and reposition your image to fit in your circle.
Here is code that will resize your image to its largest size that will fit in the circle.
Then the code positions the resized image properly in the circle.
Here is a Fiddle --- http://jsfiddle.net/m1erickson/s6MzZ/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var radius=50; // circle radius
var fullWidth=200; // actual width of image in pixels
var fullHeight=300; // actual height of image in pixels
var centerX=100; // center X coordinate of the circle
var centerY=100; // center Y coordinate of the Circle
// the image must be resized to fit into the circle
// Call CalcResizedImageDimensions() to get the resized width/height
var size=CalcResizedImageDimensions(radius,fullWidth,fullHeight);
var rectX=centerX-size.width/2; // the X coordinate of the resized rectangle
var rectY=centerY-size.height/2 // the Y coordinate of the resized rectangle
ctx.beginPath();
ctx.arc(centerX,centerY,radius,0,Math.PI*2,true);
// I illustrate with just a rectangle
// you would drawImage() instead
ctx.rect(rectX,rectY,size.width,size.height);
ctx.stroke();
function CalcResizedImageDimensions(r,w,h){
var d=2*r;
var newH=(d*h)/Math.sqrt(w*w+h*h);
var newW=w/h*newH;
return({width:newW,height:newH});
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=200 height=200></canvas>
</body>
</html>

Categories

Resources