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

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;
. . .

Related

Cannot render an image when source passed in as a variable

I am writing a code that takes in an image and pastes it into an HTML canvas. The code works when I declare my <img> in the HTML file, but this does not allow the user to input a new file.
Here is the html structure (the program works if the tag line is put back in:
<style type='text/css'>
canvas{
border: 10px solid black;
}
</style>
</head>
<body>
<canvas id='balls'>
</canvas>
<canvas id='hide' style:'border: 10px solid black;'>
<!-- <img id="taco" width="300" height="300" src="prime.png"> -->
</canvas>
<div>
<input id='url' placeholder="image url">
<button id='submit'>Submit</button>
</div>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<script src="client.js" async defer></script>
</body>
</html>
Here is the portion of JS code I am working on:
$(document).ready(onReady);
var canvas = document.querySelector('canvas');
canvas.width = 300;
canvas.height= 300;
let bounced = false;
let newPic = `id="taco" width="300" height="300" src="prime.png"`
function onReady(){
$('#submit').on('click', updateImage)
$('#hide').empty()
$('#hide').append(`<img ${newPic}>`)
makeCanvas();
setup();
animate();
}
function updateImage() {
newPic= `id="taco" width="300" height="300" src="${$('#url').val()}" alt="prime.png"`
//console.log(newPic)
$('#hide').empty()
$('#hide').append(`<img ${newPic}>`)
makeCanvas();
setup();
animate();
}
let c, can, ctx, img
function makeCanvas(){
c = canvas.getContext('2d');
can=document.getElementById("hide");
console.log(can)
can.width = 300;
can.height = 300;
ctx=can.getContext("2d");
img=document.getElementById("taco");
ctx.drawImage(img,10,10);
console.log(img)
console.log(ctx.drawImage(img,10,10))
}
My console.log statements for img are identical when the code in the HTML file is placed back in.
When you're setting up your canvas, your image isn't loaded at all. So your
ctx.drawImage(img,10,10);
call just draws... an unloaded image... an empty set of bytes... Nothing.
So you should first load your image. After that, drawing stuff will easily be done. Here's a little code example:
var canv, ctx, img;
function setup() {
//Setting up canvas
//Fetching Context
ctx = canv.getContext("2d");
//Now drawing our image
ctx.drawImage(img,10,10);
}
img = new Image();
img.onload = setup; //We'll setup the canvas after the image is fully loaded
img.src = "your/path/or/variable/pointing/to/your/image.ext";
Hope it helps!

How do I get pixels from Canvas created by js-dosbox

I have worked through the dosbox Div to find the canvas, but once I have found the node holding the canvas how can I reference it?
Getting the context of dbGranChild[0] just results in an error..
Im trying to build an array of the pixels that make up the dosbox window, so thought using the canvas get image and looping through as frames change would be one way. If there is a better way altogether than my above attempt happy to take that as an answer.
Code: http://plnkr.co/edit/MC1n9HfwWcqXlAk95XCO?p=preview
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>js-dos api</title>
<style type="text/css">
.dosbox-container { width: 640px; height: 400px; }
.dosbox-container > .dosbox-overlay { background: url(https://js-dos.com/cdn/digger.png); }
.dosbox-start { font-size: 35px !important; }
</style>
</head>
<body>
<div id="dosbox"></div>
<br/>
<button onclick="dosbox.requestFullScreen();">Make fullscreen</button>
<script type="text/javascript" src="https://js-dos.com/cdn/js-dos-api.js"></script>
<script type="text/javascript">
var dosbox = new Dosbox({
id: "dosbox",
onload: function (dosbox) {
dosbox.run("https://js-dos.com/cdn/digger.zip", "./DIGGER.COM");
},
onrun: function (dosbox, app) {
console.log("App '" + app + "' is runned");
}
});
var dosboxId = document.getElementById('dosbox');
dbChild = dosboxId.childNodes;
dbGranChild = dbChild[0].childNodes;
console.log(dbGranChild[0])
</script>
</body>
</html>
See the w3Schools tutorial.
First, you need to use a <canvas> tag instead of a <div>.
That is, replace this:
<div id="dosbox"></div>
with something like this:
<canvas id="dosbox" width="200" height="100" style="border:1px solid #000000;">
</canvas>`
Second, replace this code:
var dosboxId = document.getElementById('dosbox');
dbChild = dosboxId.childNodes;
dbGranChild = dbChild[0].childNodes;
console.log(dbGranChild[0])
With something like this:
var c = document.getElementById("dosbox");
var ctx = c.getContext("2d");
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();

Incorrect canvas width value

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;

Using destination-over to save background and actual sketch

I've read this and a few other questions, and it is clear I need to use destination-over to save the background and the sketch by display the new image over the old one.
I'm using Sketch.JS with my code as such:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
$('#myCanvas').sketch({
defaultColor: "red"
});
$('#download').click(function() {
ctx.globalCompositeOperation = "destination-over";
img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = 'http://lorempixel.com/400/200/';
ctx.drawImage(img, 0, 0);
$('#url').text(c.toDataURL('/image/png'));
window.open(c.toDataURL('/image/png'));
});
#myCanvas {
background: url(http://lorempixel.com/400/200/);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/intridea/sketch.js/gh-pages/lib/sketch.js"></script>
<canvas id="myCanvas"></canvas>
<input type='button' id='download' value='download'>
<span id='url'></span>
Fiddle
But that doesn't help. Clicking 'download' still only produces the sketch. Now, it seems I don't understand how I need to use destination-over properly. W3Schools doesn't seem to help.
Could anyone point me in the right direction please?
Assume you have a SketchJS canvas on top of an image containing a background:
#wrapper{positon:relative;}
#bk,#myCanvas{position:absolute;}
<div id='wrapper'>
<img crossOrigin='anonymous' id=bk src='yourImage.png'>
<canvas id="myCanvas" width=500 height=300></canvas>
</div>
Then when you want to combine the Sketch with the background and save it as an image you can use destination-over compositing to draw the background "under" the existing Sketch.
ctx.globalCompositeOperation='destination-over';
ctx.drawImage(bk, 0, 0);
Here's example code:
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://rawgit.com/intridea/sketch.js/gh-pages/lib/sketch.js"></script>
<style>
body{ background-color: ivory; }
#wrapper{positon:relative;}
#bk,#myCanvas{position:absolute;}
</style>
<script>
$(function(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
$('#myCanvas').sketch({ defaultColor: "red" });
$('#download').click(function() {
var img=document.getElementById('bk');
ctx.globalCompositeOperation='destination-over';
ctx.drawImage(bk, 0, 0);
ctx.globalCompositeOperation='source-over';
var html="<p>Right-click on image below and Save-Picture-As</p>";
html+="<img src='"+c.toDataURL()+"' alt='from canvas'/>";
var tab=window.open();
tab.document.write(html);
});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag to sketch on the map.</h4>
<button id=download>Download</button>
<div id='wrapper'>
<img crossOrigin='anonymous' id=bk src='https://dl.dropboxusercontent.com/u/139992952/multple/googlemap1.png'>
<canvas id="myCanvas" width=459 height=459></canvas>
</div>
</body>
</html>

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