i'm making an application that draws curves with as3 and i ant the curves to highlight when the mouse is over.
I managed to do it with mouseOver, but the interaction is not natural because you have to be exactly on the curve (1px wide) to highlight it. So i was wondering if it was possible to have some sort of 'tolerance' on the mouseOver behaviour.
I know i could use a enterFrame event and check there the distance between the curve and the cursor, but it seems to me it will be a lot of calculations for such a simple task.
thanks.
ps: my curves are not real curves (like bezier), but a succession of lineTo commands.
There is no tolerance in mouse_over, so the quickest solution that I can imagine is to draw thicker line with alpha set to 0, and then addEventListener to that thicker invisible line.
Related
By default, adding a Stroke to a Shape in WPF / WinRT XAML creates an outline that is centered around the edges, meaning that half of the outline is outside the shape. But I need to create a shape with stroke und no fill that has the same silhouette as the shape with fill and no stroke. Is there an easy way to change the stroke so that the whole outline is inside?
I could create an OpacityMask that covers the inverted shape, but OpacityMasks are not supported in WinRT XAML. I could also create a smaller shape via inward polygon buffering (An algorithm for inflating/deflating (offsetting, buffering) polygons), but I was hoping for a simpler solution, e.g. a simple property to change the stroke to "inside".
I've really been trying to come up with an answer to this one. Over and over every attempt has some type of limitation. I'm afraid the answer is, you cannot do this - not with dynamic vectors at least. You can always create an image to simulate it. But that sucks.
I know it is not possible to add eventhandlers to specific circles or rectangles in canvas. But there are some nice frameworks like EaselJS, KineticJS, Paper.js, Fabric.js that support the eventhandling on specific elements.
Can someone explain me how do they work?
I think there are only two solutions.
1. You create for each element a new canvas region and put them on each other. In this way you can give each region an event handler.
2. You have only one canvas region and one event handler. In this way you have to do complex mathematical calculations to find out if a specific element was clicked. If you have only circles or rectangles, this solution might be easy. But if you have path with lots of curves, this solution is quite difficult.
I don't want to use the libraries. So it would be nice, if someone can help me.
Here's a BRIEF summary of how canvas drawing libraries work
An unaltered canvas is just a big bitmap. Once you draw shapes on the canvas, they are unaccessible, forgotten pixels.
Canvas drawing libraries store all your shapes into “retained” objects. Each shape object has sufficient information about itself to allow the drawing library to redraw it whenever necessary.
The canvas drawing libraries are the "controllers" for objects. The libraries have the algorithms necessary to track, manipulate and redraw all shape objects as necessary.
The following information is retained about every shape object:
Basic identification
ID,
Shape name
Parent or Container
Inherent properties of the shape:
Rectangular shapes( rect, image, text) know width and height.
Circular shapes (circles, elipses, regular polygons, stars) know radius and sidecount.
Lines know length.
Curved shapes (arcs, beziers, paths) know anchor points and control points.
Text also knows…well, the text!
Images also know their pixel data (usually stored in javascript Image objects)
Transformational information:
Starting X/Y coordinate
Translations—accumulated movements off the starting coordinate.
Rotations—accumulated rotations of this shape (usually in radians).
Scalings—accumulated resizings
Other transforms (less common) are skews and warps
Layering information—the current z-index
Styling information:
StrokeColor,
StrokeWidth,
FillColor,
Opacity,
isVisible,
lineCaps,
cornerRadius
Tracking abilities:
Bounding box—the smallest rectangle that completely contains this shape
This is used for “hit testing” to see if the mouse is inside this object (for selecting and dragging)
If you don't want to use a library, you may find my answer in this thread helpful. As markE says once the canvas is written to there is no way of tracking that data (unless you care to loop through each individual pixel and test its colour; though that is only really useful for pixel level collision detection).
I am working on a jigsaw-like game in as3 where irregularly shaped layers imported from photoshop are used to mask parts of their original background.
By setting cacheAsBitmap=true on the mask and its contents the result is a nice irregular shape with its transparent bounding portions left out.
However the invisible bounding areas are still detected at MOUSE_DOWN. I would prefer the mouse not be detected anywhere but on the visible masked part. At the moment I cannot detect the mouse on any other clips on the stage that might appear behind the overlapping transparent areas.
I have seen a solution here involving bitmap pixel detection which I have not found a way to apply as a solution. The contents of my masked areas are either shapes or MovieClips.
I hope someone can help me find a solution
The simplest and the most stable approach to prevent the mouse events on the transparent area of bitmap graphics is to create a separate vector shape as the target for mouse and set the mouseEnabled flag to false to the bitmap or set hitArea property to this shape.
You can create such shape manually in the Flash IDE for the tests and even for the production. Sometimes it's more suitable to write the bitmap tracert script that creates contour shape in runtime by checking the pixel transparency.
Im starting on some simple-to-complex canvas scripting. I want to draw a circle. That's easy. The problem is the circle is drawn right away. What if I wanted the circle to slowly grow (lets say from a vertical line, to a semi circle, to a half circle, to a full circle) Is there any way in canvas to do this (natively) or do I need to make a function that builds and deletes several circles (quickly) to simulate the effect?
If the latter is true, is there any sort of performance hits I should be looking out for?
Thank you!
Any form of animation using canvas requires the canvas to be cleared and the next drawing in the sequence to be made. The Mozilla Development Network has a good tutorial on canvas and canvas animations.
Check out the animate.js library. Its is exactly what you need. Usage is same as jQueryUI.
What you need can be done by the following piece of code:
canvas_element.animateCircle(x,y,r);
There are other optional parameters like animateCircle(x,y,r,{'lineWidth':5, 'lineColour':'red', 'stop': function() {alert('completed');}}) & some other functions. Check the Readme file for details.
I am implementing free drawing with HTML5 canvas. Currently every thing is working fine. I am using moveTo() and lineTo() for every mousemove. I have to fine tune the drawing;
when I draw some curve like lines with rapid movements, the drawing will be drawn like joints of straight lines. Is there any alternative way for drawing, to make the drawing smoother?
I dont think there is a better way for the drawing itself, however, if you put the draw functions directly onto the mouse move event handlers, then that would slow it down,
To speed that up you could just save the coordinates in an array in the event handlers and wait for the mouse to stop moving before walking trough the array and drawing.
The advantage would be that the events are called more reapidly, making smoother curves, the disadvantge would be that there is a 'lag' if you move the mouse alot.
An alternative would be to try and detect when the user curves and use the appropiate curve drawing method.
I actually did the same thing:
ctx.beginPath();
ctx.moveTo(lp.x-.5, lp.y-.5); // Last recorded position.
ctx.lineTo(cp.x-.5, cp.y-.5); // Current position at time of call.
ctx.stroke();
Bezier Curves are great for pen-like (paths) functionality, but I've ended up with unintended results with that as well, namely the curve between P0 and P2 being too distant from P1... This can be handled by adding extra points against which to evaluate the function (taking it to higher degrees, which seems to be how adobe does it).
I've spent two days answering this question, doing a lot of research of the best examples, tearing through code where available. There are essentially two responses:
1.) Apply a filter – a box- or gaussian- blur will smooth the rough edges a little, making it look less angular.
2.) Apply a Bezier Curve – Between the mousedown and mouseup events, log an array of the points and apply the curve. The longer the line, the slower the re-rendering.(Muro - deviantArt's canvas app appears to do this). [NB: If the idea is to create an artistic web app for people to draw on, show them the original line until the smooth rendering is complete.]
I like somewhere in between, personally. A slight blur tends to soften things, especially near corners, and makes slowly placed (thus frequent, shorter lines) much softer).
Something I'll add, which may be completely obvious so I apologize: Make sure you've set your cap style to 'round' –– ctx.lineCap = 'round'