Last active
May 27, 2018 17:57
-
-
Save eeropic/10789820b03c2326584956915181e98c to your computer and use it in GitHub Desktop.
paper.js sketches 2018
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include('http://eerojohannes.com/js/bezier-easing.js') | |
var ease=BezierEasing(0.3,0,0.3,1) | |
function lerp(obj1,obj2,prop,fac){ | |
return (obj2[prop]-obj1[prop])*fac+obj1[prop] | |
} | |
function lerpArray(arr1,arr2,fac){ | |
return [ | |
(arr2[0]-arr1[0])*fac+arr1[0], | |
(arr2[1]-arr1[1])*fac+arr1[1], | |
] | |
} | |
function lerpRGB(col1,col2,fac){ | |
return [ | |
(col2[0]-col1[0])*fac+col1[0], | |
(col2[1]-col1[1])*fac+col1[1], | |
(col2[2]-col1[2])*fac+col1[2] | |
] | |
} | |
function lerpSegments(segs1,segs2,fac){ | |
let newSegments=[] | |
for(let i=0;i<segs1.length;i++){ | |
let newSegment=[ | |
[ | |
(segs2[i][0][0]-segs1[i][0][0])*fac+segs1[i][0][0], | |
(segs2[i][0][1]-segs1[i][0][1])*fac+segs1[i][0][1], | |
], | |
[ | |
(segs2[i][1][0]-segs1[i][1][0])*fac+segs1[i][1][0], | |
(segs2[i][1][1]-segs1[i][1][1])*fac+segs1[i][1][1], | |
], | |
[ | |
(segs2[i][2][0]-segs1[i][2][0])*fac+segs1[i][2][0], | |
(segs2[i][2][1]-segs1[i][2][1])*fac+segs1[i][2][1], | |
], | |
] | |
newSegments.push(newSegment) | |
} | |
return newSegments | |
} | |
Item.prototype.scrub=function(time){ | |
let propKeys=Object.keys(this.data.anim) | |
for(var i=0;i<propKeys.length;i++){ | |
//first key | |
var prop=propKeys[i]; | |
var keys=this.data.anim[propKeys[i]] | |
//console.log(keys) | |
if(time<keys[0].time){ | |
let key1=keys[0] | |
this[prop]=key1.value | |
} | |
else if(time>=keys[0].time && time<keys[keys.length-1].time){ | |
var currentKeys=keys.filter( | |
(obj,idx,arr) => | |
time >= arr[Math.max(0,idx-1)].time | |
) | |
if(currentKeys.length>1){ //console.log('arrrr') | |
let key1=currentKeys[currentKeys.length-2] | |
let key2=currentKeys[currentKeys.length-1] | |
let delta=key2.time-key1.time | |
let pos=time-key1.time | |
//playhead from 0 to 1 | |
let fac=Math.min(1,Math.max(0,pos/delta)) | |
if(prop=="position"){ | |
let v=lerpArray(key1.value,key2.value,ease(fac)) | |
this[prop]=v | |
} | |
else if(prop=="fillColor" || prop=="strokeColor"){ | |
let v=lerpRGB(key1.value,key2.value,ease(fac)) | |
this[prop]=v | |
} | |
else if(prop=="segments"){ | |
let v=lerpSegments(key1.value,key2.value,ease(fac)) | |
this[prop]=v | |
} | |
else { | |
let v=lerp(key1,key2,'value',ease(fac)) | |
this[prop]=v | |
} | |
} | |
} | |
//last key | |
else{ | |
let key1=keys[keys.length-1] | |
this[prop]=key1.value | |
} | |
} | |
} | |
paths=200 | |
numKeys=3 | |
w=view.viewSize.width | |
h=view.viewSize.height | |
for(var i=0;i<paths;i++){ | |
var test=new Path({ | |
segments:[ | |
[[-5,-5],[-5,-5],[5,5]], | |
[[0,-5],[-5,-5],[5,5]], | |
[[-5,5],[-5,-5],[5,5]], | |
], | |
fillColor:i/paths, | |
strokeColor:1-i/paths, | |
strokeWidth:5, | |
position:[100,100], | |
data:{anim:{}}, | |
applyMatrix:false | |
}) | |
test.data.anim.position=[] | |
test.data.anim.strokeWidth=[] | |
test.data.anim.fillColor=[] | |
test.data.anim.strokeColor=[] | |
test.data.anim.segments=[] | |
for(var j=0;j<numKeys;j++){ | |
test.data.anim.position.push({ | |
time:j*2+i/200, | |
value:[ | |
Math.random()*w, | |
Math.random()*h | |
] | |
} | |
) | |
test.data.anim.strokeWidth.push({ | |
time:j*2+i/200, | |
value:Math.random()*10+2 | |
} | |
) | |
test.data.anim.fillColor.push({ | |
time:j*2+i/200, | |
value:[ | |
0, | |
Math.random(), | |
Math.random(), | |
] | |
} | |
) | |
test.data.anim.strokeColor.push({ | |
time:j*2+i/200, | |
value:[ | |
0, | |
Math.random(), | |
Math.random(), | |
] | |
} | |
) | |
test.data.anim.segments.push({ | |
time:j*2+i/200, | |
value:[ | |
[ | |
[-10*(j+1),-10*(j+1)], | |
[-5,5], | |
[5,-5], | |
], | |
[ | |
[10*(j+1),-10*(j+1)], | |
[-5,-5], | |
[5,5], | |
], | |
[ | |
[10*(j+1),10*(j+1)], | |
[5*j,-5*j], | |
[-5*j,5*j], | |
], | |
[ | |
[Math.random()*-20*(j+1),Math.random()*20*(j+1)], | |
[5,5], | |
[-5,-5], | |
], | |
] | |
} | |
) | |
} | |
} | |
// keyframes array of objects | |
// {time, value} | |
playing=true | |
view.startTime=0 | |
view.time=0 | |
view.playhead=0 | |
view.timelineLength=10.0 | |
function onFrame(e){ | |
view.time=e.time | |
if(playing){ | |
view.playhead=(e.time-view.startTime)%view.timelineLength; | |
for(var item of project.activeLayer.children){ | |
item.scrub(view.playhead) | |
} | |
} | |
} | |
function onKeyDown(e){ | |
if(!e.modifiers.command){ | |
playing=!playing; | |
view.startTime=view.time | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include('http://eerojohannes.com/js/bezier-easing.js') | |
var x1=0.4 | |
var y1=0 | |
var x2=0.2 | |
var y2=1 | |
var easing=BezierEasing(x1,y1,x2,y2) | |
var w=200 | |
var h=200 | |
var sx=200 | |
var sy=200 | |
var pt1=new Point(sx,sy) | |
var pt2=new Point(sx+w,sy-h) | |
var ecurve=new Path({ | |
segments:[ | |
new Segment({ | |
point:pt1, | |
handleOut:new Point(x1*w,-y1*h) | |
}), | |
new Segment({ | |
point:pt2, | |
handleIn:new Point((x2-1)*w,(y2-1)*h) | |
}) | |
] | |
, | |
strokeWidth:2, | |
strokeColor:"white" | |
}) | |
var ept=new Shape.Circle({ | |
radius:20, | |
fillColor:"white" | |
}) | |
time=0 | |
ballCount=1 | |
document.body.style.backgroundColor="#303240" | |
Item.prototype.anim = function(opts){ | |
var self=this; | |
let duration=opts.duration || 500 | |
let position=opts.position || new Point(0,0) | |
let loop=opts.loop || 1 | |
var itemTypes={ | |
Path(){ | |
}, | |
Shape(){ | |
self.data.anim={position:[self.position,new Point(position[0],position[1])]} | |
self.data.anim.start=time | |
self.data.anim.loop=loop | |
self.data.anim.duration=duration | |
}, | |
Group(){ | |
for(var i in self.children){ | |
var item=self.children[i]; | |
} | |
} | |
} | |
itemTypes[this.className]() | |
return self | |
} | |
balls=[] | |
var ball=new Shape.Circle([200,200],20) | |
ball.fillColor="red" | |
balls.push(ball) | |
var t=new Tool() | |
t.path=new Path({strokeWidth:1,strokeColor:"white"}) | |
for(var i=0;i<ballCount;i++)t.path.add([0,0]) | |
t.on({ | |
mousedown(e){ | |
for(var i=1;i<ballCount;i++){ | |
t.path.segments[i].point=balls[i].position | |
} | |
for(var i=0;i<ballCount;i++){ | |
if(i==0){ | |
var pt=e.point-balls[0].position | |
balls[i].anim({position:[e.point.x,e.point.y],duration:pt.length*2}) | |
} | |
else { | |
var pt=balls[i].position-balls[(i+1)%ballCount].position; | |
balls[i].anim({position:[balls[(i+1)%ballCount].position.x,balls[(i+1)%ballCount].position.y],duration:pt.length*2}) | |
} | |
} | |
} | |
}) | |
function onFrame(e){ | |
time=e.time*1000 | |
for(var item of project.activeLayer.children){ | |
if(item.data.anim!=null){ | |
if(time>=item.data.anim.start && time<=item.data.anim.start+item.data.anim.duration*item.data.anim.loop){ | |
pos=((time-item.data.anim.start)/item.data.anim.duration)%1; | |
pos2=easing(pos) | |
ept.position=pt1+[pos*w, -h*pos2] | |
let delta=(item.data.anim.position[1]-item.data.anim.position[0]); | |
item.position=item.data.anim.position[0]+delta.multiply(pos2) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
frameCount=60/20; | |
document.body.style.backgroundColor="#303240" | |
document.addEventListener('paste', function(evt) { | |
if(document.activeElement.nodeName!="TEXTAREA"){ | |
var str=evt.clipboardData.getData('text/plain').slice(0, -1); | |
var svg=project.importSVG(str) | |
svg.position=pastePos | |
var items=svg.parent.insertChildren(svg.index,svg.removeChildren()); | |
svg.remove(); | |
//remove the bounding box and hidden paths | |
var nullItems=new Group(project.getItems({strokeColor:null,fillColor:null})).remove() | |
for(var item of items[1].children){ | |
item.position.x=pastePos.x; | |
} | |
} | |
}) | |
pastePos=new Point(0,0) | |
var t=new Tool() | |
t.on({ | |
mousemove(e){ | |
pastePos=e.point | |
}, | |
}) | |
function onFrame(e){ | |
if(e.count%frameCount==0){ | |
var currentFrame=Math.floor(e.count/frameCount) | |
var items = project.getItems({name: /^anim/}); | |
for(var item of items){ | |
var frames=item.children; | |
for(var frame of frames){ | |
frame.opacity=0 | |
} | |
var thisFrame=frames[(currentFrame+item.index)%frames.length]; | |
thisFrame.opacity=1 | |
} | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include('http://eerojohannes.com/js/bezier-easing.js') | |
var easeOut=BezierEasing(0,0,0.1,1) | |
var easeIn=BezierEasing(0.9,0,1,1) | |
var ease=BezierEasing(0.3,0,0.3,1) | |
function lerp(obj1,obj2,prop,fac){ | |
return (obj2[prop]-obj1[prop])*fac+obj1[prop] | |
} | |
Item.prototype.interpolate2=function(src,tgt,fac){ | |
this.style=src.style | |
if(src.style.strokeColor!=null&&tgt.style.strokeColor!=null){ | |
let col1=src.style.strokeColor | |
let col2=tgt.style.strokeColor | |
this.strokeColor.red=lerp(col1,col2,'red',fac) | |
this.strokeColor.green=lerp(col1,col2,'green',fac) | |
this.strokeColor.blue=lerp(col1,col2,'blue',fac) | |
/* | |
this.strokeColor.hue=((col2.hue+360)-(col1.hue+360))*fac+col1.hue; | |
this.strokeColor.brightness=lerp(col1,col2,'brightness',fac) | |
this.strokeColor.saturation=lerp(col1,col2,'saturation',fac) | |
*/ | |
} | |
if(src.style.fillColor!=null&&tgt.style.fillColor!=null){ | |
let col1=src.style.fillColor | |
let col2=tgt.style.fillColor | |
this.fillColor.red=lerp(col1,col2,'red',fac) | |
this.fillColor.green=lerp(col1,col2,'green',fac ) | |
this.fillColor.blue=lerp(col1,col2,'blue',fac ) | |
/* | |
this.fillColor.hue=((col2.hue+360)-(col1.hue+360))*fac+col1.hue; | |
this.fillColor.brightness=lerp(col1,col2,'brightness',fac) | |
this.fillColor.saturation=lerp(col1,col2,'saturation',fac) | |
*/ | |
} | |
this.opacity=(tgt.opacity-src.opacity)*fac+src.opacity; | |
if(src.style.strokeWidth!=tgt.style.strokeWidth){ | |
this.style.strokeWidth=(tgt.style.strokeWidth-src.style.strokeWidth)*fac+src.style.strokeWidth | |
} | |
return this.interpolate(src,tgt,fac) | |
} | |
Item.prototype.interpolateGroup=function(item,fac){ | |
var len=this.children.length; | |
let start=Math.floor(fac*len) | |
let end=(start+1)%len | |
//item.interpolate2(this.children[start], this.children[end], easing( (fac*len)%1 )) | |
/* | |
if(start==0){ | |
console.log('in') | |
item.interpolate2(this.children[start], this.children[end], easeIn( (fac*len)%1 )) | |
} | |
else if(start==len-1){ | |
console.log('out') | |
item.interpolate2(this.children[start], this.children[end], easeOut( (fac*len)%1 )) | |
} | |
else { | |
*/ | |
//item.interpolate2(this.children[start], this.children[end], ease((fac*len)%1) ) | |
item.interpolate2(this.children[start], this.children[end], (fac*len)%1 ) | |
// } | |
} | |
document.addEventListener('paste', function(evt) { | |
if(document.activeElement.nodeName!="TEXTAREA"){ | |
var str=evt.clipboardData.getData('text/plain').slice(0, -1); | |
var svg=project.importSVG(str) | |
svg.clipped=false; | |
svg.children[0].remove() | |
svg.parent.insertChildren(svg.index,svg.removeChildren()); | |
svg.remove(); | |
var nullItems=new Group(project.getItems({strokeColor:null,fillColor:null})).remove() | |
var items=project.getItems({name:/^tween/}) | |
for(var it of items){ | |
var anim=new Path.Circle({radius:10,strokeColor:"red"}) | |
it.data.anim=anim | |
project.activeLayer.appendTop(anim) | |
it.visible=false | |
} | |
} | |
}) | |
item1=null | |
item2=null | |
function onFrame(e){ | |
var items=project.getItems({name:/^tween/}) | |
for(var it of items){ | |
it.interpolateGroup(it.data.anim, (e.count+(it.index*4))%80/80) | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include('http://eerojohannes.com/js/bezier-easing.js') | |
var x1=0.4 | |
var y1=0 | |
var x2=0.2 | |
var y2=1 | |
var easing=BezierEasing(x1,y1,x2,y2) | |
var w=200 | |
var h=200 | |
var sx=200 | |
var sy=200 | |
var pt1=new Point(sx,sy) | |
var pt2=new Point(sx+w,sy-h) | |
var ecurve=new Path({ | |
segments:[ | |
new Segment({ | |
point:pt1, | |
handleOut:new Point(x1*w,-y1*h) | |
}), | |
new Segment({ | |
point:pt2, | |
handleIn:new Point((x2-1)*w,(y2-1)*h) | |
}) | |
] | |
, | |
strokeWidth:2, | |
strokeColor:"white" | |
}) | |
var ept=new Shape.Circle({ | |
radius:20, | |
fillColor:"white" | |
}) | |
var eline=new Path({ | |
strokeWidth:2, | |
strokeColor:"white" | |
}) | |
eline.add(pt1) | |
eline.add(pt1-[0,h]) | |
time=0 | |
ballCount=1 | |
document.body.style.backgroundColor="#303240" | |
colors=["red","orange","yellow","green","blue","violet"] | |
ease = { | |
linear: function (t) { return t }, | |
inQuad: function (t) { return t*t }, | |
outQuad: function (t) { return t*(2-t) }, | |
inOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t }, | |
inCubic: function (t) { return t*t*t }, | |
outCubic: function (t) { return (--t)*t*t+1 }, | |
inOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }, | |
inQuart: function (t) { return t*t*t*t }, | |
outQuart: function (t) { return 1-(--t)*t*t*t }, | |
inOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t }, | |
inQuint: function (t) { return t*t*t*t*t }, | |
outQuint: function (t) { return 1+(--t)*t*t*t*t }, | |
inOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t } | |
} | |
Item.prototype.anim = function(opts){ | |
var self=this; | |
let duration=opts.duration || 500 | |
let position=opts.position || new Point(0,0) | |
let loop=opts.loop || 1 | |
var itemTypes={ | |
Path(){ | |
}, | |
Shape(){ | |
self.data.anim={position:[self.position,new Point(position[0],position[1])]} | |
self.data.anim.start=time | |
self.data.anim.loop=loop | |
self.data.anim.duration=duration | |
}, | |
Group(){ | |
for(var i in self.children){ | |
var item=self.children[i]; | |
} | |
} | |
} | |
itemTypes[this.className]() | |
return self | |
} | |
balls=[] | |
for(var i=0;i<ballCount;i++){ | |
var ball=new Shape.Circle([200,200],20) | |
ball.fillColor=colors[i%colors.length] | |
balls.push(ball) | |
} | |
var t=new Tool() | |
t.path=new Path({strokeWidth:1,strokeColor:"white"}) | |
for(var i=0;i<ballCount;i++)t.path.add([0,0]) | |
t.on({ | |
mousedown(e){ | |
for(var i=1;i<ballCount;i++){ | |
t.path.segments[i].point=balls[i].position | |
} | |
for(var i=0;i<ballCount;i++){ | |
if(i==0){ | |
var pt=e.point-balls[0].position | |
balls[i].anim({position:[e.point.x,e.point.y],duration:pt.length*2}) | |
} | |
else { | |
var pt=balls[i].position-balls[(i+1)%ballCount].position; | |
balls[i].anim({position:[balls[(i+1)%ballCount].position.x,balls[(i+1)%ballCount].position.y],duration:pt.length*2}) | |
} | |
} | |
} | |
}) | |
function onFrame(e){ | |
time=e.time*1000 | |
for(var item of project.activeLayer.children){ | |
if(item.data.anim!=null){ | |
if(time>=item.data.anim.start && time<=item.data.anim.start+item.data.anim.duration*item.data.anim.loop){ | |
pos=((time-item.data.anim.start)/item.data.anim.duration)%1; | |
pos2=easing(pos) | |
eline.position=pt1+[pos*w,-h/2]; | |
var int=ecurve.getIntersections(eline) | |
ept.position=int[0].point | |
let delta=(item.data.anim.position[1]-item.data.anim.position[0]); | |
item.position=item.data.anim.position[0]+delta.multiply(pos2) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var t=new Tool(); | |
playing=false; | |
fps=30 | |
frameCount=60/fps; | |
t.on({ | |
mousedown(e){ | |
project.deselectAll() | |
this.path=new Path({ | |
strokeWidth:2, | |
strokeColor:"red", | |
name:"aaa", | |
opacity:0.5 | |
}) | |
}, | |
mousedrag(e){ | |
//if(e.count<100) | |
this.path.add(e.point) | |
}, | |
mouseup(e){ | |
this.path.smooth(); | |
this.path.selected=true | |
}, | |
keydown(e){ | |
var test=new Path({ | |
fillColor:"blue", | |
closed:true, | |
opacity:0.8, | |
segments:[[10,10],[100,10],[100,100]] | |
}) | |
/* | |
var items=project.activeLayer.children; | |
for(var i=0;i<10;i++){ | |
var test=new Path.Circle({ | |
name:'ci', | |
radius:10, | |
position:[100,100], | |
strokeColor:"blue", | |
strokeWidth:10 | |
}) | |
test.interpolate(items[0],items[1],i/10) | |
} | |
*/ | |
} | |
}) | |
var loopLen=100 | |
function onFrame(e){ | |
var drawPos=e.count%loopLen | |
if(e.count%frameCount==0){ | |
var items=project.activeLayer.children; | |
if(project.activeLayer.children.length>3){ | |
/* | |
// Find the point on the path: | |
var pt1 = items[0].getPointAt(drawPos*(items[0].length/loopLen)); | |
var pt2 = items[1].getPointAt(drawPos*(items[1].length/loopLen)); | |
var pt3 = items[2].getPointAt(drawPos*(items[2].length/loopLen)); | |
var pt4 = items[3].getPointAt(drawPos*(items[3].length/loopLen)); | |
items[4].segments[0].point=pt1 | |
items[4].segments[1].point=pt2 | |
items[4].segments[2].point=pt3 | |
items[4].segments[3].point=pt4 | |
*/ | |
items[3].segments[0].point=items[0].segments[Math.floor(drawPos*(items[0].segments.length/loopLen))].point; | |
items[3].segments[1].point=items[1].segments[Math.floor(drawPos*(items[1].segments.length/loopLen))].point; | |
items[3].segments[2].point=items[2].segments[Math.floor(drawPos*(items[2].segments.length/loopLen))].point; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//for tiles | |
Point.prototype.toIso=function(){ | |
let x=this.x-this.y; | |
let y=(this.x+this.y)/2; | |
return new Point(x,y) | |
} | |
Point.prototype.fromIso=function(){ | |
let x=(this.x+this.y*2)/2; | |
let y=(this.y*2-this.x)/2; | |
return new Point(x,y) | |
} | |
//3d point projection 2:1 isometric | |
x=(x-z)/Math.sqrt(2) | |
y=(x+2*y+z)/Math.sqrt(8) | |
//3d point rotation | |
X = x; | |
Y = y*Math.cos(angle)-z*Math.sin(angle); | |
Z = y*Math.sin(angle)+z*Math.cos(angle); | |
X = x*Math.cos(angle)+z*Math.sin(angle); | |
Y = y; | |
Z = z*Math.cos(angle)-x*Math.sin(angle); | |
X = x*Math.cos(angle)-y*Math.sin(angle); | |
Y = x*Math.sin(angle)+y*Math.cos(angle); | |
Z = z; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment