I am using requestAnimationFrame to animate video streams and I know that request animation does not work in backgrounds so is there any way to make it run on background.
I know that we can animate using setInterval or setTimeout too but when I use these, animations were not work properly and images on video stream were blinking.
Here is my code:
const drawFrame = function drawFrame() {
if (!ctx) {
ctx = canvas.getContext('2d');
}
if (!tmpCanvas) {
tmpCanvas = document.createElement('canvas');
tmpCtx = tmpCanvas.getContext('2d');
tmpCanvas.width = canvas.width;
tmpCanvas.height = canvas.height;
}
tmpCtx.drawImage(videoElement, 0, 0, tmpCanvas.width, tmpCanvas.height);
const imgData = tmpCtx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
const data = selectedFilter(imgData);
ctx.putImageData(data, 0, 0);
if (!stopped) {
requestAnimationFrame(drawFrame);
} else {
tmpCanvas = null;
tmpCtx = null;
ctx = null;
}
};
requestAnimationFrame(drawFrame);
I guess you are out of luck. requestAnimationFrame intentionally pauses in the background because animations have no reason to be running in the background, and as you mention setInterval and setTimeout are not designed for animation and should not be used as such.
You mention that you need to animate a video stream. Do you mean that you are applying an animation on top of a video tag, or changing the appearance of the video element via a canvas element? In both cases, you shouldn't continue to do so in the background anyway, but you may give computeFrame (Firefox only) a go, which will fire once every frame of the video. Or is it that you are actually faking a video stream by animating a set of static images in succession? In that case, why are you not using the video element?
Related
I'm trying to make an animation using html canvas, but I don't know if I have the best approach to it.
What I'm trying is to make a <canvas id="canvas"></canvas> and draw a rectangle on it using the fillRect().
Then I'm executing a function onload, that has a timeout of 500 miliseconds.
The function basically draws the rectangle 1px to where I want, by changing its x or y, and then, with clearRect(), I'm crealing the rectangle some time after starting on the starting point and following the other one.
Am I doing this right? or is there a better way to approach it?
You can use this structure
const canvas = document.getElementById('can');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.backgroundColor = 'white';
var someconstructorName = function(paramA,paramB,...){
"Initialisation of variables and other things"
this.draw = function(){
"your logic"
}
this.update = function(){
"your update logic"
this.draw();
}
}
function animate(){
requestAnimationFrame(animate)
}
animate();
Check out this Pen here it will give you a good idea:
https://codepen.io/khanChacha/pen/YgpBxM
If you have to use this style multiple times, I recommend diving into AnimeJS, a JS library which makes animating a lot simpler. ^^
AnimeJS
It supports delays and timelines too, which seems to be what you are using right now ^^
So I have a problem with clearRect in js-canvas-animation. This problem happens only on Android API 16, and only in the moment when animation is restart.
I'm using setInterval() for my animation (here is simplify code)
function start() {
clearInterval(animationInterval);
x = 0;
canvas = document.getElementById("animationCanvas");
ctx = canvas.getContext("2d");
animationInterval = setInterval(func, 30);
}
function func() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(halfWidth - x, 0, 250, 150);
x += extensionStep;
}
It is look like a shore. But every time, when i restart animation with help start function, under new animation i see last frame previous animation. Already i was trying beginPath(), save, stroke. I check all question on SO and nothing.
How i can clear the background under animation?
So after several hours, i found one of the solves. It is strange bug for old android, because new android (i checked on api 24) it fixed. For hard cleaning you can detach canvas from DOM and reattach again:
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.style.display = 'none';// Detach from DOM
canvas.offsetHeight; // Force the detach
canvas.style.display = 'inherit'; // Reattach to DOM
It is simple operation and is not resource intensive.
I am developing a camera based SPA. When I'm trying to resize the image it cause to a memory leak.
without executing resize
first executing resize
.
second executing resize
The memory never go down until I do refresh.
It is strange the same app http://shitu.baidu.com does release the memory.
Here is the my resize function.
var useRightPen = function (img, pre_img_wid, pre_img_hei, aft_img_wid, aft_img_hei, callback) {
var canvas = document.createElement('canvas');
var ctx=canvas.getContext('2d');
canvas.setAttribute("height", aft_img_hei);
canvas.setAttribute("width", aft_img_wid);
var orientation = 1;
if (!!(/http/.test(img.src))) {
//memory keeps the same before the drawimage
canvas.getContext('2d').drawImage(img, 0, 0, aft_img_wid, aft_img_hei);
//memory goes up after the draimage
callback(canvas.toDataURL('image/jpeg'), aft_img_wid, aft_img_hei);
}
canvas = null;
}
Appreciate for everyone.
---update--06-11--2015
I make one fildde http://jsfiddle.net/onTheRoad/dc17guba/
The demo will reset the image src after every pick.Memory goes high on its way.
I am creating a image in a canvas and saving the image. I found a very nice plugin here.
Code for the image saving:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = imageURI;
imageObj.onload = function() {
contentW = $("#content").width();
canvas.width = 400;
canvas.height = 600;
context.drawImage(imageObj, 0, 0,canvas.width,canvas.height);
//the plugin
setTimeout(function(){
window.savephotoplugin(canvas,"image/png",device.version,function(val){
//returns you the saved path in val
alert("Photo Saved: " + val);
});
},3000)
}
The plugin works very nice only problem is that it is done before the canvas is even drawn. So I put a setTimeout to avoid it, however is there a way to detect when canvas is done and call the function after it. Tried jquery .change() didn't work.
If anyone finds this code useful feel free to use and the plugin is very nice :)
As you can see drawImage doesn't accept any callbacks. Also canvas doesn't define any events about its drawing process. So you choice of timeout is correct. Only one thing you could possibly improve. Use setTimeout(..., 0) instead of setTimeout(..., 3000). More details about this trick here
I've found similar timing issues concerning IE 9 and drawing images to HTML5 cnavases discussed on stackoverflow, but none quite match mine.
I'm encountering an issue such that periodically the image's onload function is called, but it is still not ready to be drawn to a canvas. (The canvas remains blank). Within onload, the image's "complete" property is always true, and the "width" and "height" properties always contain the expected values. No exceptions are thrown. If I put a small delay in onload prior to drawing the image to the canvas, I never get a blank draw. I can also tie another attempt to draw the image to an event like a mouse click, and this is always successful. I do not observe this in Chrome or Firefox. I appreciate any insights. Thanks!
var canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
var context = canvas.getContext("2d");
var image = new Image();
image.onload = function()
{
// this.complete always true here
// A delay here seems to guarantee the draw will succeed
context.drawImage(this, 0, 0); // Half the time canvas remains blank after draw
// If the canvas is still blank, a later call to context.drawImage with this image will succeed
}
image.src = "some.png";
I don't see where you append the canvas to the body--is that intentional?
Anyway, try putting the createElement inside the onload
Does this make things consistently good?
var canvas;
var context;
var image = new Image();
image.onload = function()
{
canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
document.body.appendChild(canvas);
context = canvas.getContext("2d");
context.drawImage(this, 0, 0); // Half the time canvas remains blank after draw
}
image.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/city-q-c-640-480-6.jpg";