I have tried to create an HTML page with a full screen canvas and I can draw to this fine. If I create a second "off screen" canvas to draw on and display on the main canvas I do not see anything.
My code is:
var canvas;
var canvas_ctx;
var off_canvas = document.createElement('canvas');
var off_canvas_ctx;
init();
drawTree();
function init() {
canvas = document.getElementById('treeCanvas');
if (canvas.getContext) {
canvas_ctx = canvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
}
off_canvas.width = 5000;
off_canvas.height = 5000;
off_canvas_ctx = off_canvas.getContext('2d');
}
function resizeCanvas() {
var cWidth = window.innerWidth;
var cHeight = window.innerHeight - 3;
var imgData = canvas_ctx.getImageData(0, 0, cWidth, cHeight);
// Resize original canvas
canvas.width = cWidth;
canvas.height = cHeight;
// Copy back to resized canvas
canvas_ctx.putImageData(imgData, 0, 0);
}
function drawTree() {
canvas_ctx.fillStyle = "#FF0000";
canvas_ctx.fillRect(0, 0, 150, 75);
off_canvas_ctx.fillStyle = "#FF0000";
off_canvas_ctx.fillRect(0, 0, 150, 75);
resizeCanvas();
}
<div align="center">
<canvas id="treeCanvas" width="200" height="100">
Your browser does not support the canvas element.
</canvas>
</div>
My "drawTree()" function currently draws the same thing to both canvas contexts and then calls "resizeCanvas()" in order to update the display.
If I use the line
var imgData = canvas_ctx.getImageData(0, 0, cWidth, cHeight);
in "resizeCanvas()", the rectangle displays but if I try to use the image data from the off screen canvas with the line
var imgData = off_canvas_ctx.getImageData(0, 0, cWidth, cHeight);
then nothing is displayed. Can anyone see what I am doing wrong?
My mistake, in the "init()" function i was calling "resizeCanvas()" before i had got the context to the second canvas, this seemed to mess it up for the rest of the session.
canvas_ctx = canvas.getContext("2d");
off_canvas.width = 5000;
off_canvas.height = 5000;
off_canvas_ctx = off_canvas.getContext('2d');
Moving the block up appears to have fixed the problem.
Related
I'm trying to have a full-screen canvas, and I wanted to resize it WITH its contents proportionally. I'm debating which of these two methods is better...
1) having everything with pixel-based values then simply scaling the entire canvas with css if the window gets resized...
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 1280;
canvas.height = window.innerHeight;
var sizeCanvas = function(){
scale = window.innerWidth/1280;
canvas.style.transform = 'scale('+ scale + ')';
canvas.height = window.innerHeight/scale;
}
sizeCanvas();
window.addEventListener('resize', function(){
sizeCanvas();
});
function loop(){
window.requestAnimationFrame(loop);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0,0,1280,300);
}
OR
2) drawing the canvas at window.inner size constantly, and resizing every image with relative values to the canvas width and height
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var sizeCanvas = function(){
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
}
sizeCanvas();
window.addEventListener('resize', function(){
sizeCanvas();
});
function loop(){
window.requestAnimationFrame(loop);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height/4);
}
I have a lot going on the canvas, so I guess performance is probably the biggest priority
Basically what my project does is to fetch a picture from Database, place it into canvas, move it, zoom in and out, this this are working perfectly.
Next step is to rotate the picture and i have no idea what I am doing wrong. In the picture i described how my document looks like when the canvas is accessed. After I rotate the picture, it goes outside the canvas. My code looks like below and i have no idea what I am doing wrong. Thank you
function drawRotated(degrees) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(image.width*0.15,image.height*0.15);
ctx.rotate(degrees * Math.PI / 180);
ctx.translate(-image.width*0.15,-image.height*0.15);
ctx.drawImage(image, 0, 0, image.width*0.15, image.height*0.15);
}
Maybe this is not the answer you are expecting for. I didn't use your code. I hope it helps.
The main idea is to draw the image with the center in the origin of the canvas.
window.onload = function() {
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 200;
var gkhead = gk;
gkhead.src = gk.src;
let w = gkhead.width;
let h = gkhead.height;
let x = -w/2;
let y = -h/2;
ctx.drawImage(gkhead,x,y,w,h);
function translateToThePoint(p){
ctx.save();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(p.x,p.y);
ctx.scale(.25,.25);
ctx.drawImage(gkhead,x,y,w,h);
ctx.restore();
}
function rotate(angleInRad, p){
ctx.save();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(p.x,p.y);
ctx.rotate(angleInRad);
ctx.scale(.25,.25);
ctx.drawImage(gkhead,x,y,w,h);
ctx.restore();
}
let p = {x:canvas.width/2,y:canvas.height/2}
//translateToThePoint(p);
rotate(-Math.PI/10,p);
}
canvas {
border:1px solid
}
<canvas id="canvas">
<img id="gk" src='https://www.warrenphotographic.co.uk/photography/cats/38088.jpg' />
</canvas>
Here is my code. I am uploading a image and using like this :
> var canvas = document.createElement('canvas');
> var context = canvas.getContext('2d');
> context.drawImage(image, 0, 0);
This works fine but if I copy the imagedata like below to another canvas. It loads image partially.
var canvas = document.getElementById('myCanvas');
var context1 = canvas.getContext('2d');
context1.putImageData(context.getImageData(0, 0, image.width, image.height), 0, 0);
I tried same approach by creating two canvas and this code which worked fine but without image.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 300, 300);
var d = document.getElementById("myCanvas1");
var btx = d.getContext('2d');
var imgData = ctx.getImageData(0, 0, 300, 300);
btx.putImageData(imgData, 0, 0);
If i create two canvas it works fine but not like the above where I am using in memory canvas.
My HTML file has this :
<canvas id="myCanvas" width="960" height="960"></canvas>
<canvas id="myCanvas1" width="960" height="960"></canvas>
When you create canvases, you need to set their width manually. Default canvas size is 300x150. From here HTMLCanvasElement.
Something like this:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
To copy one canvas to another use drawImage rather than getImageData, setImageData That way you will use the GPU to move the pixels rather than the CPU. You also have the option to resize, crop, and apply a variety of FXs.
// create a copy of canvasSource
// returns the newly created canvas.
function copyCanvas(canvasSource){
var canvasCopy = document.createElement("canvas");
canvasCopy.width = canvasSource.width;
canvasCopy.height = canvasSource.height;
canvasCopy.getContext("2d").drawImage(canvasSource, 0, 0);
return canvasCopy;
}
The title is poorly worded but there's no way to concisely describe the problem. I'm drawing images to the 2D context of a dynamically created canvas. The data of the context is then saved to an image via toDataURL, which is then draw on every frame. The code below is condensed, I will be drawing multiple images to the context, not just one; which is why I'm saving to an image. I will only draw part of the image at once but the image remains constant so I thought this was the best method, if there are alternatives I will happily accept those as answers.
In short: many images drawn on an image. Part of the image draw each frame.
The code below works:
var picture = new Image();
picture.src = "images/tilesheet.png";
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
function generate(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = canvas.width;
ctx.canvas.height = canvas.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(picture,0,0);
image = new Image();
image.src = ctx.canvas.toDataURL("image/png");
}
function draw(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0,0,100,100,0,0,100,100);
}
function play(){
generate();
setInterval(function(){draw();}, 0.0333);
}
window.onload = function(){
if(picture.complete)play();
else picture.onload = play;
}
<canvas id="background"></canvas>
However this doesn't:
window.Game = {};
canvas = document.getElementById("background");
var tilesheet = new Image();
tilesheet.src = "images/tilesheet.png";
(function(){
function Map(){
this.width = 2736;
this.height = 2736;
this.image = null;
}
Map.prototype.generate = function(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(tilesheet,0,0);
this.image = new Image();
this.image.setAttribute('crossOrigin', 'anonymous');
this.image.src = ctx.canvas.toDataURL("image/png");
}
Map.prototype.draw = function(context){
context.drawImage(this.image, 0,0, context.canvas.height, context.canvas.height, 0, 0, context.canvas.height, context.canvas.height);
}
Game.Map = Map;
})();
(function(){
var room = new Game.Map();
room.generate();
var draw = function(){
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
room.draw(canvas.getContext("2d"));
}
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
})();
window.onload = function(){
if(tilesheet.complete)Game.play();
else tilesheet.onload = Game.play;
}
<canvas id="background"></canvas>
It seems therefore, that the problem is lying in the fact that I'm using function objects but I'm not sure. What am I doing wrong? There are no errors in the debug console.
Those two have different execution order.
First one:
...
Attach image.onload
Call generate()
...
Second one:
...
Call generate()
Attach image.onload
...
That's why it's not working - generate() expects image to be loaded, however second case order doesn't guarantees it.
Instead of
...
room.generate();
...
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
do this
...
Game.play = function(){
room.generate();
setInterval(function(){draw();}, 0.0333);
}
I am trying to blank canvas when there is image already in it.
I want to remove old image and load new image that I am getting from var getfrontimage.
But It failed me.
$('#fittocanvasfront').click(function () {
var canvas = document.getElementById("canvas-front");
var c = canvas.getContext("2d");
var getfrontimage = $('#image-tocanvaschangefront').attr('src');
var img = new resize(getfrontimage);
function resize(src) {
console.log('blank canvas');
canvas.width = canvas.width;
var image = new Image();
image.src = getfrontimage;
image.width = canvas.width;
image.height = canvas.height;
image.onload = function () {
// clearing canvas
c.clearRect(0, 0, canvas.width, canvas.height);
//loading image
c.drawImage(image, 0, 0);
//creating a hole in canvas
var centerX = canvas.width / 2;
var centerY = canvas.offsetTop;
var radius = 30;
c.beginPath();
c.arc(centerX, centerY, radius, 0, 2 * Math.PI, true);
c.fillStyle = 'black';
c.fill();
}
}
});
Into the script-
I have image in <img> tag-
var getfrontimage = $('#image-tocanvaschangefront').attr('src');
this above image is what i will be using after clearing canvas.
So I tried doing canvas empty as below when image is being loaded-
c.clearRect(0, 0, canvas.width, canvas.height);
But this didn't work, I tried doing canvas empty on click-
$('#fittocanvasfront').click(function () {
var canvas = document.getElementById("canvas-front");
var c = canvas.getContext("2d");
c.clearRect(0, 0, canvas.width, canvas.height);
});
How do I empty this canvas with existing image in it.
What you are saying is not true. You can clear of any image using clearRect. Please see fiddle with your code where image's cleared on click.
$("#canvas-front").click(function(){
c.clearRect(0, 0, canvas.width, canvas.height);
});
Hard to say what you're doing wrong, since you didn't provide the full code, use the code I provided in fiddle and all should be fine.