html5 canvas animate bezier curve endpoint - html

I want to animate the endpoint of a bezier curve to x,y coordinates in an html5 canvas without redrawing the entire stroke. Basically, I need to make the endpoint look as though it is draggable, and when dragged, affects the length of the line.
This is my current standard bezier stroke code:
var canvas = document.getElementById("myCanvas"),
context = canvas.getContext("2d"),
controlX1 = 140,
controlY1 = 10,
controlX2 = 388,
controlY2 = 10,
endX = 388,
endY = 170;
context.moveTo(188, 130);
context.bezierCurveTo(controlX1, controlY1, controlX2,
controlY2, endX, endY);
context.lineWidth = 10;
context.strokeStyle = "black";
context.stroke();
Does anyone have any ideas how this can be accomplished without using a library like Raphael; however, I am using jQuery, so that is an available resource.

without redrawing the entire stroke.
That's not possible. The way you animate things in HTML5 Canvas is by (clearing and) redrawing them.
library like Raphael
For the record, Raphael uses SVG, not HTML5 Canvas, and SVG makes this sort of thing much easier because it is a retained drawing surface.
Canvas is an immediate drawing surface. As soon as you draw something (like a curve) the canvas has no knowledge of what was drawn or where it is. You have to keep track of everything yourself. I feel like I parrot this a lot but I wrote a simple tutorial on learning to retain the necessary information to make canvas feel persistent like SVG that can be found here.
That being said, you might be better off using SVG (and not Canvas) if your planned app/site is not going to be very complex or intensive.

Related

As3 Actionscript drawing within the outlines

I am developing a coloring game using adobe air and as3. I have an image with black outline and the user can draw / color the image using a pen tool. I need help to figure out how can I restrict the user to draw within the outlines only. Masking the image with the line-graphics is something I have tried but it hangs the application. Any hint / suggestion towards the solution is appreciated.
following is the code on mouse_down event
_dot = new MovieClip();
_dot.graphics.lineStyle(lineSize, color);
_dot.graphics.moveTo(img.mouseX,img.mouseY);
img.addChild(_dot);
Let's say, the area you are drawing on is a DisplayObject with an instance name of Canvas. What you need is to check if the mouse is on Canvas or not.
In order to do so, you want to use the DisplayObject.hitTestPoint(...) method with the shapeFlag set to true (if it is false, it tests the point against the object's rectangle bounding box, which would produce the wrong results for any non-rectangular or rotated shapes).
So, you do as following:
var P:Point = new Point;
// First, convert coordinates to Stage coordinates,
// because the method requires so.
P.x = Canvas.mouseX;
P.y = Canvas.mouseY;
P = Canvas.localToGlobal(P);
// Now, test if the mouse is within the given canvas.
if (Canvas.hitTestPoint(P.x, P.y, true))
{
// The drawing should happen here.
}

AS3 3D-Renders slowly

Good time.
As you know,3d shapes in as3 are flat surfaces and we can make polyhedrons by moving and rotating that flat surfaces in the three dimensions.
BUT......
what about Non-Polyhedra shapes(spheres,cylinders)??
One way is to make surfaces using flat shapes.
An example to make a cylinder; you can copy this code to see what happens:
import flash.display.Sprite;
const angle:Number=Math.PI/180;
var numOfSides:uint=200;
//number of sides around
var pixWidth:uint=4;
//width and height of sides
var cldHeight:uint=20;
//height of cylinder
var s:Sprite=new Sprite();
s.graphics.beginFill(0xffffff*Math.random());
s.graphics.drawRect(0,0,pixWidth,pixWidth);
addChild(s);
this.cacheAsBitmap=true;
for(var n:uint=1;n<cldHeight;n++){
for(var i:uint=1;i<numOfSides;i++){
var prevS:Sprite=s;
s=new Sprite();
s.graphics.beginFill(0xffffff*Math.random());
s.graphics.drawRect(0,0,pixWidth,pixWidth);
s.x= prevS.x + Math.cos(-prevS.rotationY*angle)*s.width;
s.y=n*pixWidth;
s.z=prevS.z+Math.sin(-prevS.rotationY*angle)*s.width;
s.rotationY=-i*(360/numOfSides);
s.cacheAsBitmap=true;
addChild(s);
}
s=new Sprite();
}
and my problems:
Flash now renders EXTREMELY slow :-(
please improve this code or suggest a better one.
A few minor notes on the code:
Don't forget to end the fill when you're done(e.g. s.graphics.endFill() after the drawRect() call)
cacheAsBitmap works well for display objects without rotation applied if I can remember
4000 (200*20) Sprites with 3D transformations applied might push the display list a bit.
Remember to also sort the sprites
I recommend checking out these resources:
Flash & Math blog Icosahedron 3D tutorial
Senocular's exhaustive FP10 Drawing API article (using drawTriangles() would be more efficient since you'll have a single Sprite on the display list)
If you want to draw the vertices, it should be pretty fast to draw the 3D points projected to 2D on a bitmap
All of the above use Flash Player 10's features, but it might be much simpler to use a 3D API like Away3D which already provides easy ways to draw cylinders (with textures) at very high speeds(especially newer versions that use hardware acceleration)

Getting a bitmap of a spark window

I have an AIR application that I'm working on in which I would like to basically get a bitmap of what's going on in a separate spark window. The use case is a scaled preview of the spark window that will likely be on a projector to the main display. I want to pump the bitmap into a spark image as a source. Googling this doesn't seem to reveal much or I just don't what terms to google. Can anybody point me in the right direction? Anybody have a better way to accomplish this?
Thanks!
If you would like to make a bitmap of some DisplayObject, be it the whole window (stage) or just a Sprite, you should use the BitmapData's draw() method.
The following code will take a "screen shoot" of the whole stage, make a bitmap image of it and add it scaled to the top left corner:
var bd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
bd.draw(stage);
var bitmap:Bitmap = new Bitmap(bd);
bitmap.width = 300;
bitmap.scaleY = bitmap.scaleX;
addChild(bitmap);
It would benefit you to read more on Bitmap and BitmapData to utilize such features as:
Pixel snapping
Smoothing
Transparency
and others. For example smoothing is something that would make the image look better when scaled, but it counts as a filter and can be a performance hitter. That's why it would be better to apply smoothing on the bitmapdata when drawing (drawing scaled image is done with the matrix), not on a bitmap; but only when you don't plan to scale the image during runtime.
Hope that answers your question!

Canvas, negative coordinates: Is it bad to draw paths that start off canvas, and continue on?

I only want to show a portion of a shape drawn on a canvas.
My line is essentially this, and it works fine:
ctx.fillRect( xPosition, rectHeight - offsetV , rectWidth, rectHeight);
The second variable there is going to be negative. So, my quesiton is: is it bad practice (or am I setting myself for errors down the road) to draw a path that starts off the canvas (with a negative coordinate) and then continue drawing on to the canvas.
No problem at all. If you have very large number of drawing object you can (like GameAlchemist said) prevent drawing that object .If you use canvas like map for explore (zoom out/in ctx, translate whole context) that preventing draw can cost more that clip cost. And its complicated ...
I have some expire with drawing object out of canvas. You can have a problem if you put calculation and other (no drawing) staff intro draw function.
Important :
-Make canvas draw function code clear(only draw canvas code).
-If your app no need for const update make update call only when it needs.
-Clear canvas only in (0,0,canvas.w,canvas.h)
-Use style only when it needs (stroke,fill,font etc.)

<canvas> rect path - how?

I'm wondering how can I draw a path of a rect (like how I can using lineTo()).
I don't understand what the problem here is. Doesn't the rect method do exactly that?
It's worth noting that the rect() function is different from the strokeRect() and fillRect() functions. These two functions draw on the canvas immediately without the need for beginPath() or stroke()/fill() calls. For example this draws a rectangle on to the canvas:
context.fillStyle = 'red';
context.fillRect(5,5,100,100);