Skip to content

Instantly share code, notes, and snippets.

@omnizach
Last active February 29, 2016 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omnizach/0f93ca731883d601a114 to your computer and use it in GitHub Desktop.
Save omnizach/0f93ca731883d601a114 to your computer and use it in GitHub Desktop.
Gradient Along Stroke
(function(){var t,n,e,r,i=function(t,n){return(+t%(n=+n)+n)%n},h=[].slice;r=function(){var t,n,e,r,i,h,s;for(i=function(){var n,e,r;for(r=[],n=0,e=arguments.length;e>n;n++)t=arguments[n],r.push(t.length);return r}.apply(this,arguments),r=Math.min.apply(Math,i),s=[],n=e=0,h=r;h>=0?h>e:e>h;n=h>=0?++e:--e)s.push(function(){var e,r,i;for(i=[],e=0,r=arguments.length;r>e;e++)t=arguments[e],i.push(t[n]);return i}.apply(this,arguments));return s},Function.prototype._getter=function(t,n){return Object.defineProperty(this.prototype,t,{get:n,configurable:!0})},Function.prototype._setter=function(t,n){return Object.defineProperty(this.prototype,t,{set:n,configurable:!0})},n=function(){function t(t,n){this.x=t,this.y=n}return t}(),t=function(){function t(t,n,e,r){this.p0=t,this.p1=n,this.p2=e,this.p3=r}return t._base3=function(t,n,e,r,i){var h,s;return h=-3*n+9*e-9*r+3*i,s=t*h+6*n-12*e+6*r,t*s-3*n+3*e},t.penPath=function(t){return"M "+t.p0.x+", "+t.p0.y+" C "+t.p1.x+", "+t.p1.y+" "+t.p2.x+", "+t.p2.y+" "+t.p3.x+", "+t.p3.y},t.paintPath=function(t){var n;return n=t/2,function(t){var e,r;return e=t.normal(0),r=t.normal(1),"M "+(t.p0.x-e.x*n)+", "+(t.p0.y-e.y*n)+" L "+(t.p0.x+e.x*n)+", "+(t.p0.y+e.y*n)+" L "+(t.p3.x+r.x*n)+", "+(t.p3.y+r.y*n)+" L "+(t.p3.x-r.x*n)+", "+(t.p3.y-r.y*n)+" Z"}},t.prototype._findT=function(t,n){var e;return t=Math.min(t,this.length),n=n||t/this.length,e=(this.lengthAt(n)-t)/this.length,Math.abs(e)<1e-4?n:this._findT(t,n-e/2)},t.prototype.lengthAt=function(n){var e,r;return null==n&&(n=1),n=n>1?1:0>n?0:n,r=n/2,e=function(n){var e;return e=r*n[0]+r,n[1]*Math.sqrt(Math.pow(t._base3(e,this.p0.x,this.p1.x,this.p2.x,this.p3.x),2)+Math.pow(t._base3(e,this.p0.y,this.p1.y,this.p2.y,this.p3.y),2))},r*[[-.1252,.2491],[.1252,.2491],[-.3678,.2335],[.3678,.2335],[-.5873,.2032],[.5873,.2032],[-.7699,.1601],[.7699,.1601],[-.9041,.1069],[.9041,.1069],[-.9816,.0472],[.9816,.0472]].map(e,this).reduce(function(t,n){return t+n})},t._getter("length",function(){return null!=this._length?this._length:this._length=this.lengthAt(1)}),t.prototype.point=function(t){return new n(Math.pow(1-t,3)*this.p0.x+3*Math.pow(1-t,2)*t*this.p1.x+3*(1-t)*Math.pow(t,2)*this.p2.x+Math.pow(t,3)*this.p3.x,Math.pow(1-t,3)*this.p0.y+3*Math.pow(1-t,2)*t*this.p1.y+3*(1-t)*Math.pow(t,2)*this.p2.y+Math.pow(t,3)*this.p3.y)},t.prototype.pointAtLength=function(t){return this.point(this._findT(t))},t.prototype.firstDerivative=function(t){return new n(3*Math.pow(1-t,2)*(this.p1.x-this.p0.x)+6*(1-t)*t*(this.p2.x-this.p1.x)+3*Math.pow(t,2)*(this.p3.x-this.p2.x),3*Math.pow(1-t,2)*(this.p1.y-this.p0.y)+6*(1-t)*t*(this.p2.y-this.p1.y)+3*Math.pow(t,2)*(this.p3.y-this.p2.y))},t.prototype.secondDerivative=function(t){return new n(6*(1-t)*(this.p2.x-2*this.p1.x+this.p0.x)+6*t*(this.p3.x-2*this.p2.x+this.p2.x),6*(1-t)*(this.p2.y-2*this.p1.y+this.p0.y)+6*t*(this.p3.y-2*this.p2.y+this.p2.y))},t.prototype.curvature=function(t){var n,e;return n=this.firstDerivative(t)||0,e=this.secondDerivative(t)||0,(n.x*e.y-n.y*e.x)/Math.pow(n.x*n.x+n.y*n.y,1.5)},t.prototype.tangent=function(t){var e,r;return r=this.firstDerivative(t),e=Math.sqrt(r.x*r.x+r.y*r.y)||1,new n(r.x/e,r.y/e)},t.prototype.normal=function(t){var e;return e=this.tangent(t),new n(-e.y,e.x)},t}(),e=function(){function e(t,n){var r;this.closed=n,this.curves=e.computeSpline(t.map(function(t){return t.x}),t.map(function(t){return t.y}),n),this.startLengths=function(){var t,n,e,i;for(e=this.curves,i=[],t=0,n=e.length;n>t;t++)r=e[t],i.push(r.startLength);return i}.call(this),this.endLengths=function(){var t,n,e,i;for(e=this.curves,i=[],t=0,n=e.length;n>t;t++)r=e[t],i.push(r.endLength);return i}.call(this),this.length=this.endLengths.slice(-1)[0]}return e.computeControlPoints=function(t){var n,e,r,i,h,s,p,o,u,c,a,l,f,v,y;for(n=function(t){return 0>=t?0:t>=o-1?2:1},r=function(t){return t>=o-1?0:1},o=t.length-1,c=new Array(o-1),a=new Array(o-1),e=function(){var t,n,e;for(e=[],i=t=0,n=o;n>=0?n>t:t>n;i=n>=0?++t:--t)e.push(4);return e}(),e[0]=2,e[o-1]=7,l=function(){var n,e,r;for(r=[],i=n=0,e=o-1;e>=0?e>n:n>e;i=e>=0?++n:--n)r.push(4*t[i]+2*t[i+1]);return r}(),l[0]=t[0]+2*t[1],l.push(8*t[o-1]+t[o]),i=h=0,f=e.length-1;f>=0?f>h:h>f;i=f>=0?++h:--h)p=n(i+1)/e[i],e[i+1]-=p*r(i),l[i+1]-=p*l[i];for(c[o-1]=l[o-1]/e[o-1],i=s=v=e.length-2;0>=v?0>=s:s>=0;i=0>=v?++s:--s)c[i]=(l[i]-r(i)*c[i+1])/e[i];for(i=u=0,y=e.length-1;y>=0?y>u:u>y;i=y>=0?++u:--u)a[i]=2*t[i+1]-c[i+1];return a[o-1]=.5*(t[o]+c[o-1]),{p1:c,p2:a}},e.computeSpline=function(s,p,o){var u,c,a,l,f,v,y,g,x,d,w,M,m,L,_,b,A,D,P,I,C;for(l=12,o&&(v=function(t){var n,e,r,h;for(h=[],n=e=0,r=l;r>=0?r>e:e>r;n=r>=0?++e:--e)h.push(t[i(n,t.length)]);return h},f=function(t){var n,e,r,h;for(h=[],n=e=r=l;0>=r?0>e:e>0;n=0>=r?++e:--e)h.push(t[i(t.length-n,t.length)]);return h},s=h.call(f(s)).concat(h.call(s),h.call(v(s))),p=h.call(f(p)).concat(h.call(p),h.call(v(p)))),c=e.computeControlPoints(s),a=e.computeControlPoints(p),C=0,o&&(s=s.slice(l,+-l+1||9e9),p=p.slice(l,+-l+1||9e9),c.p1=c.p1.slice(l,+-l+1||9e9),a.p1=a.p1.slice(l,+-l+1||9e9),c.p2=c.p2.slice(l,+-l+1||9e9),a.p2=a.p2.slice(l,+-l+1||9e9)),D=r(s.slice(0,-1),p.slice(0,-1),c.p1,a.p1,c.p2,a.p2,s.slice(1),p.slice(1)),I=[],y=g=0,x=D.length;x>g;y=++g)P=D[y],d=P[0],w=P[1],M=P[2],m=P[3],L=P[4],_=P[5],b=P[6],A=P[7],u=new t(new n(d,w),new n(M,m),new n(L,_),new n(b,A)),u.startLength=C,u.endLength=C+u.length,u.segmentOffset=y/(s.length-1),u.index=y,C+=u.length,I.push(u);return I},e.prototype._curveIndex=function(t){var n;return n=Math.trunc(t),t%=1,0>n||n>this.curves.length?null:n===this.curves.length?{i:n-1,t:t+1}:{i:n,t:t}},e.prototype.point=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].point(n.t)},e.prototype.pointAtLength=function(t){var n,e;return n=function(t,e,r,i){var h;switch(h=r+i>>>1,!1){case!((t[h-1]||0)<=e&&e<=t[h]):return h;case!(e<(t[h-1]||0)):return n(t,e,r,h);default:return n(t,e,h+1,i)}},e=n(this.endLengths,Math.min(t,this.endLengths[this.endLengths.length-1]),0,this.endLengths.length),this.curves[e].pointAtLength(t-this.startLengths[e])},e.prototype.firstDerivative=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].firstDerivative(n.t)},e.prototype.secondDerivative=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].secondDerivative(n.t)},e.prototype.curvature=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].curvature(n.t)},e.prototype.tangent=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].tangent(n.t)},e.prototype.normal=function(t){var n;return n=this._curveIndex(t),this.curves[n.i].normal(n.t)},e.prototype.normalize=function(t,n,r){var i,h;switch(r=r||Math.ceil(this.length/(n||1)),t){case"length":return n=this.length/r,h=function(){var t,e,h;for(h=[],i=t=0,e=r;e>=0?e>t:t>e;i=e>=0?++t:--t)h.push(this.pointAtLength(i*n));return h}.call(this),new e(h,this.closed);case"x":return this;default:return this}},e}(),this.bezier={Point:n,Curve:t,Spline:e}}).call(this);
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="bezier.min.js"></script>
<script>
var points = [
[86, 388],
[788, 40],
[805, 447],
[93, 72]
];
var width = 960,
height = 500;
var color = d3.interpolateLab("#008000", "#c83a22"),
path = bezier.Curve.paintPath(50);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var spline = new bezier.Spline(points.map(function(p) { return new bezier.Point(p[0], p[1]); }))
.normalize('length', 8);
svg.append('g')
.selectAll('.bezier-curve')
.data(spline.curves)
.enter()
.append('path')
.attr('class', 'bezier-curve')
.attr('d', path)
.attr('stroke', function(d) { return color(d.segmentOffset) })
.attr('fill', function(d) { return color(d.segmentOffset) });
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment