Skip to content

Instantly share code, notes, and snippets.

@eeropic
Last active May 27, 2018 17:57
Show Gist options
  • Save eeropic/10789820b03c2326584956915181e98c to your computer and use it in GitHub Desktop.
Save eeropic/10789820b03c2326584956915181e98c to your computer and use it in GitHub Desktop.
paper.js sketches 2018
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
}
}
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)
}
}
}
}
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
}
}
}
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)
}
}
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)
}
}
}
}
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;
}
}
}
//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