can't position canvas over image - javascript

I'm trying to draw some stuff over loaded image. However, for some reason canvas appears below the image not on top. I'm doing it as follows:
I have the following container:
<div id="container">
<img src="{{url_for('static', filename='nature.jpg')}}" id="target" style="zIndex=1">
</div>>
And the I'm trying to add canvas as follows:
window.onload = function() {
var img = document.getElementById('target');
var width = img.naturalWidth;
var height = img.naturalHeight;
var canvas = document.createElement('canvas'); //Create a canvas element
//Set canvas width/height
canvas.style.width=width;
canvas.id = 'mycanvas';
canvas.style.height=height;
//Set canvas drawing area width/height
canvas.width = width;
canvas.height = height;
//Position canvas
canvas.style.position='absolute';
canvas.style.left=0;
canvas.style.top=0;
canvas.style.zIndex=100000;
canvas.style.pointerEvents='none'; //Make sure you can click 'through' the canvas
$('#container').append(canvas);
}
However, canvas appears below the image rather than on top of it. What am I doing wrong?
thanks

You've used the wrong syntax for the inline style style="zIndex=1", it should be style="z-index: 1", still, for z-index to work its element need a position other than static
In this case, since the img has no position, you can actually drop the z-index all together, as the canvas has a position, position: absolute, and will be layered on top of the image because of that alone.
For the canvas to be positioned relative to the container, the container need a position, i.e. position: relative

Related

How to export Canva Render has GIF with CSS modification

I'm using p5.js to make a GIF animation but I have an issue when I want to export it.
I did a pixelased effect on my animation by adding these css properties to the Canva (140*140) :
image-rendering: pixelated;
width:500px;
height:500px;
My problem is that I can't export this Canva with the properties I added. (I'm using CCapture)
My gif is in 140x140 without the pixelated effect.
How can I get the rendering I need?
There is a difference between the width & height you can set for a HTML element e.g. <canvas width='140' height='140'> and the CSS width & height properties.
The former defines the actual size of the canvas - 140x 140in this case.
If we now set the CSS width & height to something deviating from the HTML element's width & height e.g. <canvas width='140' height='140' style='width: 500px; height:500px;'> the actual size in pixels of the canvas does not change - it stays 140 x 140 pixels. The CSS properties just control the displayed size of the element inside the browser, meaning the 140 x 140 are simply stretched to 500 x 500.
So if you get actual pixel data of the canvas - for exporting to gif/png - the final image will have the original dimensions of the canvas - not the rendered.
The fix is quite simple though. Instead of directly using the source canvas for exporting, draw it's content on a second canvas, the size of your desired resolution.
To force the 'export' canvas to not use any filtering/smoothing, you need to set the imageSmoothingEnabled property of it's context to false.
Here's an example (you can right-click and save both images to see the difference):
var ctx = document.getElementById('canvas').getContext('2d');
var image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0);
let sourceCanvas = document.getElementById("canvas");
let virtualWidth = parseInt(getComputedStyle(sourceCanvas).width);
let virtualHeight = parseInt(getComputedStyle(sourceCanvas).height);
var canvas = document.getElementById("exportCanvas");
canvas.width = virtualWidth;
canvas.height = virtualHeight;
canvas.getContext('2d').imageSmoothingEnabled = false;
canvas.getContext('2d').drawImage(sourceCanvas, 0, 0, virtualWidth, virtualHeight);
}
image.src = 'https://mdn.mozillademos.org/files/12640/cat.png';
canvas {
width: 500px;
height: 500px;
}
<span>Rendered canvas</span><br>
<canvas id="canvas" width="140" height="140"></canvas><br>
<span>Export canvas</span><br>
<canvas id="exportCanvas"></canvas>

Canvas auto resize height [duplicate]

I have the canvas
<canvas id="canvas" width="1700" height="679" style="background-color:#ffffff;width:100%;overflow:hidden;margin-top: -7px;"></canvas>
It work fine on chrome and firefox. However, ie can work only with width:100% but not change the height (height on 679)
I try height to be auto and 100% but getting wose
Edit: finally! I got it.
It's true that the canvas content will be not good at width 100%.
However, for the height (IE9 above is work) you have to set height style
$("#canvas").attr('style','background-color:#ffffff; width:100%;height:679px;overflow:hidden;margin-top: -7px;');
And use Jquery to re-size the canvas
function resizeIE()
{
canvas = document.getElementById("canvas");
if($.browser.msie) //only IE
{
$("#canvas").attr('style','background-color:#ffffff; width:100%;height:679px;overflow:hidden;margin-top: -7px;');
//set the height style first
if(window.innerWidth<960) //for other device (only for me)
{
var height_ie = (window.innerWidth*39.941176470588235294117647058824)/100;
//to make the ratio of canvas find the pencentage
//ex. canvas height: 1700px canvas width: 679px;
//(679*100)/1700 = 39.941 <-- use this one
//best solution
}
else
{
var height_ie = window.innerHeight-160; //just for the logo for my web
}
canvas.style.height = height_ie+"px";
}
}
for re-size window apply on document.ready
window.onresize = function(event) {
resizeIE();
};
If you use CSS to resize canvas you are actually reshaping the canvas's viewport.
Think of this as scaling the image. Just like when you resize a .jpg image, you can get pixilation and distortion.
Instead resize the canvas element's size.
Think of this as adding more empty pixels to the width and height of the canvas, rather than "stretching" the existing pixels.
Here's how to add pixels to the canvas element to make it 100% of the browser window:
var canvas=getElementById("myCanvas");
canvas.width= window.innerWidth;
canvas.height=window.innerHeight;
If you are resizing your browser window, you can put this code in the windows resize handler to make it happen automatically.
Note: Whenever you resize the canvas this way, you will have to redraw the canvas contents.
$("#canvas").attr('style','background-color:#ffffff; width:100%;height:679px;overflow:hidden;margin-top: -7px;');
And use Jquery to re-size the canvas
function resizeIE()
{
canvas = document.getElementById("canvas");
if($.browser.msie) //only IE
{
$("#canvas").attr('style','background-color:#ffffff; width:100%;height:679px;overflow:hidden;margin-top: -7px;');
//set the height style first
if(window.innerWidth<960) //for other device (only for me)
{
var height_ie = (window.innerWidth*39.941176470588235294117647058824)/100;
//to make the ratio of canvas find the pencentage
//ex. canvas height: 1700px canvas width: 679px;
//(679*100)/1700 = 39.941 <-- use this one
//best solution
}
else
{
var height_ie = window.innerHeight-160; //just for the logo for my web
}
canvas.style.height = height_ie+"px";
}
}
for re-size window apply on document.ready
window.onresize = function(event) {
resizeIE();
};

Scaling a canvas. What am I doing wrong

$('#myCanvas').click(function (e) { //Default mouse Position
console.log(e.pageX);
$("#myCanvas2").attr("width", e.pageX );
$("#myCanvas3").attr("width", e.pageX );
var imageData = context.getImageData(0, 0, e.pageX,400);
context2.putImageData(imageData,0,0);
context3.putImageData(imageData,0,0);
context.clearRect ( 0 , 0 , 2000 , 2000 );
$("#myCanvas3").css("scale", "(-1, 1)" );
$("#myCanvas3").css("transform", "scale(-1,1)");
var canvas4 = document.getElementById('myCanvas4');
var context4 = canvas4.getContext('2d');
context4.drawImage( myCanvas2, 0,0 );
context4.drawImage(myCanvas3, e.pageX,0 );
context3.scale(3,3);
});
I am trying to scale my canvas with the scale command.
What am I doing wrong?
I'm not clear what you're trying to do, but these thoughts come to mind:
To get an accurate canvas mouse position, calculate relative to the canvas element:
$('myCanvas').click(function(e){
var BB=canvas.getBoundingClientRect();
var mouseX=parseInt(e.clientX-BB.left);
var mouseY=parseInt(e.clientY-BB.top);
}
About mixing CSS and Canvas:
CSS scale will operate on the center of the element.
Canvas scale will operate from the origin (the origin defaults to 0,0).
CSS scaling will not affect Canvas drawing. So if you "flip" using CSS scaling and then you draw the flipped element to a canvas, the resulting canvas drawing is not flipped.
Changing the canvas element width will also automatically clear the canvas content.
Changing CSS width will retain the canvas content, but will "stretch" the existing pixels into the new width (the content will appear deformed).
Canvas scaling commands only affect drawings done after the scale command. So your context3.scale(3,3) will not affect anything you have previously drawn on myCanvas3.
Here's how to horizontally flip an image on a canvas element:
Example code and a Demo: http://jsfiddle.net/m1erickson/tSPB2/
var img=document.getElementById("theImg");
var iw=img.width;
var ih=img.height;
var canvas2=document.getElementById('myCanvas2');
var context2=canvas2.getContext('2d');
canvas2.width=iw;
canvas2.height=ih;
context2.save();
context2.translate(iw,0);
context2.scale(-1,1);
context2.drawImage(img,0,0);
context2.restore();

HTML5/ Javascript - Stretch image source

Hi I'm getting image from webcam and I save it on canvas, what I want to do is to stretch it by x and y cooridnates keeping same img dimensions, what I mean is, this is the original webcam picture:
and this is how I wanna it to be when stretched:
<canvas id="canvas" width="640" height="480" style="border:1px solid #d3d3d3;"></canvas>
this is the piece of code that shows source image to <img> element in html , so I have to stretch source image before to show it in html
function snap() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
var oImg=document.createElement("img");
oImg.setAttribute('src', canvas.toDataURL());
oImg.setAttribute('alt', 'na');
oImg.setAttribute('width', '1300');
oImg.setAttribute('height', '1300');
var img = document.body.appendChild(oImg);
return img;
}
}
any idea on how to stretch the canvas.toDataUrL() source by x and y coordinates and return it stretched to the the src <img> element?
The real problem imo is how to stretch image without altering width
and height (as shown via example photos above), is this possible?
You can use the extended properties on context.drawImage that allow scaling/positioning.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
var w=img.width;
var h=img.height;
canvas.width=w; // set the canvas size to the original image size
canvas.height=h;
ctx.drawImage(img,
0,0,w,h, // start with the image at original size
-w/4,0,w*1.25,h // widen the original image by 1.25X
// and start drawing 1/4th off the left edge of the canvas
);
}
img.src="temp18.png";

Replacing divs with background images with canvas elements

I am trying to replace any divs that have background images with canvas elements with those background images drawn onto them.
I've got the basics working but I am slightly stumped by the difference in image quality between the background-image on a div and the same image drawn onto a canvas.
Here is the code I am using to do this:
$('#container div').each(function(){
if($(this).css('background-image') != 'none'){
var bgImage = $(this).css('background-image').replace(/^url|[\(\)]/g, '');
var image = new Image();
var attrs = $(this)[0].attributes;
var dimensions = new Array();
var canvas = document.createElement('canvas');
dimensions.push($(this).height())
dimensions.push($(this).width());
$(canvas).attr('width',dimensions[0]);
$(canvas).attr('height',dimensions[1]);
$(canvas).css('background-image', 'none');
for(var i = 0; i < attrs.length; i++){
$(canvas).attr(attrs[i].nodeName,attrs[i].nodeValue);
}
var ctx = canvas.getContext('2d');
image.onload = function () {
ctx.drawImage(image, 0, 0, image.height, image.width);
}
image.src = bgImage;
$(this).replaceWith(canvas);
}
});
Here are the results:
It looks like the image is being stretched for some reason but I've tried to console.log the width/height of the image that I am using in drawImage and the values match up to the image dimensions. The results show just a crop of the image - the real one is 900x4000ish pixels.
Here is a jsfiddle link showing the problem in action:
http://jsfiddle.net/xRKJt/
What is causing this odd behaviour?
Ha! (took some seconds to figure out)
Image has naturalWidth and naturalHeight attributes which reflect its pixel dimensions. Change your code
image.onload = function () {
ctx.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight);
}
Because the image is so large, if you open the image in the browser it zooms out it by default. I think you'll get those zoomed out width and height attributes if you try to access image.width and image.height. Or something along the lines.

Categories