How To Add Movements To Bezier Curve In Kineticjs?
Solution 1:
Problem:
You are adding 9 additional Shape objects with every stage mousemove event.
That means you quickly create hundreds (thousands) of hairs.
Start with a redesign where you have only 9 hairs.
During mousemove events, you would respond by changing each hair's bend in their drawFunc
.
[ Edited to include example code ]
You can create a “smart” hair that listens if the mouse is over it and bends itself accordingly.
Then you can add as many smart hairs as you need.
You don't need to track what they're doing, because each one contains enough info+code to bend itself properly.
Since this is just an instructional example, I’ve simplified your curves into a 2 part line which is vertical at the bottom and “bent” at the top.
Here’s the draw function for the custom hair shape. The top of the line is “bent” towards the mouse position. If the mouse has moved inside the hairs response area, the hairs endX property will be set to the mouseX position. This causes the hair to be bent towards the mouseX.
drawFunc: function(canvas){
if(mouseX>=this.attrs.respondLeft && mouseX<=this.attrs.respondRight){
this.attrs.endX=mouseX;
}
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.startX,this.attrs.bottomY);
context.lineTo(this.attrs.startX,this.attrs.midY);
context.lineTo(this.attrs.endX,this.attrs.topY);
canvas.fillStroke(this);
},
Since we want the hair to bend itself as the mouse moves over it, we add a mousemove event handler for the stage. When the mouse moves the mouseX position is updated. When the hair is redrawn, it will be bent to the mouseX.
stage.on('mousemove', function() {
// set the endX where the hair will bend to
mouseX=stage.getMousePosition().x;
// redraw the layer
layer.draw();
});
The working code below is a little more complicated because each hair stores its own info about how to draw itself and about its hit area.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/ey38w/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var mouseX;
var hair1=addHair(100,200,20,150);
var hair2=addHair(120,200,20,150);
var hair3=addHair(140,200,20,150);
layer.draw();
function addHair(x,y,width,height){
var shape=new Kinetic.Shape({
drawFunc: function(canvas){
if(mouseX>=this.attrs.respondLeft && mouseX<=this.attrs.respondRight){
this.attrs.endX=mouseX;
}
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.startX,this.attrs.bottomY);
context.lineTo(this.attrs.startX,this.attrs.midY);
context.lineTo(this.attrs.endX,this.attrs.topY);
canvas.fillStroke(this);
},
lineJoin: 'round',
stroke: 'grey',
strokeWidth: 12,
respondWidth:width,
respondLeft:x-width/2,
respondRight:x+width/2,
respondHeight:height,
respondTop:y-100,
topY:y-100,
midY:y-50,
bottomY:y,
startX:x,
endX:x
});
layer.add(shape);
return(shape);
}
// "bend" when mouse is inside any hairs hit boundaries
stage.on('mousemove', function() {
// set the endX where the hair will bend to
mouseX=stage.getMousePosition().x;
layer.draw();
});
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
[Additional words of encouragement]
This pattern will work for you.
Yes…even for your bezier curves.
But this is just a starting point that you must adjust for your own project.
For example, in your original code you went through these steps
- Listen for mousemove events and handle them (your moving function),
- Determine if the mouse position should affect your hairs,
- If so, recalculate the control+end points (your init function).
- Redraw the hairs (only now you know to just redraw the existing hairs--not create new ones),
So modify these code pieces into this pattern!
No, you can't just cut-and-paste. You will have to modify, improve, adapt.
To start, get 1 Bezier hair working the way you like.
Then--not before, take this hint:
Instead of having a separate Kinetic Shape for each hair, create one Shape object and draw all you hairs in its drawFunc. This is more performant. Also, then you can listen for mousemove on that one shape instead of the whole canvas. Again, more performant.
Above all—Learn!: (1)Experiment (2)Test, (3)Adapt, (4)Don't Give Up, (5)Repeat at#1.
Solution 2:
KineticJS now supports Spline tweening, which means that you can easily animate the points along a curve. Check out this example:
http://www.html5canvastutorials.com/labs/html5-canvas-animated-clown-face/
Post a Comment for "How To Add Movements To Bezier Curve In Kineticjs?"