Skip to content

Instantly share code, notes, and snippets.

@gregtatum
Created July 26, 2016 02:08
Show Gist options
  • Select an option

  • Save gregtatum/d5ce508e7bb2e37bf828c0cacd5ddd06 to your computer and use it in GitHub Desktop.

Select an option

Save gregtatum/d5ce508e7bb2e37bf828c0cacd5ddd06 to your computer and use it in GitHub Desktop.
requirebin sketch
var roundCorner = require('round-corner')
// Main runs immediately, just to organize the code a bit.
;(function main () {
var path = createPathElement()
// Create our line segment.
var line = [
[125, 500],
[200, 50],
[400, 400]
]
// Immediately run and loop some code.
;(function loop () {
// Change the inset over time to illustrate the functionality.
var t = (Math.sin(Date.now() * 0.001) + 1) / 2
var inset = 250 * t
// This is the sequence of [segment, arc, segment].
var sequence = roundCorner(line, inset)
// Generate the arc path, and set the path attribute
path.setAttribute('d', generateArcPath(sequence))
// Run the loop to animate.
window.requestAnimationFrame(loop)
})()
})()
function generateArcPath (sequence) {
var segmentA = sequence[0]
var arc = sequence[1]
var segmentB = sequence[2]
return [
drawLine(segmentA),
drawArc(segmentA, arc, segmentB),
drawLine(segmentB)
].join(' ')
}
function drawLine (segment) {
return 'M' + segment[0][0] + ',' + segment[0][1] + ' ' +
'L' + segment[1][0] + ',' + segment[1][1]
}
function drawArc (segmentA, arc, segmentB) {
// We need to compute the rotation of the arc to match the needed SVG format.
var rotation = toDegrees(Math.atan2(
segmentB[0][1] - segmentA[1][1],
segmentB[0][0] - segmentA[1][0]
))
return [
'A', arc.radius, arc.radius, rotation, 0, 1, segmentB[0][0], segmentB[0][1]
].join(' ')
}
function toDegrees (radians) {
return radians / Math.PI * 180
}
function createPathElement () {
var xmlns = 'http://www.w3.org/2000/svg'
var width = window.innerWidth
var height = window.innerHeight
var svg = document.createElementNS(xmlns, 'svg')
svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height)
svg.setAttributeNS(null, 'width', width)
svg.setAttributeNS(null, 'height', height)
Object.assign(svg.style, {
position: 'absolute',
top: 0,
left: 0
})
var path = document.createElementNS(xmlns, 'path')
Object.assign(path.style, {
fill: 'none',
stroke: 'black',
'stroke-width': 3
})
svg.appendChild(path)
document.body.appendChild(svg)
return path
}
setTimeout(function(){require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=add;function add(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out}},{}],2:[function(require,module,exports){module.exports=clone;function clone(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out}},{}],3:[function(require,module,exports){module.exports=copy;function copy(out,a){out[0]=a[0];out[1]=a[1];return out}},{}],4:[function(require,module,exports){module.exports=create;function create(){var out=new Float32Array(2);out[0]=0;out[1]=0;return out}},{}],5:[function(require,module,exports){module.exports=cross;function cross(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out}},{}],6:[function(require,module,exports){module.exports=distance;function distance(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)}},{}],7:[function(require,module,exports){module.exports=divide;function divide(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out}},{}],8:[function(require,module,exports){module.exports=dot;function dot(a,b){return a[0]*b[0]+a[1]*b[1]}},{}],9:[function(require,module,exports){module.exports=forEach;var vec=require("./create")();function forEach(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}},{"./create":4}],10:[function(require,module,exports){module.exports=fromValues;function fromValues(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out}},{}],11:[function(require,module,exports){module.exports={create:require("./create"),clone:require("./clone"),fromValues:require("./fromValues"),copy:require("./copy"),set:require("./set"),add:require("./add"),subtract:require("./subtract"),multiply:require("./multiply"),divide:require("./divide"),min:require("./min"),max:require("./max"),scale:require("./scale"),scaleAndAdd:require("./scaleAndAdd"),distance:require("./distance"),squaredDistance:require("./squaredDistance"),length:require("./length"),squaredLength:require("./squaredLength"),negate:require("./negate"),normalize:require("./normalize"),dot:require("./dot"),cross:require("./cross"),lerp:require("./lerp"),random:require("./random"),transformMat2:require("./transformMat2"),transformMat2d:require("./transformMat2d"),transformMat3:require("./transformMat3"),transformMat4:require("./transformMat4"),forEach:require("./forEach")}},{"./add":1,"./clone":2,"./copy":3,"./create":4,"./cross":5,"./distance":6,"./divide":7,"./dot":8,"./forEach":9,"./fromValues":10,"./length":12,"./lerp":13,"./max":14,"./min":15,"./multiply":16,"./negate":17,"./normalize":18,"./random":19,"./scale":20,"./scaleAndAdd":21,"./set":22,"./squaredDistance":23,"./squaredLength":24,"./subtract":25,"./transformMat2":26,"./transformMat2d":27,"./transformMat3":28,"./transformMat4":29}],12:[function(require,module,exports){module.exports=length;function length(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)}},{}],13:[function(require,module,exports){module.exports=lerp;function lerp(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out}},{}],14:[function(require,module,exports){module.exports=max;function max(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out}},{}],15:[function(require,module,exports){module.exports=min;function min(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);return out}},{}],16:[function(require,module,exports){module.exports=multiply;function multiply(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out}},{}],17:[function(require,module,exports){module.exports=negate;function negate(out,a){out[0]=-a[0];out[1]=-a[1];return out}},{}],18:[function(require,module,exports){module.exports=normalize;function normalize(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out}},{}],19:[function(require,module,exports){module.exports=random;function random(out,scale){scale=scale||1;var r=Math.random()*2*Math.PI;out[0]=Math.cos(r)*scale;out[1]=Math.sin(r)*scale;return out}},{}],20:[function(require,module,exports){module.exports=scale;function scale(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out}},{}],21:[function(require,module,exports){module.exports=scaleAndAdd;function scaleAndAdd(out,a,b,scale){out[0]=a[0]+b[0]*scale;out[1]=a[1]+b[1]*scale;return out}},{}],22:[function(require,module,exports){module.exports=set;function set(out,x,y){out[0]=x;out[1]=y;return out}},{}],23:[function(require,module,exports){module.exports=squaredDistance;function squaredDistance(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y}},{}],24:[function(require,module,exports){module.exports=squaredLength;function squaredLength(a){var x=a[0],y=a[1];return x*x+y*y}},{}],25:[function(require,module,exports){module.exports=subtract;function subtract(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out}},{}],26:[function(require,module,exports){module.exports=transformMat2;function transformMat2(out,a,m){var x=a[0],y=a[1];out[0]=m[0]*x+m[2]*y;out[1]=m[1]*x+m[3]*y;return out}},{}],27:[function(require,module,exports){module.exports=transformMat2d;function transformMat2d(out,a,m){var x=a[0],y=a[1];out[0]=m[0]*x+m[2]*y+m[4];out[1]=m[1]*x+m[3]*y+m[5];return out}},{}],28:[function(require,module,exports){module.exports=transformMat3;function transformMat3(out,a,m){var x=a[0],y=a[1];out[0]=m[0]*x+m[3]*y+m[6];out[1]=m[1]*x+m[4]*y+m[7];return out}},{}],29:[function(require,module,exports){module.exports=transformMat4;function transformMat4(out,a,m){var x=a[0],y=a[1];out[0]=m[0]*x+m[4]*y+m[12];out[1]=m[1]*x+m[5]*y+m[13];return out}},{}],"round-corner":[function(require,module,exports){var vec2=require("gl-vec2");function roundCornerRouter(segment,inset,ctx){var a=segment[0];var b=segment[1];var c=segment[2];var vX=b[0]-a[0];var vY=b[1]-a[1];var wX=c[0]-b[0];var wY=c[1]-b[1];var theta=Math.atan2(vX,vY);var rotatedWX=wX*Math.cos(theta)-wY*Math.sin(theta);if(rotatedWX>0){var result=roundCorner(c,b,a,inset,ctx);var start=result[0];var end=result[2];result[0]=end;result[2]=start;return result}else{return roundCorner(a,b,c,inset,ctx)}}var _s1=[0,0];var _s2=[0,0];var _s3=[0,0];var _s4=[0,0];var _s5=[0,0];var _s6=[0,0];var _s7=[0,0];var _s8=[0,0];function roundCorner(a,b,c,inset,ctx){var v=vec2.subtract(_s1,b,a);var w=vec2.subtract(_s2,b,c);var unitV=vec2.normalize(_s3,v);var unitW=vec2.normalize(_s4,w);var lengthV=vec2.length(v);var lengthW=vec2.length(w);var targetInset=Math.min(inset,vec2.length(v),vec2.length(w));var mv=vec2.add(_s5,vec2.scale(_s5,unitV,lengthV-targetInset),a);var mw=vec2.add(_s6,vec2.scale(_s6,unitW,lengthW-targetInset),c);var normalV=[-unitV[1],unitV[0]];var normalW=[unitW[1],-unitW[0]];var distanceOnNormalV=magCross(vec2.subtract(_s7,mv,mw),normalW)/magCross(normalW,normalV);var arcCenter=vec2.add(_s8,mw,vec2.scale(_s8,normalW,distanceOnNormalV));var arcRadius=vec2.distance(mv,arcCenter);var arcStart=Math.PI+Math.atan2(normalV[1],normalV[0]);var arcEnd=Math.PI+Math.atan2(normalW[1],normalW[0]);var arc={center:arcCenter,radius:arcRadius,start:arcStart,end:arcEnd};return[[a,mv],arc,[mw,c]]}function magCross(v,w){return v[0]*w[1]-v[1]*w[0]}module.exports=roundCornerRouter},{"gl-vec2":11}]},{},[]);var roundCorner=require("round-corner");(function main(){var path=createPathElement();var line=[[125,500],[200,50],[400,400]];(function loop(){var t=(Math.sin(Date.now()*.001)+1)/2;var inset=250*t;var sequence=roundCorner(line,inset);path.setAttribute("d",generateArcPath(sequence));window.requestAnimationFrame(loop)})()})();function generateArcPath(sequence){var segmentA=sequence[0];var arc=sequence[1];var segmentB=sequence[2];return[drawLine(segmentA),drawArc(segmentA,arc,segmentB),drawLine(segmentB)].join(" ")}function drawLine(segment){return"M"+segment[0][0]+","+segment[0][1]+" "+"L"+segment[1][0]+","+segment[1][1]}function drawArc(segmentA,arc,segmentB){var rotation=toDegrees(Math.atan2(segmentB[0][1]-segmentA[1][1],segmentB[0][0]-segmentA[1][0]));return["A",arc.radius,arc.radius,rotation,0,1,segmentB[0][0],segmentB[0][1]].join(" ")}function toDegrees(radians){return radians/Math.PI*180}function createPathElement(){var xmlns="http://www.w3.org/2000/svg";var width=window.innerWidth;var height=window.innerHeight;var svg=document.createElementNS(xmlns,"svg");svg.setAttributeNS(null,"viewBox","0 0 "+width+" "+height);svg.setAttributeNS(null,"width",width);svg.setAttributeNS(null,"height",height);Object.assign(svg.style,{position:"absolute",top:0,left:0});var path=document.createElementNS(xmlns,"path");Object.assign(path.style,{fill:"none",stroke:"black","stroke-width":3});svg.appendChild(path);document.body.appendChild(svg);return path}},0);
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"round-corner": "1.0.0"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment