If I have ui elements in a canvas that I want to be clickable - what
is the best way to go about doing that? Do I need to create some kind
of collision detection to see if the mouse x,y is in a region? Or is
there some better way?
Hi,
Can anyone give me a function that returns the X/Y position of the
mouse pointer in relation to the canvas it;s over. I have one already
that seems to work regardless of how nested in DIVs it is. However if
it's nested in a TABLE it fails.
TIA.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.rgraph.org (Updated October 25th)
Let me put it this way: I recently noticed that the DOM TYPE constants from the DOM1 specification were missing in IE. I did some research into the issue and found a bug filed against IE8. In Microsoft's response, they admitted that it was a problem and a flaw in the standards support. Solution? Close the bug as "not going to make it" for IE8.
I will reiterate. Microsoft found it too difficult to add ~8 constant integers to the Element object in IE8. Something that would take only about 2 minutes to change, and no more than a half-hour to test.
With amazing standards support like that (DOM *ONE* for crying out loud!) I wouldn't hold out my hopes for Canvas support. Microsoft's recent participation on the HTML5 mailing lists is promising, but I fear they may be empty promises. If you want to see widespread Canvas support, continue evangelizing alternative browsers. Because there is no help coming from Redmond.
Jerason
On Sun, Oct 19, 2008 at 12:49 PM, Richard Heyes <richard.heyes@...> wrote:
Hi,
This is not a troll, even though it may distinctly smell like one. I'm
just interested in what people think about MSIE and canvas. For
instance, with it being in the HTML5 draft, do you think IE9 will
support it?
Hi,
This is not a troll, even though it may distinctly smell like one. I'm
just interested in what people think about MSIE and canvas. For
instance, with it being in the HTML5 draft, do you think IE9 will
support it?
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.rgraph.org
Hi,
No nothing to do with the forthcoming US election, but here's a short
article on the canvas tag. Doubtless I'll add to it as time goes on.
http://www.phpguru.org/static/canvas.html
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.rgraph.org
> Javascript's trig functions work in radians, not degrees
Ah, that explains a lot... :-)
> (as do most
> other programming languages and libraries). To convert from degrees to
> radians, multiply by Math.PI/180 (e.g. Math.sin(45 * Math.PI/180) in
> this case). More generally though, for this sort of thing it helps to
> get into the habit of 'thinking' in radians and using them
> consistently across your application rather than having to convert
> between radians and degrees...
Well it's a public API, and people recognise degrees. Most probably
don't even know what a radian is (radioactive?), so for said API, I
think I'll have to stick with convertiong to radians.
>
> - Matt
>
>
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
--- In canvas-developers@yahoogroups.com, "Richard Heyes"
<richard.heyes@...> wrote:
>
> Unfortunately the
> JS Math.sin function comes out differently tro my calculator
[...]
> Opposite = Math.sin(45) * 100
>
> Where 100 is the radius of the circle I'm drawing (for example) and 45
> is 45 degrees. I've just got to get it working... :-/
Javascript's trig functions work in radians, not degrees (as do most
other programming languages and libraries). To convert from degrees to
radians, multiply by Math.PI/180 (e.g. Math.sin(45 * Math.PI/180) in
this case). More generally though, for this sort of thing it helps to
get into the habit of 'thinking' in radians and using them
consistently across your application rather than having to convert
between radians and degrees...
- Matt
> Hm, I'm not sure why you need an arc() -- note that arc() doesn't
> actually draw anything, it just adds an arc to the current path.
> drawText ignores the current path (or should!). What you want is
> something like:
The translate method however needs coords to move to. I think it's
just some trig I need. And to get said trig working. Unfortunately the
JS Math.sin function comes out differently tro my calculator.
To recap, I'm trying to get horizontal text (ie readable) text at a
point but only knowing the angle in relation of the hypotenuse, and
the length of said line. So the equation would be:
Opposite = Math.sin(45) * 100
Where 100 is the radius of the circle I'm drawing (for example) and 45
is 45 degrees. I've just got to get it working... :-/
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
On Sep 28, 2008, at 9:25 AM, Richard Heyes wrote:
>> 1. Draw an arc using arc() (suprise) where the start and finish
>> angles
>> are the same. Thus no arc would be actually drawn, but (rather
>> handily) the pen is left at the end of the arc, giving a way to
>> specify radius and angle.
>>
>> 2. Draw the text.
>
> Actually scratch that, the drawText() method needs X/Y coords, so I
> would therefore need to know them as well. What would be nice is
> something analagous to ftell() that returns the X/Y coords.
Hm, I'm not sure why you need an arc() -- note that arc() doesn't
actually draw anything, it just adds an arc to the current path.
drawText ignores the current path (or should!). What you want is
something like:
// move to the start of the line where you want the text to appear
translate(50,50);
// rotate by the angle that you want the text to be drawn at
rotate(Math.PI / 4);
// draw the text
fillText("Hello World", 0, 0);
Or am I misunderstanding the effect that you're trying to achieve --
I'm assuming you're trying to get an angled line of text drawn?
- Vlad
> 1. Draw an arc using arc() (suprise) where the start and finish angles
> are the same. Thus no arc would be actually drawn, but (rather
> handily) the pen is left at the end of the arc, giving a way to
> specify radius and angle.
>
> 2. Draw the text.
Actually scratch that, the drawText() method needs X/Y coords, so I
would therefore need to know them as well. What would be nice is
something analagous to ftell() that returns the X/Y coords.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
Hi,
I'm using the CanvasText functions to render text but am trying to get
a function which fits the name DrawTextByAngle(). It's for a pie chart
for example. I could write one, but was wondering if anyone has
already written one (a better one no doubt)...?
I reckon the process would be something like:
1. Draw an arc using arc() (suprise) where the start and finish angles
are the same. Thus no arc would be actually drawn, but (rather
handily) the pen is left at the end of the arc, giving a way to
specify radius and angle.
2. Draw the text.
Caveats:
This process when stroked would end up with a line from 0,0 to the
start of the text (ie the arc) Not such a problem as long as you can
set the pen colour to the same as the background. But graduated
backgrounds become problematic. I already have a DrawLineByAngle()
function which uses this method.
Thanks.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
We are experimenting with using Canvas for a simple web base weather
product display application. I have upload a screenshot to our photos
section:
http://small-url.com/?67
As you can see (maybe), where the product image overlays the map
image, the map lines seemed to have been changed (sort of merged with
the product). I am using "destination-over", but it does not seem to
be leaving the destination "untouched". Here is some of the code (the
images and product display are 512x512):
//
// Draw the merged Maps
//
ctx.putImageData(maps.getMapImageData(), 0, 0);
//
// Draw the Product
//
ctx.globalCompositeOperation = 'destination-over';
ctx.drawImage(img, 0, 0, img.width, img.height,
0, 0, pd_width, pd_width);
Now one problem I had from the start is that the map images are a PNG,
but all the pixels get changed to transparent via canvas (they are not
transparent in the PNG file). I wrote some stupid code to get around
this (imgd is an ImageData object):
//***********************************************************
//
function pfixTransparency(imgd) {
//
//***********************************************************
//
// A stupid workaround for a problem I do not understand.
// Certain images seems to get the alpha bit set to zero.
// I do not know why, but we must set it back to 255.
//
for (var i=0; i<imgd.width*imgd.height; i++) {
imgd.data[i*4+3] = 255;
}
}
this.fixTransparency = pfixTransparency;
Any ideas?
Hi,
> I think the key to understanding it is realising that scale(),
> rotate(), translate() and transform() change the coordinate system (so
> that, for example, the point (0,0) becomes somewhere else besides the
> top-left corner) - NOT the current pen position or the appearance of
> anything that's been drawn already. It's the coordinate system that is
> being remembered by save() and restore() (along with some other bits
> and pieces like fill style).
Now that helps. I think based on that, I don't imagine I'd need too
much, if at all.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
--- In canvas-developers@yahoogroups.com, "Richard Heyes"
<richard.heyes@...> wrote:
>
> > ...
>
> Well, thank you. Still don't "get" it. Fortunately I haven't needed
> save() or restore() yet. Mind you, I wouldn't would I... :-)
I think the key to understanding it is realising that scale(),
rotate(), translate() and transform() change the coordinate system (so
that, for example, the point (0,0) becomes somewhere else besides the
top-left corner) - NOT the current pen position or the appearance of
anything that's been drawn already. It's the coordinate system that is
being remembered by save() and restore() (along with some other bits
and pieces like fill style).
> ...
Well, thank you. Still don't "get" it. Fortunately I haven't needed
save() or restore() yet. Mind you, I wouldn't would I... :-)
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
On Sep 24, 2008, at 11:29 AM, Jerason Banes wrote:
So what you're saying is that the path is not affected by the transform matrix until it is restarted? So simply transforming it will not have the desired effect without calling beginPath()? That appears to be how it tests. Your code above + a lineTo() does indeed draw between (0,0)-(100,100).
Each point/coordinate added to the path is affected by the current transformation matrix at the time that it's added; the matrix is never applied to the entire path itself. For example:
moveTo(0,0);
translate(100,0);
lineTo(0,0);
translate(0, 100);
lineTo(0,0);
translate(-100, 0);
lineTo(0,0);
translate(0, -100);
lineTo(0,0);
fill();
Would draw a rectangle. beginPath() by itself just clears the path and the current point; it doesn't interact with the CTM.
In which case, the proper code that Mr. Hayes is looking for would be:
canvas = document.getElementById("myc");
context = canvas.getContext('2d');
// Save the current state
context.save();
// Now go draw something
context.translate(100,100);
context.beginPath();
context.moveTo(0,0);
context.arc(0,0,10,0,6.28, false);
context.fill();
// End up back at 0,0 ? Apparently not...
context.restore();
context.beginPath();
context.moveTo(0,0);
context.lineTo(300,300);
context.stroke();
Correct?
Yep, that looks right -- the first beginPath() there isn't strictly necessary in that snippet, but it's a good idea anyway since then you don't depend on there being no current point going into that block.
(No idea why Mail.app generates strikethroughts in quoted code samples -- sorry if that's showing up for anyone else!)
// current point is still (0,0); -- if at this point you did a lineTo(0,0); you'd end up with a line from 0,0 to 100,100.
So what you're saying is that the path is not affected by the transform matrix until it is restarted? So simply transforming it will not have the desired effect without calling beginPath()? That appears to be how it tests. Your code above + a lineTo() does indeed draw between (0,0)-(100,100). Restarting the path like this...
context.save();
context.translate(100,100);
context.beginPath();
context.moveTo(0,0);
context.lineTo(50,50);
context.stroke();
context.restore();
...appears to give the expected result of (100,100)-(150,150).
In which case, the proper code that Mr. Hayes is looking for would be:
On Sep 24, 2008, at 10:08 AM, Jerason Banes wrote:
Ok, that's bizarre. Your code actually works in WebKit! (It's not supposed to do that. :P)
Your problem is that you're using the pen state via moveTo. The state of the pen is not saved. What you want is to move the transformation matrix like this:
canvas = document.getElementById("myc");
context = canvas.getContext('2d');
//Set the default pen location
context.moveTo(0,0);
// Save the current state
context.save();
// Now go draw something
context.translate(100,100);
context.arc(0,0,10,0,6.28, false);
context.fill();
// End up back at 0,0 ? Yup.
context.restore();
context.lineTo(300,300);
context.stroke();
Note that FireFox appears to have some odd bugs in its pen handling. If you don't set a location for the pen, it will default to the last point that was drawn at. Which appears to be 100,100 after the translate. That's why I added the moveTo(0, 0) at the top.
Hmm... not quite :)
At context creation, there is no "current point"; all the various path functions do specific things if there is no current point (which is the state you get to if you call beginPath). Specifically: moveTo just sets the current point; lineTo will act as a moveTo if there is no current point, and the arc functions will add a line from the current point to the start of the arc (if there is no current point, then no line will be added). Also, the current point is not affected by save/restore, and all path operations have the transform immediately applied to them. So here's what's happening in the above snippet:
moveTo(0,0);
// current point is now (0,0);
save();
translate(100,100);
// current point is still (0,0); -- if at this point you did a lineTo(0,0); you'd end up with a line from 0,0 to 100,100.
arc(0,0, 10, 0, 2*Math.PI, false);
// arc() draws a circle at 100,100 of radius 10.
// But there is already a current point, because of the original moveTo() -- so arc() adds a line from the current point to the start of the arc.
// After the arc(), the current point is at the end of the arc that was drawn -- a point at the right side of the circle, which in this case is 110,100 (same as the start of the arc)
fill();
// the current path (which is line + circle) is filled, but the line doesn't show up because it's just a line.. so only the circle is visible. Change this to a stroke() to see the line.
restore();
// The current point now is not 0,0, but is still the right point of the circle. The first line and circle are still part of the path, since beginPath wasn't called.
lineTo(300,300);
// A line is added from the rightmost point of the arc (110,100) to 300,300
stroke();
// Everything is stroked -- the line from 0,0 to the start of the circle, the circle, and the line from the end of the circle to 300,300.
The line that's visible at the end of the snippet is not a line from 0,0 to 300,300 -- if you draw a separate line from 0,0 to 300,300 you can see that they don't line up; the line from 0,0 to 300,300 would pass right through the circle, whereas the one that the snippet draws goes to 110,100 and then bends slightly back to get to 300,300.
Note that currently released versions of Safari have some differences in the handling of the current point... WebKit nightlies produce the same output as Firefox 3.
Ok, that's bizarre. Your code actually works in WebKit! (It's not supposed to do that. :P)
Your problem is that you're using the pen state via moveTo. The state of the pen is not saved. What you want is to move the transformation matrix like this:
canvas = document.getElementById("myc");
context = canvas.getContext('2d');
//Set the default pen location
context.moveTo(0,0);
// Save the current state
context.save();
// Now go draw something
context.translate(100,100);
context.arc(0,0,10,0,6.28, false);
context.fill();
// End up back at 0,0 ? Yup.
context.restore();
context.lineTo(300,300);
context.stroke();
Note that FireFox appears to have some odd bugs in its pen handling. If you don't set a location for the pen, it will default to the last point that was drawn at. Which appears to be 100,100 after the translate. That's why I added the moveTo(0, 0) at the top.
Thanks!
Jerason Banes
On Wed, Sep 24, 2008 at 11:54 AM, Richard Heyes <richard.heyes@...> wrote:
Hi,
Apparently I didn't quite get it - I made an example here:
1. We're at 0,0
2. Save the current state
3. Do some stuff, ie move to 100,100 and draw a circle and fill it.
4. Call restore(). As I understand this will move us back to 0,0
5. It doesn't.
When the line is drawn I would have expected it to come from 0,0, ie
the position at which save() was called, but it doesn't. It comes from
where it finished drawing the circle. What am I doing wrong? Or have I
completely misunderstood?
--- In canvas-developers@yahoogroups.com, "Richard Heyes"
<richard.heyes@...> wrote:
>
> Hi,
>
> Apparently I didn't quite get it - I made an example here:
>
> http://www.phpguru.org/RGraph_dev/examples/text.html
>
> My understanding is this:
>
> 1. We're at 0,0
> 2. Save the current state
> 3. Do some stuff, ie move to 100,100 and draw a circle and fill it.
> 4. Call restore(). As I understand this will move us back to 0,0
> 5. It doesn't.
>
> When the line is drawn I would have expected it to come from 0,0, ie
> the position at which save() was called, but it doesn't. It comes from
> where it finished drawing the circle. What am I doing wrong? Or have I
> completely misunderstood?
>
> Thanks!
>
> --
> Richard Heyes
>
> HTML5 Graphing for FF, Chrome, Opera and Safari:
> http://www.phpguru.org/RGraph
>
I think, it depends on if you are asking about path or position.
According to
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas.html#the-\
canvas.
"The current path and the current bitmap are not part of the drawing
state. The current path is persistent, and can only be reset using the
beginPath() method. "
Positions. or transforms, are part of the state and therefore restored.
Hi,
Apparently I didn't quite get it - I made an example here:
http://www.phpguru.org/RGraph_dev/examples/text.html
My understanding is this:
1. We're at 0,0
2. Save the current state
3. Do some stuff, ie move to 100,100 and draw a circle and fill it.
4. Call restore(). As I understand this will move us back to 0,0
5. It doesn't.
When the line is drawn I would have expected it to come from 0,0, ie
the position at which save() was called, but it doesn't. It comes from
where it finished drawing the circle. What am I doing wrong? Or have I
completely misunderstood?
Thanks!
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
> no, restore doesn't erase the drawing. it acts over the context, allowing
> you to save, plot a pink line, restore and back drawing black lines again.
Great, thank you.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
On Tue, Sep 23, 2008 at 4:59 PM, Richard Heyes <richard.heyes@...> wrote:
> if I draw some stuff, but don't call
> stroke() to apply it to the canvas, then save(), do some stuff, call
> restore(), would that undrawn stuff still be there?
save() and restore() do not affect the path at all. So if you do
ctx.rect(...);
ctx.save();
ctx.beginPath();
ctx.restore();
ctx.stroke();
then the rectangle will not be drawn, because beginPath() blows away
the current path and restore() does not restore the path.
HTML 5
(http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas.html#the\
-canvas0
- "The canvas state") defines exactly what is affected by
save()/restore(), and says "Note: The current path and the current
bitmap are not part of the drawing state. The current path is
persistent, and can only be reset using the beginPath() method. The
current bitmap is a property of the canvas, not the context."
--
Philip Taylor
excors@...
It helps a lot thanks. So if I draw some stuff, but don't call
stroke() to apply it to the canvas, then save(), do some stuff, call
restore(), would that undrawn stuff still be there?
> I hope that answers your question?
It helps a lot thanks. So if I draw some stuff, but don't call
stroke() to apply it to the canvas, then save(), do some stuff, call
restore(), would that undrawn stuff still be there?
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
If you're familiar with OpenGL, then these are the same thing as pushing the transformation matrix (i.e. the state) onto the stack with that API. If you're not familiar with OpenGL, here's the quick rundown.
The Canvas API has several destructive APIs that change how pixels are plotted. For example, scale, transform, translate, and rotate have consequences for all drawing operations. If you only want to use those operations for part of the drawing, it can be a pain to first make changes to the drawing context's state, then have to do some fancy calculations to revert that state.
The solution is a stack-based system that stores the current transform matrix. When you call save(), everything from the current drawing color to the current scaling factor is stored on a stack. You can then make changes to the rendering context and perform your drawing operations. When you are done with your operations, you can call restore() to pull the last save off the stack and get back to the drawing state you were at when you called save().
Since save() and restore() are stack-based (rather than only holding one value), you can save and restore multiple times. For example:
ctx.save(); //Save the default state
ctx.translate(100, 100); //Move the drawing 100 pixels in from the edge
ctx.drawImage(character, 0, 0); // Draw a character at 100,100
ctx.save(); //Save our 100,100 translate
ctx.scale(4.0, 4.0); //Makes our image 4x its original size
ctx.drawImage(bigmonster, 100, 0); //Draws a monster at 400,100
ctx.restore(); //Undo our scale(4.0, 4.0);
ctx.drawImage(bullet, 20, 0); //Draw a bullet at 120,0... pew pew pew!
ctx.restore(); //Undo the translate(100, 100)
I hope that answers your question?
Thanks!
Jerason Banes
On Tue, Sep 23, 2008 at 5:24 AM, Richard Heyes <richard.heyes@...> wrote:
Hi,
Can someone explain the save() and restore() functions?
Hi,
Can someone explain the save() and restore() functions?
Thanks.
--
Richard Heyes
HTML5 Graphing for FF, Chrome, Opera and Safari:
http://www.phpguru.org/RGraph
On Thu, Sep 18, 2008 at 1:55 PM, Richard Heyes <richard.heyes@...> wrote:
> Anyone have an example of MooCanvas that works? I have a bare bones
> example that doesn't appear to be working:
>
> http://www.phpguru.org/moo/test.html
Moocanvas requires a doctype and UTF-8 encoding:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
...
Firebug is showing an error in your test case: $("startExample") is null.
$("startExample") is the same as
document.getElementById('startExample'), so you are missing an element
with id, startExample.
There are quite a few test case examples here:
http://ibolmo.com/projects/moocanvas/demos/tests.php
Also, just to keep in mind, Excanvas automatically replaces canvas
tags in the page but has to have the canvas elements initialized if
they are created dynamically. Moocanvas works just the opposite. If a
canvas tag is in the page already you have to replace it and new
canvas tags are already initialized.
I haven't ever used the new Canvas class. Instead I create new canvases with:
myCanvas = new Element('canvas', {
'id': 'myCanvas',
'width': 100,
'height': 100
}).inject(document.body);
G.
On Thu, Sep 18, 2008 at 1:55 PM, Richard Heyes <richard.heyes@...> wrote:
> Hi,
>
> Anyone have an example of MooCanvas that works? I have a bare bones
> example that doesn't appear to be working:
>
> http://www.phpguru.org/moo/test.html
>
> Thanks.
>
> --
> Richard Heyes
>
> HTML5 Graphing for IE7, FF, Chrome, Opera and Safari:
> http://www.phpguru.org/RGraph
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>