I have made a Bezier Shape in kinetic js with control points on it vertices. the code allows the user to drag the starting, ending and control points thereby modifying the shape of the curve like shown below.
The link to the js fiddle containing the above code is http://jsfiddle.net/Lucy1/da90vct4/2/
Code for the anchor points is
var room = new Kinetic.Shape({
x: 0,
y: 0,
width: 100,
height: 100,
stroke: "black",
fill: 'ivory',
drawFunc: function (context) {
var x = this.x();
var y = this.y();
var w = this.width();
var h = this.height();
var trX = anchorTR.x();
var trY = anchorTR.y();
var brX = anchorBR.x();
var brY = anchorBR.y();
var blX = anchorBL.x();
var blY = anchorBL.y();
var tlX = anchorTL.x();
var tlY = anchorTL.y();
context.beginPath();
context.moveTo(tlX, tlY);
// top
context.bezierCurveTo(x + w / 3, y, x + w * 2 / 3, y, trX, trY);
// right
context.bezierCurveTo(x + w, y + h / 3, x + w, y + h * 2 / 3, brX, brY);
// bottom
context.bezierCurveTo(x + w * 2 / 3, y + h, x + w / 3, y + h, blX, blY);
// left
context.bezierCurveTo(x, y + h * 2 / 3, x, y + h / 3, tlX, tlY);
context.closePath();
context.fillStrokeShape(this);
}
});
g.add(room);
var anchorTR = new Kinetic.Circle({
x: 100,
y: 0,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorTR);
var anchorBR = new Kinetic.Circle({
x: 100,
y: 100,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorBR);
var anchorBL = new Kinetic.Circle({
x: 0,
y: 100,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorBL);
var anchorTL = new Kinetic.Circle({
x: 0,
y: 0,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorTL);
layer.draw();
Currently i'm defining multiple kinetic circles for the anchor points and multiple variables for positioning the anchor points.I'm trying to optimize the code in such a way that i can reuse the code multiple times without using loops but not being able to..Please help..
You can make the code reusable by encapsulating it into functions and adding some references.
Put the code that creates a group & room into a function and return the new room from that function.
Put the code that creates an anchor into a function and return the new anchor from that function.
Attach references to a room's anchors to the room node itself.
Here's a refactoring of the code and a Demo: http://jsfiddle.net/m1erickson/opsy1pn9/
<!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-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var room1=makeRoom(50,50,50,50);
var room2=makeRoom(150,150,50,50);
function makeRoom(x,y,w,h){
var g=new Kinetic.Group({x:x,y:y,draggable:true});
layer.add(g);
var room=new Kinetic.Shape({
x:0,
y:0,
width:w,
height:h,
stroke:"blue",
fill: 'red',
drawFunc: function(context) {
var x=this.x();
var y=this.y();
var w=this.width();
var h=this.height();
var tlX=this.anchorTL.x();
var tlY=this.anchorTL.y();
context.beginPath();
context.moveTo(tlX,tlY);
// top
context.bezierCurveTo(x+w/3,y, x+w*2/3,y, this.anchorTR.x(),this.anchorTR.y());
// right
context.bezierCurveTo(x+w,y+h/3, x+w,y+h*2/3, this.anchorBR.x(),this.anchorBR.y());
// bottom
context.bezierCurveTo(x+w*2/3,y+h, x+w/3,y+h, this.anchorBL.x(),this.anchorBL.y());
// left
context.bezierCurveTo(x,y+h*2/3, x,y+h/3, tlX,tlY);
context.closePath();
context.fillStrokeShape(this);
}
});
g.add(room);
room.anchorTR=makeAnchor(w,0,g);
room.anchorBR=makeAnchor(w,h,g);
room.anchorBL=makeAnchor(0,h,g);
room.anchorTL=makeAnchor(0,0,g);
layer.draw();
}
function makeAnchor(x,y,group){
var anchor=new Kinetic.Circle({
x:x,
y:y,
radius:8,
fill:"green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
group.add(anchor);
anchor.moveToTop();
return(anchor);
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag green circle to change red rect</h4>
<div id="container"></div>
</body>
</html>