Flat, round, designer-friendly pseudo-3D engine for canvas & SVG
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

🎩 lerp keyframes

fix codepen-logo

+96 -86
+9 -9
demo/castle/castle.js
··· 240 240 // ]; 241 241 242 242 var keyframes = [ 243 - { x: 0, y: 1/4 }, 244 - { x: -35/350, y: 5/8 }, 245 - { x: -1/4, y: 3/4 }, 246 - { x: -35/350, y: 9/8 }, 247 - { x: 0, y: 5/4 }, 243 + { x: TAU * 0, y: TAU * 1/4 }, 244 + { x: TAU * -35/360, y: TAU * 5/8 }, 245 + { x: TAU * -1/4, y: TAU * 3/4 }, 246 + { x: TAU * -35/360, y: TAU * 9/8 }, 247 + { x: TAU * 0, y: TAU * 5/4 }, 248 248 ]; 249 249 250 250 function animate() { ··· 253 253 var easeT = Zdog.easeInOut( t % 1, 4 ); 254 254 var turnLimit = keyframes.length - 1; 255 255 var turn = Math.floor( t % turnLimit ); 256 - var keyframeA = keyframes[ turn ]; 257 - var keyframeB = keyframes[ turn + 1 ]; 258 - illo.rotate.x = Zdog.lerp( keyframeA.x * TAU, keyframeB.x * TAU, easeT ); 259 - illo.rotate.y = Zdog.lerp( keyframeA.y * TAU, keyframeB.y * TAU, easeT ); 256 + var keyA = keyframes[ turn ]; 257 + var keyB = keyframes[ turn + 1 ]; 258 + illo.rotate.x = Zdog.lerp( keyA.x, keyB.x, easeT ); 259 + illo.rotate.y = Zdog.lerp( keyA.y, keyB.y, easeT ); 260 260 t += tSpeed; 261 261 } 262 262
+2 -4
demo/codepen-logo/codepen-logo.js
··· 80 80 illo.rotate.z = Zdog.lerp( TAU/8 * -3, TAU/8, easeT ); 81 81 illo.rotate.x = Zdog.lerp( 0, tiltAngle, easeT ); 82 82 } else if ( turn == 1 ) { 83 - illo.rotate.x = Zdog.lerp( -TAU/2, 0, easeT ); 83 + prism.rotate.x = Zdog.lerp( -TAU/2, 0, easeT ); 84 84 } 85 85 t += tSpeed; 86 86 } 87 87 88 - illo.updateGraph(); 89 - 90 - illo.renderGraph(); 88 + illo.updateRenderGraph(); 91 89 requestAnimationFrame( animate ); 92 90 } 93 91
+17 -11
demo/cones/cones.js
··· 120 120 121 121 // -- animate --- // 122 122 123 + var keyframes = [ 124 + { x: TAU * 0, y: TAU * 0 }, 125 + { x: TAU * 1/2, y: TAU * 1/2 }, 126 + { x: TAU * 1, y: TAU * 1 }, 127 + ]; 128 + 123 129 var t = 0; 124 - var cycleFrame = 360; 125 130 126 131 function animate() { 127 - rotate(); 132 + spin(); 128 133 illo.updateRenderGraph(); 129 134 requestAnimationFrame( animate ); 130 135 } ··· 133 138 134 139 // -- update -- // 135 140 136 - function rotate() { 141 + function spin() { 137 142 if ( !isSpinning ) { 138 143 return; 139 144 } 140 - t += 1/cycleFrame; 141 - t = t % 1; 142 - var isFirstHalf = t < 0.5; 143 - var halfT = isFirstHalf ? t : t - 0.5; 144 - var doubleEaseT = Zdog.easeInOut( halfT*2 % 1, 3 ) / 2; 145 - doubleEaseT += isFirstHalf ? 0 : 0.5; 146 - illo.rotate.y = doubleEaseT * TAU; 147 - illo.rotate.x = Math.cos( doubleEaseT * TAU ) * TAU/12; 145 + var easeT = Zdog.easeInOut( t % 1, 3 ); 146 + var turnLimit = keyframes.length - 1; 147 + var turn = Math.floor( t % turnLimit ); 148 + var keyA = keyframes[ turn ]; 149 + var keyB = keyframes[ turn + 1 ]; 150 + var thetaX = Zdog.lerp( keyA.x, keyB.x, easeT ); 151 + illo.rotate.x = Math.cos( thetaX ) * TAU/12; 152 + illo.rotate.y = Zdog.lerp( keyA.y, keyB.y, easeT ) ; 153 + t += 1/180; 148 154 }
+17 -12
demo/cylinders/cylinders.js
··· 83 83 84 84 // -- animate --- // 85 85 86 + var keyframes = [ 87 + { x: TAU * 0, y: TAU * 0 }, 88 + { x: TAU * 1/2, y: TAU * 1/2 }, 89 + { x: TAU * 1, y: TAU * 1 }, 90 + ]; 91 + 86 92 var t = 0; 87 - var cycleFrame = 360; 88 93 89 94 function animate() { 90 - rotate(); 95 + spin(); 91 96 illo.updateRenderGraph(); 92 97 requestAnimationFrame( animate ); 93 98 } ··· 96 101 97 102 // -- update -- // 98 103 99 - function rotate() { 104 + function spin() { 100 105 if ( !isSpinning ) { 101 106 return; 102 107 } 103 - 104 - t += 1/cycleFrame; 105 - t = t % 1; 106 - var isFirstHalf = t < 0.5; 107 - var halfT = isFirstHalf ? t : t - 0.5; 108 - var doubleEaseT = Zdog.easeInOut( halfT*2 % 1, 3 ) / 2; 109 - doubleEaseT += isFirstHalf ? 0 : 0.5; 110 - illo.rotate.y = doubleEaseT * TAU; 111 - illo.rotate.x = Math.cos( doubleEaseT * TAU ) * TAU/12; 108 + var easeT = Zdog.easeInOut( t % 1, 3 ); 109 + var turnLimit = keyframes.length - 1; 110 + var turn = Math.floor( t % turnLimit ); 111 + var keyA = keyframes[ turn ]; 112 + var keyB = keyframes[ turn + 1 ]; 113 + var thetaX = Zdog.lerp( keyA.x, keyB.x, easeT ); 114 + illo.rotate.x = Math.cos( thetaX ) * TAU/12; 115 + illo.rotate.y = Zdog.lerp( keyA.y, keyB.y, easeT ) ; 116 + t += 1/180; 112 117 } 113 118
+15 -10
demo/hemisphere-ball/hemisphere-ball.js
··· 70 70 71 71 // -- animate --- // 72 72 73 + var keyframes = [ 74 + { x: TAU * 0, y: TAU * 0 }, 75 + { x: TAU * 1/2, y: TAU * 1/2 }, 76 + { x: TAU * 1, y: TAU * 1 }, 77 + ]; 78 + 73 79 var t = 0; 74 - var cycleFrame = 360; 75 80 76 81 function animate() { 77 82 rotate(); ··· 87 92 if ( !isSpinning ) { 88 93 return; 89 94 } 90 - 91 - t += 1/cycleFrame; 92 - t = t % 1; 93 - var isFirstHalf = t < 0.5; 94 - var halfT = isFirstHalf ? t : t - 0.5; 95 - var doubleEaseT = Zdog.easeInOut( halfT*2 % 1, 3 ) / 2; 96 - doubleEaseT += isFirstHalf ? 0 : 0.5; 97 - illo.rotate.y = doubleEaseT * TAU; 98 - illo.rotate.x = Math.cos( doubleEaseT * TAU ) * TAU/12; 95 + var easeT = Zdog.easeInOut( t % 1, 3 ); 96 + var turnLimit = keyframes.length - 1; 97 + var turn = Math.floor( t % turnLimit ); 98 + var keyA = keyframes[ turn ]; 99 + var keyB = keyframes[ turn + 1 ]; 100 + var thetaX = Zdog.lerp( keyA.x, keyB.x, easeT ); 101 + illo.rotate.x = Math.cos( thetaX ) * TAU/12; 102 + illo.rotate.y = Zdog.lerp( keyA.y, keyB.y, easeT ) ; 103 + t += 1/180; 99 104 }
+15 -9
demo/hemisphere-cone-ball/hemisphere-cone-ball.js
··· 75 75 76 76 // -- animate --- // 77 77 78 + var keyframes = [ 79 + { x: TAU * 0, y: TAU * 0 }, 80 + { x: TAU * 1/2, y: TAU * 1/2 }, 81 + { x: TAU * 1, y: TAU * 1 }, 82 + ]; 83 + 78 84 var t = 0; 79 85 var cycleFrame = 360; 80 86 ··· 92 98 if ( !isSpinning ) { 93 99 return; 94 100 } 95 - 96 - t += 1/cycleFrame; 97 - t = t % 1; 98 - var isFirstHalf = t < 0.5; 99 - var halfT = isFirstHalf ? t : t - 0.5; 100 - var doubleEaseT = Zdog.easeInOut( halfT*2 % 1, 3 ) / 2; 101 - doubleEaseT += isFirstHalf ? 0 : 0.5; 102 - illo.rotate.y = doubleEaseT * TAU; 103 - illo.rotate.x = Math.cos( doubleEaseT * TAU ) * TAU/12; 101 + var easeT = Zdog.easeInOut( t % 1, 3 ); 102 + var turnLimit = keyframes.length - 1; 103 + var turn = Math.floor( t % turnLimit ); 104 + var keyA = keyframes[ turn ]; 105 + var keyB = keyframes[ turn + 1 ]; 106 + var thetaX = Zdog.lerp( keyA.x, keyB.x, easeT ); 107 + illo.rotate.x = Math.cos( thetaX ) * TAU/12; 108 + illo.rotate.y = Zdog.lerp( keyA.y, keyB.y, easeT ) ; 109 + t += 1/180; 104 110 }
+21 -31
demo/tri-prism/tri-prism.js
··· 97 97 return prism; 98 98 } 99 99 100 - var prismA = makePrism({ 101 - 102 - }); 100 + var prismA = makePrism({}); 103 101 104 102 var prismB = makePrism({ 105 103 rotate: { x: TAU/4, z: TAU/4 }, ··· 116 114 117 115 // -- update -- // 118 116 119 - var transforms = { 120 - 0: function( prism, easeT ) { 121 - prism.children[0].rotate.y = 0; 122 - prism.children[0].rotate.z = 0; 123 - prism.children[0].rotate.x = easeT; 124 - }, 125 - 1: function( prism, easeT ) { 126 - prism.children[0].rotate.y = -easeT; 127 - }, 128 - 2: function( prism, easeT ) { 129 - prism.children[0].rotate.y = -easeT - TAU/4; 130 - }, 131 - 3: function( prism, easeT ) { 132 - prism.children[0].rotate.z = -easeT; 133 - }, 134 - 4: function( prism, easeT ) { 135 - prism.children[0].rotate.z = -easeT - TAU/4; 136 - }, 137 - 5: function( prism, easeT ) { 138 - prism.children[0].rotate.x = easeT + TAU/4; 139 - }, 117 + var keyframes = [ 118 + { x: 0, y: 0, z: 0 }, 119 + { x: 1, y: 0, z: 0 }, 120 + { x: 1, y: -1, z: 0 }, 121 + { x: 1, y: -2, z: 0 }, 122 + { x: 1, y: -2, z: -1 }, 123 + { x: 1, y: -2, z: -2 }, 124 + { x: 2, y: -2, z: -2 }, 125 + ]; 140 126 141 - }; 127 + function transform( shape, turn, alpha ) { 128 + var keyA = keyframes[ turn ]; 129 + var keyB = keyframes[ turn + 1 ]; 130 + shape.rotate.x = Zdog.lerp( keyA.x, keyB.x, alpha ) * TAU/4; 131 + shape.rotate.y = Zdog.lerp( keyA.y, keyB.y, alpha ) * TAU/4; 132 + shape.rotate.z = Zdog.lerp( keyA.z, keyB.z, alpha ) * TAU/4; 133 + } 142 134 143 135 function update() { 144 - var easeT = Zdog.easeInOut( t % 1, 4 ) * TAU/4; 145 - 136 + var easeT = Zdog.easeInOut( t % 1, 4 ); 146 137 var turn = Math.floor( t % 6 ); 147 - var transform = transforms[ turn ]; 148 138 149 - transform( prismA, easeT ); 150 - transform( prismB, easeT ); 151 - transform( prismC, easeT ); 139 + transform( prismA.children[0], turn, easeT ); 140 + transform( prismB.children[0], turn, easeT ); 141 + transform( prismC.children[0], turn, easeT ); 152 142 153 143 t += tSpeed; 154 144