I need a little help from you. I have created a canvas image using excanvas.js and it was rendered properly. Now i want to use that same canvas to draw another image but before that i need to clear that same canvas otherwise images will be overlapped over each other.
Can anyone please explain how can i call fillRect() or any another method from excanvas.js for the same canvas element ?? I am using IE 8 as browser.
ctx.clearRect(0, 0, excanvas.width, excanvas.height);
or perhaps:
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, excanvas.width, excanvas.height);
Where excanvas is your DOMElement canvas, and ctx being its 2d context (via getContext('2d')).
Related
When I run this code it produces the lines "rotating" from 0 degrees to 180, the problem is the previous line does not get cleared (so the ctx.clearRect(0,0,400,200) does not work. In the console log it shows up as running (when I try to debug) but it is not actually clearing it. Does anyone have any idea how to fix this?
var canvas = document.getElementById("radarImage");
var ctx = canvas.getContext("2d");
var angle = 0
function incrementAngle(){
angle++;
if(angle>180){
angle=0;
}
}
function rotateRadar(){
incrementAngle();
ctx.clearRect(0,0,400,200);
ctx.save();
ctx..translate(-200,-200);
ctx.rotate((Math.PI/180)*angle);
ctx.translate(-200,-200);
ctx.moveTo(200,200);
ctx.lineTo(0,200);
ctx.stroke();
ctx.restore;
}
setInterval(rotateRadar,200);
Edit: You should call your updates constantly using request animation frame: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
If you are open to using a library for working with canvas then easel js is could be a possibility: http://www.createjs.com/easeljs
Another SO user asked a similar question for Easel Js and there are some good answers that may be relavant to you: EaselJS - Rotate a shape around its center
Simply you cant rotate a line cont in canvas, you have to read sin,cos to rotate a line in canvas.
Hope this should help you.JsFiddle
context.clearRect(0,0,400,200);
context.beginPath();
context.moveTo(x,y);
x1=Math.cos(startAngle)*radius+10;
y1=Math.sin(startAngle)*radius+10;
console.log(x1,y1);
context.lineTo(x1,y1);
context.stroke();
Regardless of the javascript, is there a performance problem when adding multiple html5 canvas elements for the purpose of displaying canvas made icon? I mean is there a difference performancewise between a div and canvas sematic element?
I am trying to step away from images, svg and even fontawesome, thats why im asking.
Based on the request, I have this short code:
var canvas = document.createElement("canvas");
canvas.width = 250;
canvas.height = 80;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, 250, 80);
//draw a red box
ctx.fillStyle = "#FF0000";
ctx.font = "30px Tahoma";
ctx.fillText("Hello World", 45, 50);
var dataURL = canvas.toDataURL();
document.getElementById("img-data").innerHTML = dataURL;
document.getElementById("canvas-mirror").src = dataURL;
<div id="img-data"></div>
<img id="canvas-mirror"></div>
In short,
Create canvas element with javascript. You don't have to include it into html, why would you? This way it might be a little bit faster.
Use canvas.getContext 2d, WebGL or whatever you want to do. This is essential, once you choose method, you shouldnt change it! (Dont use it twice on same canvas.)
Draw anything you want.
Get data from canvas back. Now the most known way is to use "high level" method toDataUrl. This is good and easy to do. But in case of more complicated application, you might choose also different methods, for example webgl has readPixels which is faster, like really fast, you get smaller data and you can also use scissors before, but it is also much harder to code.
Use data for image. In case of base64 it is valid param for img src property. WebGL readPixels must be transformed first. It might be binary blob or base64.
Yes,
Performance depends on the total area of all canvases, try to keep it( total area of canvas) small.
If you are planning to use canvas then try to use clipping option , it will increase performance.
I'm having a bit of trouble here to develop this functionality since it must work on IE9+ so css clip-path is not an option ( http://caniuse.com/#feat=css-clip-path ).
The issue:
I need to create a grid composed of 6 elements.
Each element is an image.
The images can be different according to user answers before getting to the grid page.
Eeach element / image must be clicable and will acquire a "selected" class that will overlay div with text and background image.
image:
What is the best way to achieve this?
One way to do this could be to save out each combination of the six images you require into one big image. Then, depending on the user's answer combination, you insert the corresponding image as a background-image of a div. You then overlay click-able hotspots within the same div that roughly correlate to the dividing edges.
This may however not be the most practical solution and largely depends on how many answers/images you are dealing with.
Alternatively you could draw SVG shapes and set their fills to the images you require.
I can recommend Raphael.js as a starting point. You should be able to find what you need in the documentation
Another option would be to use HTML5 canvas:
http://jsfiddle.net/julienbidoret/GKP7X/1/
(credit goes to julienbidoret for the jsfiddle)
Javascript:
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function () {
ctx.save();
ctx.beginPath();
ctx.moveTo(20, 0);
ctx.lineTo(240, 0);
ctx.lineTo(220, 240);
ctx.lineTo(0, 240);
ctx.closePath();
ctx.clip();
ctx.drawImage(img, 0, 0);
ctx.restore();
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/2/2b/Clouds.JPG";
HTML:
<canvas id="c" width="300" height="300" ></canvas>
Both SVG and canvas are supported in IE9.
In putting together a small canvas app I've stumbled across a weird behavior that only seems to occur in the default browser in Android.
When drawing to a canvas that has the globalCompositeOperation set to 'destination-out' to act as the 'eraser' tool, Android browser sometimes acts as expected, sometimes does not update the pixels in the canvas at all.
the setup:
context.clearRect(0,0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.globalCompositeOperation = 'destination-out';
draw a circle to erase pixels from the canvas:
context.fillStyle = '#FFFFFF';
context.beginPath();
context.arc(x,y,25,0,TWO_PI,true);
context.fill();
context.closePath();
a small demo to illustrate the issue can be seen here:
http://gumbojuice.com/files/source-out/
and the javascript is here:
http://gumbojuice.com/files/source-out/js/main.js
this has been tested in multiple desktop and mobile browsers and behaves as expected. On Android native browser after refreshing the page sometimes it works, sometimes nothing happens.
I've seen other hacks that move the canvas by a pixel in order to force a redraw but this is not an ideal solution..
Thanks all.
I did something like this, which forces the detachment of the canvas:
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (isStockAndroid) {
canvas.style.display = "none";
canvas.offsetHeight;
canvas.style.display = "block";
}
That seems to be the most efficient as far as FPS is concerned. Otherwise it's the not-so-nice:
canvas.width = canvas.width;
...which seemed to also get it all working normally for me. Haven't tested to see if the first is essentially the same as the second and resets canvas settings, though, but it seems to be getting a higher frame rate? Anyway that definitely clears things. For the native detection stuff try here: How to detect only the native Android browser
Assuming that I have a WebGL canvas (by calling getContext("experimental-webgl")).
Is there any way to switch context later for using a "2d" one ?
The goal of such thing would be to display a debug BSOD-like when an error happening during rendering.
If it's not possible, then :
Can I embed an html element over a canvas, and force this element to have exactly the same same that the canvas (even if this last is resized) ?
Can I replace an dom node, and update every reference about the old one to reflect the changement ?
[edit] This is my current minimal call code. Canvas is a DOM node containing a canvas which is filled by WebGL API, and callback is a function which process a single frame.
function failure(cvs, e) {
var ctx = cvs.getContext('2d'); // Fail here, returns `null' if cvs.getContext('webgl') has been called
ctx.fillStyle = 'rgb(0, 0, 0)';
ctx.fillRect(0, 0, cvs.width, cvs.height);
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.font = 'bold 12px sans-serif';
ctx.fillText(e.toString(), 0, 0);
}
function foobar(canvas, callback) {
try {
callback();
} catch (e) {
failure(canvas, e);
throw e;
} finally {
requestAnimationFrame(arguments.callee);
}
}
The short answer is pretty much no, according to the spec.
Every canvas has what is called a primary context. This is the first context that is invoked on a canvas. Making a non-primary context on a canvas might do some things on different browsers but I would never, ever depend on it.
I would instead have a second canvas that is overlaid over the first and maintains the same width and height attributes. I would then hide one and unhide the other (or just unhide the 2D one when you want it seen).
OR just use a PNG for simplicity's sake., centered inside of a DIV that also holds the canvas. In other words:
Div container has black background and holds:
PNG (centered)
3D Canvas
Then when you want the error png to be displayed you just hide the 3D canvas (and optionally unhide the PNG)
Rather than have two canvases overlaying, the solution I went with was to replace the existing canvas with a clone of itself.
var newCvs = cvs.cloneNode(false);
cvs.parentNode.replaceChild(newCvs, cvs);
cvs = newCvs;
All the properties of the original canvas will be retained but the context will be freed up to allocate as you wish.