Reputation: 213
I would like to add images along a Spline. So a spline is drawn by the user, and then after it is drawn I'd like to run images along it's path. Fundamentally, the images would be repeated along the path of the spline Any ideas on how this could be achieved?
Upvotes: 0
Views: 154
Reputation: 105035
You can place markers (or your images) at intervals along the spline
You can get the starting point of the Kinetic.Spline by calling mySpline.getPoints().
You can get the curve definitions for a spline by calling the internal mySpline.getTensionPoints.
The first curve is a quadratic curve (controlX, controlY, endX, endY)
The intermediate curves are cubic curves. (control1X, control1Y, control2X, control2Y, endX, endY);
The last curve is a quadratic curve (controlX, controlY, endX, endY)
With this info and some Math, you can place markers (or your images) at intervals on each curve.
Here’s code and a Demo: http://jsfiddle.net/m1erickson/8mb9r/
<!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.0.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:400px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 400,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var spline = new Kinetic.Line({
points: [20,100,340,100,200,200,50,200],
stroke: 'green',
strokeWidth: 3,
lineCap: 'round',
tension: 1,
});
layer.add(spline);
layer.draw();
//
// the following code places markers along the spline at interval
//
showSplineMarkers(spline,0.25);
function showSplineMarkers(spline,interval){
var points = spline.getPoints();
var length = points.length;
var tension = spline.getTension();
var closed = spline.getClosed();
var tp, len, n, pt1, pt2, pt3, pt4;
var intervalT=interval;
var spots=[];
pt1={x:points[0],y:points[1]}; // starting point of spline
// return if not a spline (tension==0)
// return when insufficient spline points are declared
if(tension==0 || length<=4){ return; }
// walk along the spline and place markets at interval
tp = spline.getTensionPoints();
len = tp.length;
n = closed ? 0 : 4;
// the first curve of the spline is Quadratic
if (!closed) {
pt2={x:tp[0],y:tp[1]};
pt3={x:tp[2],y:tp[3]};
placeAlongQuad(intervalT,pt1,pt2,pt3);
pt1=pt3;
}
// all intermediate curves of the spline are CubicBezier
while(n < len - 2) {
pt2={x:tp[n++],y:tp[n++]};
pt3={x:tp[n++],y:tp[n++]};
pt4={x:tp[n++],y:tp[n++]};
placeAlongCubicBezier(intervalT,pt1,pt2,pt3,pt4);
pt1=pt4;
}
// the last curve of the spline is Quadratic
if (!closed) {
pt2={x:tp[len-2],y:tp[len-1]};
pt3={x:points[length-2],y:points[length-1]};
placeAlongQuad(intervalT,pt1,pt2,pt3);
}
} // end showSplineMarkers
// place markers at interval along the Quad curve
function placeAlongQuad(intervalT,pt1,pt2,pt3){
for(var i=0.00;i<=1.00;i+=intervalT){
var pt=getQuadraticBezierXYatT(pt1,pt2,pt3,i);
spot(pt.x,pt.y);
}
}
// place markers at interval along CubicBez curve
function placeAlongCubicBezier(intervalT,pt1,pt2,pt3,pt4){
for(var i=0.00;i<=1.00;i+=intervalT){
var pt=getCubicBezierXYatT(pt1,pt2,pt3,pt4,i);
spot(pt.x,pt.y);
}
}
// draw a marker
function spot(x,y){
var n=new Kinetic.Circle({
x:x,
y:y,
radius:4,
fill:"red"
});
layer.add(n);
layer.draw();
}
// get XY at interval on Quad
function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x;
var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y;
return( {x:x,y:y} );
}
// get XY at interval on CubicBez
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Upvotes: 1