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.

๐Ÿ’€ remove demo/. Move to zdog-demos repo

-13316
-136
demo/bird-house/bird-house.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 7 - var zoom = Math.floor( minWindowSize / w ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - var isSpinning = false; 11 - var TAU = Zdog.TAU; 12 - // colors 13 - var yellow = "#ED0"; 14 - var gold = '#EA0'; 15 - var orange = '#E62'; 16 - var garnet = '#C25'; 17 - var eggplant = '#636'; 18 - 19 - [ Zdog.Shape, Zdog.Ellipse, Zdog.Rect ].forEach( function( ShapeClass ) { 20 - ShapeClass.defaults.stroke = 1/zoom; 21 - ShapeClass.defaults.fill = true; 22 - }); 23 - 24 - var illo = new Zdog.Illustration({ 25 - element: illoElem, 26 - zoom: zoom, 27 - dragRotate: true, 28 - onDragStart: function() { 29 - isSpinning = false; 30 - }, 31 - }); 32 - 33 - // -- illustration shapes --- // 34 - 35 - var house = new Zdog.Anchor({ 36 - addTo: illo, 37 - scale: 4, 38 - }); 39 - 40 - var frontGroup = new Zdog.Group({ 41 - addTo: house, 42 - translate: { z: 2 }, 43 - }); 44 - 45 - var gable = new Zdog.Shape({ 46 - addTo: frontGroup, 47 - path: [ 48 - { x: 0, y: -2 }, 49 - { x: 2, y: 0 }, 50 - { x: 2, y: 2 }, 51 - { x: -2, y: 2 }, 52 - { x: -2, y: 0 }, 53 - ], 54 - closed: true, 55 - color: gold, 56 - }); 57 - gable.copy({ 58 - addTo: house, 59 - translate: { z: -2 }, 60 - color: garnet, 61 - }); 62 - 63 - // hole 64 - new Zdog.Ellipse({ 65 - addTo: frontGroup, 66 - diameter: 1.25, 67 - color: eggplant, 68 - stroke: false, 69 - }); 70 - 71 - var side = new Zdog.Rect({ 72 - addTo: house, 73 - width: 4, 74 - height: 2, 75 - rotate: { y: TAU/4 }, 76 - translate: { x: 2, y: 1 }, 77 - color: orange, 78 - }); 79 - side.copy({ 80 - translate: { x: -2, y: 1 }, 81 - color: garnet, 82 - }); 83 - 84 - var roofAnchor = new Zdog.Anchor({ 85 - addTo: house, 86 - translate: { y: -2 }, 87 - rotate: { z: -TAU/8 }, 88 - }); 89 - 90 - var roofW = Math.sqrt(2) * 2; 91 - // var roofW = 4; 92 - 93 - var roof = new Zdog.Rect({ 94 - addTo: roofAnchor, 95 - width: roofW, 96 - height: 4, 97 - translate: { x: -roofW/2 }, 98 - rotate: { x: TAU/4 }, 99 - color: orange, 100 - backface: eggplant, 101 - }); 102 - 103 - roof.copy({ 104 - width: 1, 105 - translate: { x: -roofW - 0.5 }, 106 - // color: gold, 107 - }); 108 - 109 - var roofCopy = roofAnchor.copyGraph({ 110 - scale: { x: -1 }, 111 - rotate: { z: TAU/8 }, 112 - }); 113 - 114 - roofCopy.children[0].color = yellow; 115 - roofCopy.children[1].color = yellow; 116 - 117 - // base 118 - new Zdog.Rect({ 119 - addTo: house, 120 - width: 4, 121 - height: 4, 122 - translate: { y: 2 }, 123 - rotate: { x: TAU/4 }, 124 - color: eggplant, 125 - }); 126 - 127 - // -- animate --- // 128 - 129 - function animate() { 130 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 131 - illo.updateRenderGraph(); 132 - requestAnimationFrame( animate ); 133 - } 134 - 135 - animate(); 136 -
-51
demo/bird-house/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>bird house</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #FDB; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="bird-house.js"></script> 49 - 50 - </body> 51 - </html>
-271
demo/castle/castle.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 24; 5 - var h = 24; 6 - var minWindowSize = Math.min( window.innerWidth - 20, window.innerHeight - 40 ); 7 - var zoom = Math.floor( minWindowSize / w ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - [ Zdog.Shape, Zdog.Rect ].forEach( function( ItemClass ) { 12 - ItemClass.defaults.fill = true; 13 - // ItemClass.defaults.stroke = true; 14 - ItemClass.defaults.backface = false; 15 - ItemClass.defaults.stroke = 1/zoom; 16 - }); 17 - 18 - var white = 'white'; 19 - var black = '#333'; 20 - var isSpinning = true; 21 - var TAU = Zdog.TAU; 22 - var initRotate = { y: TAU/4 }; 23 - 24 - var illo = new Zdog.Illustration({ 25 - element: illoElem, 26 - zoom: zoom, 27 - rotate: initRotate, 28 - dragRotate: true, 29 - onDragStart: function() { 30 - isSpinning = false; 31 - }, 32 - }); 33 - 34 - // -- illustration shapes --- // 35 - 36 - function makeWall( options ) { 37 - var rotor = new Zdog.Anchor({ 38 - addTo: illo, 39 - rotate: options.rotate, 40 - }); 41 - 42 - // rotor 43 - var wall = new Zdog.Anchor({ 44 - addTo: rotor, 45 - translate: { z: 4 }, 46 - }); 47 - 48 - var topBlock = new Zdog.Anchor({ 49 - addTo: wall, 50 - translate: { x: -4, y: -4 }, 51 - }); 52 - 53 - // side faces 54 - var face = new Zdog.Rect({ 55 - addTo: topBlock, 56 - width: 2, 57 - height: 2, 58 - translate: { z: 1 }, 59 - color: options.outside, 60 - }); 61 - face.copy({ 62 - translate: { x: -1 }, 63 - rotate: { y: TAU/4 }, 64 - color: options.left, 65 - }); 66 - face.copy({ 67 - translate: { x: 1 }, 68 - rotate: { y: -TAU/4 }, 69 - color: options.right, 70 - }); 71 - face.copy({ 72 - translate: { z: -1 }, 73 - rotate: { y: TAU/2 }, 74 - color: options.inside, 75 - }); 76 - // top 77 - face.copy({ 78 - translate: { y: -1 }, 79 - rotate: { x: TAU/4 }, 80 - color: black, 81 - }); 82 - 83 - topBlock.copyGraph({ 84 - translate: { x: 0, y: -4 }, 85 - }); 86 - 87 - var topTile = new Zdog.Rect({ 88 - addTo: wall, 89 - width: 2, 90 - height: 2, 91 - color: black, 92 - rotate: { x: TAU/4 }, 93 - translate: { x: -2, y: -3 }, 94 - }); 95 - topTile.copy({ 96 - translate: { x: 2, y: -3 } 97 - }); 98 - 99 - // outside arch 100 - 101 - // outside arch 102 - var arch = new Zdog.Shape({ 103 - addTo: wall, 104 - path: [ 105 - { x: 0, y: -3 }, 106 - { x: 3, y: -3 }, 107 - { x: 3, y: 2 }, 108 - { arc: [ 109 - { x: 3, y: -1 }, 110 - { x: 0, y: -1 } 111 - ]}, 112 - ], 113 - translate: { z: 1 }, 114 - color: options.outside, 115 - }); 116 - arch.copy({ 117 - scale: { x: -1 }, 118 - }); 119 - 120 - 121 - // inside arch 122 - arch.copy({ 123 - translate: { z: -1 }, 124 - rotate: { y: TAU/2 }, 125 - color: options.inside, 126 - }); 127 - arch.copy({ 128 - translate: { z: -1 }, 129 - rotate: { y: TAU/2 }, 130 - scale: { x: -1 }, 131 - color: options.inside, 132 - }); 133 - 134 - // outside columns 135 - var outsideColumn = new Zdog.Rect({ 136 - addTo: wall, 137 - width: 2, 138 - height: 8, 139 - translate: { x: -4, y: 1, z: 1 }, 140 - color: options.outside, 141 - }); 142 - outsideColumn.copy({ 143 - translate: { x: 4, y: 1, z: 1 }, 144 - }); 145 - 146 - var insideColumn = new Zdog.Rect({ 147 - addTo: wall, 148 - width: 2, 149 - height: 3, 150 - translate: { x: -3, y: 3.5 }, 151 - rotate: { y: -TAU/4 }, 152 - color: options.right, 153 - }); 154 - insideColumn.copy({ 155 - translate: { x: 3, y: 3.5 }, 156 - rotate: { y: TAU/4 }, 157 - color: options.left, 158 - }); 159 - 160 - // under arch, quarter arc 161 - var underArch = new Zdog.Shape({ 162 - addTo: wall, 163 - path: [ 164 - { x: 3, y: 2 }, 165 - { arc: [ 166 - { x: 3, y: -1 }, 167 - { x: 0, y: -1 } 168 - ]}, 169 - { x: 0, y: -1, z: -2 }, 170 - { arc: [ 171 - { x: 3, y: -1, z: -2 }, 172 - { x: 3, y: 2, z: -2 }, 173 - ]}, 174 - ], 175 - translate: { z: 1 }, 176 - backface: true, 177 - color: options.left, 178 - }); 179 - underArch.copyGraph({ 180 - scale: { x: -1 }, 181 - color: options.right, 182 - }); 183 - 184 - // feet soles 185 - new Zdog.Rect({ 186 - addTo: wall, 187 - width: 2, 188 - height: 2, 189 - translate: { x: -4, y: 5, z: 0 }, 190 - rotate: { x: -TAU/4 }, 191 - color: white, 192 - }); 193 - 194 - } 195 - 196 - makeWall({ 197 - rotate: {}, 198 - outside: white, 199 - inside: black, 200 - left: white, 201 - right: black, 202 - }); 203 - 204 - makeWall({ 205 - rotate: { y: -TAU/4 }, 206 - outside: black, 207 - inside: white, 208 - left: white, 209 - right: black, 210 - }); 211 - 212 - makeWall({ 213 - rotate: { y: -TAU/2 }, 214 - outside: black, 215 - inside: white, 216 - left: black, 217 - right: white, 218 - }); 219 - 220 - makeWall({ 221 - rotate: { y: TAU * -3/4 }, 222 - outside: white, 223 - inside: black, 224 - left: black, 225 - right: white, 226 - }); 227 - 228 - 229 - // -- animate --- // 230 - 231 - var t = 0; 232 - var tSpeed = 1/105; 233 - 234 - // var keyframes = [ 235 - // { x: -1/4, y: -1/4 }, 236 - // { x: -35/350, y: 1/8 }, 237 - // { x: 0, y: 2/4 }, 238 - // { x: -35/350, y: 5/8 }, 239 - // { x: -1/4, y: 3/4 }, 240 - // ]; 241 - 242 - var keyframes = [ 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 - ]; 249 - 250 - function animate() { 251 - // update 252 - if ( isSpinning ) { 253 - var easeT = Zdog.easeInOut( t % 1, 4 ); 254 - var turnLimit = keyframes.length - 1; 255 - var turn = Math.floor( t % turnLimit ); 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 - t += tSpeed; 261 - } 262 - 263 - illo.updateGraph(); 264 - 265 - // render 266 - illo.renderGraph(); 267 - requestAnimationFrame( animate ); 268 - } 269 - 270 - animate(); 271 -
-49
demo/castle/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>castle</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/rect.js"></script> 44 - <script src="../../js/dragger.js"></script> 45 - <script src="../../js/illustration.js"></script> 46 - <script src="castle.js"></script> 47 - 48 - </body> 49 - </html>
-103
demo/codepen-logo/codepen-logo.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.floor( minWindowSize / w ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var TAU = Zdog.TAU; 12 - var isSpinning = true; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - scale: 4, 17 - zoom: zoom, 18 - dragRotate: true, 19 - onDragStart: function() { 20 - isSpinning = false; 21 - }, 22 - }); 23 - 24 - var tiltAngle = Math.asin(2/3); 25 - 26 - var prism = new Zdog.Anchor({ 27 - addTo: illo, 28 - }); 29 - 30 - // -- illustration shapes --- // 31 - 32 - var RT2 = Math.sqrt(2); 33 - var capLength = 6/RT2; 34 - var sideLength = 2 / Math.cos( tiltAngle ); 35 - var sideZ = sideLength/2; 36 - 37 - var cap = new Zdog.Rect({ 38 - width: capLength, 39 - height: capLength, 40 - addTo: prism, 41 - translate: { z: -sideZ }, 42 - stroke: 2, 43 - color: 'white', 44 - }); 45 - 46 - cap.copy({ 47 - translate: { z: sideZ }, 48 - }); 49 - 50 - var side = new Zdog.Shape({ 51 - addTo: prism, 52 - path: [ { z: -1 }, { z: 1 } ], 53 - scale: sideZ, 54 - translate: { x: capLength/2, y: capLength/2 }, 55 - stroke: 2, 56 - color: 'white', 57 - }); 58 - side.copy({ 59 - translate: { x: -capLength/2, y: capLength/2 }, 60 - }); 61 - side.copy({ 62 - translate: { x: -capLength/2, y: -capLength/2 }, 63 - }); 64 - side.copy({ 65 - translate: { x: capLength/2, y: -capLength/2 }, 66 - }); 67 - 68 - // -- animate --- // 69 - 70 - var t = 0; 71 - var tSpeed = 1/90; 72 - 73 - 74 - function animate() { 75 - // update 76 - if ( isSpinning ) { 77 - var easeT = Zdog.easeInOut( t % 1, 3 ); 78 - var turn = Math.floor( t ); 79 - if ( turn === 0 ) { 80 - illo.rotate.z = Zdog.lerp( TAU/8 * -3, TAU/8, easeT ); 81 - illo.rotate.x = Zdog.lerp( 0, tiltAngle, easeT ); 82 - } else if ( turn == 1 ) { 83 - prism.rotate.x = Zdog.lerp( -TAU/2, 0, easeT ); 84 - } 85 - t += tSpeed; 86 - } 87 - 88 - illo.updateRenderGraph(); 89 - requestAnimationFrame( animate ); 90 - } 91 - 92 - animate(); 93 - 94 - 95 - // ----- inputs ----- // 96 - 97 - document.querySelector('.reset-button').onclick = reset; 98 - 99 - function reset() { 100 - t = 0; 101 - illo.rotate.set({}); 102 - isSpinning = true; 103 - }
-51
demo/codepen-logo/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>codepen-logo</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #191A1D; 19 - color: white; 20 - font-family: sans-serif; 21 - text-align: center; 22 - } 23 - 24 - .illo { 25 - display: block; 26 - margin: 0px auto 20px; 27 - cursor: move; 28 - } 29 - </style> 30 - 31 - </head> 32 - <body> 33 - 34 - <div class="container"> 35 - <canvas class="illo"></canvas> 36 - <p><button class="reset-button">Reset</button></p> 37 - </div> 38 - 39 - <script src="../../js/boilerplate.js"></script> 40 - <script src="../../js/canvas-renderer.js"></script> 41 - <script src="../../js/vector.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/path-command.js"></script> 44 - <script src="../../js/shape.js"></script> 45 - <script src="../../js/rect.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="codepen-logo.js"></script> 49 - 50 - </body> 51 - </html>
-101
demo/composite-shapes-scale-svg/composite-shapes-scale-svg.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var svg = document.querySelector('svg'); 4 - var sceneSize = 48; 5 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 6 - var zoom = Math.floor( minWindowSize / sceneSize ); 7 - svg.setAttribute( 'width', sceneSize * zoom ); 8 - svg.setAttribute( 'height', sceneSize * zoom ); 9 - var isSpinning = true; 10 - var TAU = Zdog.TAU; 11 - 12 - var illo = new Zdog.Illustration({ 13 - element: svg, 14 - zoom: zoom, 15 - scale: 2, 16 - dragRotate: true, 17 - onDragStart: function() { 18 - isSpinning = false; 19 - }, 20 - }); 21 - 22 - // -- illustration shapes --- // 23 - 24 - new Zdog.Rect({ 25 - width: 10, 26 - height: 10, 27 - addTo: illo, 28 - translate: { z: -10 }, 29 - stroke: 2, 30 - color: '#E21', 31 - }); 32 - 33 - /* 34 - new Zdog.Ellipse({ 35 - diameter: 16, 36 - addTo: illo, 37 - translate: { z: 10 }, 38 - stroke: 4, 39 - color: '#19F', 40 - }); 41 - 42 - new Zdog.Shape({ 43 - path: [ 44 - { x: 0, z: 1 }, 45 - { x: -1, z: -1 }, 46 - { x: 1, z: -1 }, 47 - ], 48 - scale: { x: 5, z: 5 }, 49 - addTo: illo, 50 - stroke: 2, 51 - fill: true, 52 - color: '#EA0', 53 - }); 54 - */ 55 - 56 - new Zdog.Hemisphere({ 57 - diameter: 4, 58 - scale: 2, 59 - addTo: illo, 60 - translate: { x: 8 }, 61 - color: '#EA0', 62 - backface: '#456', 63 - stroke: false, 64 - }); 65 - 66 - var cyl = new Zdog.Cylinder({ 67 - diameter: 4, 68 - length: 4, 69 - scale: 2, 70 - addTo: illo, 71 - translate: { x: 0 }, 72 - color: '#C25', 73 - backface: '#E62', 74 - frontBaseColor: '#EA0', 75 - rearBaseColor: '#636', 76 - stroke: false, 77 - }); 78 - 79 - new Zdog.Cone({ 80 - diameter: 4, 81 - length: 3, 82 - scale: 2, 83 - addTo: illo, 84 - translate: { x: -8 }, 85 - color: '#456', 86 - backface: '#EA0', 87 - stroke: false, 88 - }); 89 - 90 - // -- animate --- // 91 - 92 - function animate() { 93 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 94 - illo.updateGraph(); 95 - illo.renderGraph(); 96 - requestAnimationFrame( animate ); 97 - } 98 - 99 - animate(); 100 - 101 - // -- update -- //
-54
demo/composite-shapes-scale-svg/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>composite-shapes-scale-svg</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - svg { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <svg></svg> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/svg-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/hemisphere.js"></script> 47 - <script src="../../js/cylinder.js"></script> 48 - <script src="../../js/cone.js"></script> 49 - <script src="../../js/dragger.js"></script> 50 - <script src="../../js/illustration.js"></script> 51 - <script src="composite-shapes-scale-svg.js"></script> 52 - 53 - </body> 54 - </html>
-103
demo/composite-shapes-scale/composite-shapes-scale.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 8, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var TAU = Zdog.TAU; 12 - var isSpinning = true; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - scale: 2, 18 - dragRotate: true, 19 - onDragStart: function() { 20 - isSpinning = false; 21 - }, 22 - }); 23 - 24 - // -- illustration shapes --- // 25 - 26 - new Zdog.Rect({ 27 - width: 10, 28 - height: 10, 29 - addTo: illo, 30 - translate: { z: -10 }, 31 - stroke: 2, 32 - color: '#E21', 33 - }); 34 - 35 - /* 36 - new Zdog.Ellipse({ 37 - diameter: 16, 38 - addTo: illo, 39 - translate: { z: 10 }, 40 - stroke: 4, 41 - color: '#19F', 42 - }); 43 - 44 - new Zdog.Shape({ 45 - path: [ 46 - { x: 0, z: 1 }, 47 - { x: -1, z: -1 }, 48 - { x: 1, z: -1 }, 49 - ], 50 - scale: { x: 5, z: 5 }, 51 - addTo: illo, 52 - stroke: 2, 53 - fill: true, 54 - color: '#EA0', 55 - }); 56 - */ 57 - 58 - new Zdog.Hemisphere({ 59 - diameter: 4, 60 - scale: 2, 61 - addTo: illo, 62 - translate: { x: 8 }, 63 - color: '#EA0', 64 - backface: '#456', 65 - stroke: false, 66 - }); 67 - 68 - var cyl = new Zdog.Cylinder({ 69 - diameter: 4, 70 - length: 4, 71 - scale: 2, 72 - addTo: illo, 73 - translate: { x: 0 }, 74 - color: '#C25', 75 - backface: '#E62', 76 - frontBaseColor: '#EA0', 77 - rearBaseColor: '#636', 78 - stroke: false, 79 - }); 80 - 81 - new Zdog.Cone({ 82 - diameter: 4, 83 - length: 3, 84 - scale: 2, 85 - addTo: illo, 86 - translate: { x: -8 }, 87 - color: '#456', 88 - backface: '#EA0', 89 - stroke: false, 90 - }); 91 - 92 - // -- animate --- // 93 - 94 - function animate() { 95 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 96 - illo.updateGraph(); 97 - illo.renderGraph(); 98 - requestAnimationFrame( animate ); 99 - } 100 - 101 - animate(); 102 - 103 - // -- update -- //
-54
demo/composite-shapes-scale/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>composite-shapes-scale</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/hemisphere.js"></script> 47 - <script src="../../js/cylinder.js"></script> 48 - <script src="../../js/cone.js"></script> 49 - <script src="../../js/dragger.js"></script> 50 - <script src="../../js/illustration.js"></script> 51 - <script src="composite-shapes-scale.js"></script> 52 - 53 - </body> 54 - </html>
-154
demo/cones/cones.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 64; 5 - var h = 64; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 10, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // colors 24 - var yellow = '#ED0'; 25 - // var gold = '#EA0'; 26 - var orange = '#E62'; 27 - var magenta = '#C25'; 28 - // var navy = '#249'; 29 - var beige = '#FEC'; 30 - var blue = '#8AD'; 31 - 32 - 33 - var colorWheel = [ beige, magenta, orange, blue, yellow ]; 34 - 35 - // -- illustration shapes --- // 36 - 37 - // top & bottom 38 - var cone = new Zdog.Cone({ 39 - diameter: 8, 40 - length: 10, 41 - addTo: illo, 42 - translate: { y: -16 }, 43 - // scale: { x: 2, y: 2 }, 44 - rotate: { x: -TAU/4 }, 45 - color: colorWheel[1], 46 - backface: colorWheel[0], 47 - stroke: false, 48 - }); 49 - cone.copy({ 50 - translate: { y: 16 }, 51 - rotate: { x: TAU/4 }, 52 - }); 53 - 54 - 55 - 56 - [ -1, 1 ].forEach( function( ySide ) { 57 - for ( var i=0; i < 5; i++ ) { 58 - var rotor1 = new Zdog.Anchor({ 59 - addTo: illo, 60 - rotate: { y: TAU/5 * i }, 61 - }); 62 - var rotor2 = new Zdog.Anchor({ 63 - addTo: rotor1, 64 - rotate: { x: TAU/6 }, 65 - }); 66 - 67 - cone.copy({ 68 - addTo: rotor2, 69 - translate: { y: 16*ySide }, 70 - rotate: { x: TAU/4*ySide }, 71 - color: colorWheel[i], 72 - backface: colorWheel[ (i+7) % 5 ], 73 - }); 74 - } 75 - }); 76 - 77 - [ -1, 1 ].forEach( function( ySide ) { 78 - for ( var i=0; i < 5; i++ ) { 79 - var rotor1 = new Zdog.Anchor({ 80 - addTo: illo, 81 - rotate: { y: TAU/5 * (i+0.5) }, 82 - }); 83 - var rotor2 = new Zdog.Anchor({ 84 - addTo: rotor1, 85 - rotate: { x: TAU/10 }, 86 - }); 87 - 88 - cone.copy({ 89 - addTo: rotor2, 90 - translate: { y: -16*ySide }, 91 - rotate: { x: TAU/4*ySide }, 92 - color: colorWheel[ (i+3) % 5 ], 93 - backface: colorWheel[i], 94 - }); 95 - } 96 - }); 97 - 98 - [ -1, 1 ].forEach( function( ySide ) { 99 - for ( var i=0; i < 5; i++ ) { 100 - var rotor1 = new Zdog.Anchor({ 101 - addTo: illo, 102 - rotate: { y: TAU/5 * (i+0.5) }, 103 - }); 104 - var rotor2 = new Zdog.Anchor({ 105 - addTo: rotor1, 106 - rotate: { x: TAU/4.5 }, 107 - }); 108 - 109 - cone.copy({ 110 - addTo: rotor2, 111 - translate: { y: -16*ySide }, 112 - // scale: { y: -1 }, 113 - rotate: { x: TAU/4*ySide }, 114 - color: colorWheel[ (i+1) % 5 ], 115 - backface: colorWheel[ (i+4) % 5 ], 116 - }); 117 - } 118 - }); 119 - 120 - 121 - // -- animate --- // 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 - 129 - var t = 0; 130 - 131 - function animate() { 132 - spin(); 133 - illo.updateRenderGraph(); 134 - requestAnimationFrame( animate ); 135 - } 136 - 137 - animate(); 138 - 139 - // -- update -- // 140 - 141 - function spin() { 142 - if ( !isSpinning ) { 143 - return; 144 - } 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; 154 - }
-51
demo/cones/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>cones</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #246; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/group.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/cone.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="cones.js"></script> 49 - 50 - </body> 51 - </html>
-236
demo/crypto-kitty/crypto-kitty.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 64; 5 - var h = 64; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 10, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - rotate: { x: -TAU/32 }, 18 - dragRotate: true, 19 - onDragStart: function() { 20 - isSpinning = false; 21 - }, 22 - }); 23 - 24 - // colors 25 - var magenta = '#F49'; 26 - var midnight = '#103'; 27 - var white = 'white'; 28 - 29 - 30 - // -- illustration shapes --- // 31 - 32 - var cat = new Zdog.Group({ 33 - addTo: illo, 34 - updateSort: true, 35 - }); 36 - 37 - // body 38 - new Zdog.Shape({ 39 - path: [ { y: -1 }, { y: 1} ], 40 - scale: { y: 3 }, 41 - addTo: cat, 42 - stroke: 14, 43 - color: magenta, 44 - }); 45 - 46 - var face = new Zdog.Anchor({ 47 - addTo: cat, 48 - translate: { y: -4, z: 6.5 }, 49 - }); 50 - 51 - // nose 52 - new Zdog.Shape({ 53 - path: [ 54 - { x: -1 }, 55 - { x: 1 }, 56 - { y: 1 }, 57 - ], 58 - scale: { x: 0.25, y: 0.25 }, 59 - addTo: face, 60 - translate: { z: 1.5 }, 61 - stroke: 1, 62 - color: midnight, 63 - }); 64 - 65 - // tummy 66 - new Zdog.RoundedRect({ 67 - width: 5, 68 - height: 7, 69 - cornerRadius: 2.5, 70 - addTo: cat, 71 - translate: { y: 3.5, z: 5 }, 72 - // rotate: { x: TAU/64 }, 73 - color: white, 74 - stroke: 3, 75 - fill: true, 76 - }); 77 - 78 - // chin 79 - new Zdog.Shape({ 80 - path: [ { x: -1 }, { x: 1 } ], 81 - scale: { x: 2 }, 82 - addTo: cat, 83 - translate: { y: -3, z: 4 }, 84 - stroke: 4, 85 - color: magenta, 86 - }); 87 - 88 - // tail 89 - new Zdog.Shape({ 90 - path: [ { y: 0 }, { y: 8 } ], 91 - addTo: cat, 92 - translate: { y: 7, z: -4 }, 93 - rotate: { x: -TAU/32 }, 94 - stroke: 1, 95 - color: magenta, 96 - }); 97 - 98 - var backLine = new Zdog.Shape({ 99 - path: [ { x: -1 }, { x: 1 } ], 100 - scale: { x: 3 }, 101 - addTo: cat, 102 - translate: { y: 0, z: -6.5 }, 103 - stroke: 0.5, 104 - color: '#F7A', 105 - }); 106 - backLine.copy({ 107 - translate: { y: -3, z: -6.5 }, 108 - }); 109 - backLine.copy({ 110 - translate: { y: 3, z: -6.5 }, 111 - }); 112 - 113 - [ -1, 1 ].forEach( function( xSide ) { 114 - // eye 115 - new Zdog.Shape({ 116 - path: [ { y: -1 }, { y: 1} ], 117 - scale: { y: 0.3 }, 118 - addTo: face, 119 - translate: { x: 0.75*xSide, y: -1.5 }, 120 - stroke: 0.8, 121 - color: midnight, 122 - }); 123 - 124 - // maw 125 - new Zdog.Shape({ 126 - path: [ { x: -1 }, { x: 1} ], 127 - scale: { x: 0.4 }, 128 - addTo: face, 129 - translate: { x: 1*xSide, y: 0.5, z: 0.5 }, 130 - stroke: 1.5, 131 - color: white, 132 - }); 133 - 134 - // whisker 135 - var whisker = new Zdog.Shape({ 136 - path: [ 137 - { x: 0, y: 0 }, 138 - { x: 1, y: 1 }, 139 - ], 140 - scale: { x: xSide*3, y: 0.75 }, 141 - addTo: face, 142 - translate: { x: 2.5*xSide, y: 0.5 }, 143 - color: white, 144 - stroke: 0.25, 145 - }); 146 - whisker.copy({ 147 - scale: { x: xSide*3, y: -0.75 }, 148 - }); 149 - 150 - // ear 151 - new Zdog.Shape({ 152 - path: [ 153 - { x: 0, y: 0 }, 154 - { x: 1, y: 1 }, 155 - { x: 1, y: -1 }, 156 - ], 157 - scale: { x: 2*xSide, y: 1.5 }, 158 - addTo: cat, 159 - translate: { x: 2*xSide, y: -8 }, 160 - color: magenta, 161 - stroke: 3, 162 - fill: true, 163 - }); 164 - 165 - // arm 166 - var arm = new Zdog.Shape({ 167 - path: [ { y: 0 }, { y: 3.5 } ], 168 - addTo: cat, 169 - translate: { x: 3.5*xSide, y: -1, z: 5.5 }, 170 - rotate: { x: TAU/16 }, 171 - stroke: 3, 172 - color: magenta, 173 - }); 174 - 175 - // leg 176 - arm.copy({ 177 - translate: { x: 3.5*xSide, y: 8, z: 2 }, 178 - rotate: {}, 179 - }); 180 - }); 181 - 182 - var diamondPanel = new Zdog.Shape({ 183 - path: [ 184 - { x: 0, y: 1, z: -0 }, 185 - { x: -1, y: 0, z: 1 }, 186 - { x: 1, y: 0, z: 1 }, 187 - ], 188 - scale: { x: 12, y: 30, z: -12 }, 189 - addTo: illo, 190 - stroke: false, 191 - fill: true, 192 - color: 'hsla(60, 100%, 50%, 0.1)', 193 - }); 194 - diamondPanel.copy({ 195 - rotate: { y: TAU/4*1 }, 196 - color: 'hsla(60, 100%, 50%, 0.2)', 197 - }); 198 - diamondPanel.copy({ 199 - rotate: { y: TAU/4*2 }, 200 - color: 'hsla(60, 100%, 50%, 0.3)', 201 - }); 202 - diamondPanel.copy({ 203 - rotate: { y: TAU/4*3 }, 204 - color: 'hsla(60, 100%, 50%, 0.4)', 205 - }); 206 - diamondPanel.copy({ 207 - scale: { x: 12, y: -30, z: -12 }, 208 - rotate: { y: TAU/4*0 }, 209 - color: 'hsla(60, 100%, 50%, 0.4)', 210 - }); 211 - diamondPanel.copy({ 212 - scale: { x: 12, y: -30, z: -12 }, 213 - rotate: { y: TAU/4*1 }, 214 - color: 'hsla(60, 100%, 50%, 0.3)', 215 - }); 216 - diamondPanel.copy({ 217 - scale: { x: 12, y: -30, z: -12 }, 218 - rotate: { y: TAU/4*2 }, 219 - color: 'hsla(60, 100%, 50%, 0.2)', 220 - }); 221 - diamondPanel.copy({ 222 - scale: { x: 12, y: -30, z: -12 }, 223 - rotate: { y: TAU/4*3 }, 224 - color: 'hsla(60, 100%, 50%, 0.1)', 225 - }); 226 - 227 - // -- animate --- // 228 - 229 - function animate() { 230 - illo.rotate.y += isSpinning ? -TAU/150 : 0; 231 - illo.updateRenderGraph(); 232 - requestAnimationFrame( animate ); 233 - } 234 - 235 - animate(); 236 -
-50
demo/crypto-kitty/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>crypto-kitty</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #013; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/rounded-rect.js"></script> 44 - <script src="../../js/group.js"></script> 45 - <script src="../../js/dragger.js"></script> 46 - <script src="../../js/illustration.js"></script> 47 - <script src="crypto-kitty.js"></script> 48 - 49 - </body> 50 - </html>
-61
demo/curves/curves.js
··· 1 - var illoElem = document.querySelector('.illo'); 2 - var w = 72; 3 - var h = 72; 4 - var zoom = 6; 5 - illoElem.setAttribute( 'width', w * zoom ); 6 - illoElem.setAttribute( 'height', h * zoom ); 7 - // colors 8 - 9 - var illo = new Zdog.Illustration({ 10 - element: illoElem, 11 - zoom: zoom, 12 - dragRotate: true, 13 - }); 14 - 15 - // -- illustration shapes --- // 16 - 17 - // rectangle with curve 18 - new Zdog.Shape({ 19 - path: [ 20 - { x: -6, y: -8 }, 21 - { bezier: [ 22 - { x: 0, y: -12, z: -5 }, 23 - { x: 0, y: -4 }, 24 - { x: 6, y: -8 }, 25 - ]}, 26 - { x: 6, y: 8 }, 27 - { bezier: [ 28 - { x: 0, y: 8, z: -5 }, 29 - { x: 0, y: 8, z: 5 }, 30 - { x: -6, y: 8 }, 31 - ]}, 32 - { x: -6, y: 8 }, 33 - ], 34 - addTo: illo, 35 - stroke: 2, 36 - color: '#19F', 37 - }); 38 - 39 - // quarter circle 40 - new Zdog.Shape({ 41 - path: [ 42 - { x: 10, y: 0 }, 43 - { arc: [ 44 - { x: 20, y: 0 }, 45 - { x: 20, y: 10 } 46 - ]}, 47 - { x: 10, y: 10 } 48 - ], 49 - addTo: illo, 50 - stroke: 2, 51 - color: '#A00', 52 - }); 53 - 54 - // -- animate --- // 55 - 56 - function animate() { 57 - illo.updateRenderGraph(); 58 - requestAnimationFrame( animate ); 59 - } 60 - 61 - animate();
-42
demo/curves/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>curves</title> 8 - 9 - <style> 10 - body { 11 - background: #DDD; 12 - text-align: center; 13 - } 14 - 15 - .illo { 16 - display: block; 17 - margin: 0px auto; 18 - } 19 - </style> 20 - 21 - </head> 22 - <body> 23 - 24 - <canvas class="illo"></canvas> 25 - 26 - <p>Click &amp; drag to rotate</p> 27 - 28 - <script src="../../js/boilerplate.js"></script> 29 - <script src="../../js/canvas-renderer.js"></script> 30 - <script src="../../js/vector.js"></script> 31 - <script src="../../js/anchor.js"></script> 32 - <script src="../../js/path-command.js"></script> 33 - <script src="../../js/shape.js"></script> 34 - <!-- <script src="../../js/group.js"></script> --> 35 - <!-- <script src="../../js/ellipse.js"></script> --> 36 - <!-- <script src="../../js/rect.js"></script> --> 37 - <script src="../../js/dragger.js"></script> 38 - <script src="../../js/illustration.js"></script> 39 - <script src="curves.js"></script> 40 - 41 - </body> 42 - </html>
-118
demo/cylinders/cylinders.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 10, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // colors 24 - var yellow = '#ED0'; 25 - var gold = '#EA0'; 26 - var orange = '#E62'; 27 - var magenta = '#C25'; 28 - var navy = '#249'; 29 - 30 - // -- illustration shapes --- // 31 - 32 - var y = 12; 33 - 34 - var cylinder = new Zdog.Cylinder({ 35 - diameter: 10, 36 - length: 5, 37 - addTo: illo, 38 - translate: { y: -y }, 39 - rotate: { x: -TAU/4 }, 40 - // rotate: { x: -TAU/8 }, 41 - color: magenta, 42 - backface: navy, 43 - stroke: false, 44 - }); 45 - cylinder.copy({ 46 - addTo: illo, 47 - translate: { y: y }, 48 - rotate: { x: TAU/4 }, 49 - color: magenta, 50 - backface: navy, 51 - }); 52 - 53 - var colorWheel = [ navy, magenta, orange, gold, yellow, ]; 54 - 55 - [ -1, 1 ].forEach( function( ySide ) { 56 - for ( var i=0; i < 5; i++ ) { 57 - var rotor1 = new Zdog.Anchor({ 58 - addTo: illo, 59 - rotate: { y: TAU/5 * i }, 60 - }); 61 - var rotor2 = new Zdog.Anchor({ 62 - addTo: rotor1, 63 - rotate: { x: TAU/6 }, 64 - }); 65 - 66 - cylinder.copy({ 67 - addTo: rotor2, 68 - translate: { y: y*ySide }, 69 - rotate: { x: TAU/4*ySide }, 70 - color: colorWheel[i], 71 - backface: colorWheel[ (i+7) % 5 ], 72 - }); 73 - } 74 - }); 75 - 76 - new Zdog.Shape({ 77 - visible: false, 78 - addTo: illo, 79 - stroke: 18, 80 - // color: '#FED', 81 - color: 'hsla(50, 50%, 90%, 0.8)', 82 - }); 83 - 84 - // -- animate --- // 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 - 92 - var t = 0; 93 - 94 - function animate() { 95 - spin(); 96 - illo.updateRenderGraph(); 97 - requestAnimationFrame( animate ); 98 - } 99 - 100 - animate(); 101 - 102 - // -- update -- // 103 - 104 - function spin() { 105 - if ( !isSpinning ) { 106 - return; 107 - } 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; 117 - } 118 -
-52
demo/cylinders/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>cylinders</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #026; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/group.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/cylinder.js"></script> 46 - <!-- <script src="../../js/rect.js"></script> --> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="cylinders.js"></script> 50 - 51 - </body> 52 - </html>
-848
demo/davey-nippu/davey-nippu.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - // HACK - better z-sort separation of shapes 4 - Zdog.RoundedRect.prototype.updateSortValue = 5 - Zdog.Ellipse.prototype.updateSortValue = Zdog.Shape.prototype.updateSortValue; 6 - 7 - var illoElem = document.querySelector('.illo'); 8 - var w = 128; 9 - var h = 128; 10 - var minWindowSize = Math.min( window.innerWidth, (window.innerHeight - 60) ); 11 - var zoom = Math.floor( minWindowSize / w ); 12 - illoElem.setAttribute( 'width', w * zoom ); 13 - illoElem.setAttribute( 'height', h * zoom ); 14 - 15 - var isSpinning = true; 16 - var TAU = Zdog.TAU; 17 - var sceneStartRotation = { y: -TAU/8 }; 18 - 19 - var illo = new Zdog.Illustration({ 20 - element: illoElem, 21 - zoom: zoom, 22 - rotate: sceneStartRotation, 23 - dragRotate: true, 24 - onDragStart: function() { 25 - isSpinning = false; 26 - }, 27 - }); 28 - 29 - var quarterTurn = Math.sin( TAU/8 ); 30 - 31 - // ----- colors ----- // 32 - 33 - var beigeDark = '#F96'; 34 - var beigeLight = '#FC9'; 35 - var skinDark = '#F66'; 36 - var skinMedium = '#F88'; 37 - var skinLight = '#FAA'; 38 - var navy = '#036'; 39 - var midnight = '#003'; 40 - var auburn = '#903'; 41 - var red = '#C33'; 42 - var sky = '#09D'; 43 - var offWhite = '#FFD'; 44 - var white = 'white'; 45 - var blueDark = '#66C'; 46 - var bluePale = '#CCF'; 47 - 48 - // -- models --- // 49 - 50 - var ground = new Zdog.Anchor({ 51 - addTo: illo, 52 - translate: { y: 56 }, 53 - }); 54 - 55 - // ----- dude ----- // 56 - 57 - ( function() { 58 - 59 - var dude = new Zdog.Anchor({ 60 - addTo: ground, 61 - translate: { x : -24, z: -12 }, 62 - }); 63 - 64 - var hipX = ( 8 / quarterTurn ) / 2; 65 - var hips = new Zdog.Shape({ 66 - path: [ 67 - { x: -hipX }, 68 - { x: hipX }, 69 - ], 70 - addTo: dude, 71 - translate: { y: -49 }, 72 - rotate: { x: TAU/16 }, 73 - stroke: 8, 74 - color: beigeLight, 75 - }); 76 - 77 - // right thigh 78 - var rightThigh = new Zdog.Shape({ 79 - path: [ 80 - { y: 0 }, 81 - { y: 18 }, 82 - ], 83 - addTo: hips, 84 - translate: { x: -hipX }, 85 - stroke: 8, 86 - color: beigeLight, 87 - }); 88 - // right tight line 89 - var rightThighLine = rightThigh.copy({ 90 - addTo: rightThigh, 91 - translate: { x: -4 }, 92 - color: white, 93 - stroke: 0.5, 94 - }); 95 - 96 - var shinEnd = { y: 22 }; 97 - 98 - var rightShin = rightThigh.copy({ 99 - path: [ 100 - { y: 0 }, 101 - shinEnd, 102 - ], 103 - addTo: rightThigh, 104 - translate: { y: 18 }, 105 - }); 106 - // right shin line 107 - rightThighLine.copy({ 108 - path: [ 109 - { y: -2 }, 110 - shinEnd, 111 - ], 112 - addTo: rightShin, 113 - }); 114 - 115 - var rightAnkle = new Zdog.Shape({ 116 - path: [ 117 - { y: 3 }, 118 - { y: 4 }, 119 - ], 120 - addTo: rightShin, 121 - translate: shinEnd, 122 - color: skinMedium, 123 - stroke: 6, 124 - }); 125 - 126 - var leftThigh = rightThigh.copy({ 127 - translate: { x: hipX }, 128 - color: beigeDark, 129 - }); 130 - // left thigh line 131 - rightThighLine.copy({ 132 - addTo: leftThigh, 133 - translate: { x: 4 }, 134 - color: beigeLight, 135 - }); 136 - 137 - var leftShin = rightShin.copy({ 138 - addTo: leftThigh, 139 - rotate: { x: -TAU/4 - hips.rotate.x }, 140 - color: beigeDark, 141 - }); 142 - // left shin line 143 - leftShin.copy({ 144 - addTo: leftShin, 145 - translate: { x: 4 }, 146 - rotate: {}, 147 - color: beigeLight, 148 - stroke: rightThighLine.stroke, 149 - }); 150 - 151 - var leftAnkle = rightAnkle.copy({ 152 - addTo: leftShin, 153 - color: skinDark, 154 - }); 155 - 156 - // shoes 157 - [ true, false ].forEach( function( isRight ) { 158 - var shoeAngleX = isRight ? -TAU/16 : -hips.rotate.x; 159 - var shoe = new Zdog.RoundedRect({ 160 - width: 2, 161 - height: 10, 162 - cornerRadius: 2, 163 - addTo: isRight ? rightAnkle : leftAnkle, 164 - translate: { y: 6, z: 4 }, 165 - rotate: { x: -TAU/4 - shoeAngleX }, 166 - color: isRight ? white : offWhite, 167 - fill: true, 168 - stroke: 6, 169 - }); 170 - 171 - // laces 172 - var lacesGroup = new Zdog.Group({ 173 - addTo: shoe, 174 - translate: { z: -3 }, 175 - }); 176 - var shoeLace = new Zdog.Shape({ 177 - path: [ { x: -1 }, { x: 1 } ], 178 - scale: { x: 2 }, 179 - addTo: lacesGroup, 180 - translate: { y: -2 }, 181 - color: blueDark, 182 - stroke: 1, 183 - }); 184 - shoeLace.copy({ 185 - translate: { y: -4 }, 186 - }); 187 - // HACK, add invisible shape so laces better render on top 188 - new Zdog.Shape({ 189 - visible: false, 190 - addTo: lacesGroup, 191 - translate: { y: 4 }, 192 - }); 193 - 194 - // soles 195 - new Zdog.RoundedRect({ 196 - width: 6, 197 - height: 13, 198 - cornerRadius: 3, 199 - addTo: shoe, 200 - translate: { z: 3.5 }, 201 - // rotate: { x: -TAU/4 }, 202 - stroke: 1, 203 - fill: true, 204 - color: blueDark, 205 - }); 206 - }); 207 - 208 - var torsoX = 6 / quarterTurn; 209 - var torso = new Zdog.Shape({ 210 - path: [ 211 - { x: -torsoX }, 212 - { x: torsoX }, 213 - ], 214 - addTo: dude, 215 - translate: { y: -59, z: -6 }, 216 - color: navy, 217 - stroke: 16, 218 - }); 219 - 220 - var shoulderX = torsoX + 1.5; 221 - var rightShoulder = new Zdog.Shape({ 222 - path: [ 223 - { y: 0 }, 224 - { y: 14 }, 225 - ], 226 - addTo: torso, 227 - translate: { x: -shoulderX, y: -3 }, 228 - rotate: { x: -TAU/16, z: TAU/8 }, 229 - stroke: 10, 230 - color: navy, 231 - }); 232 - 233 - var leftShoulder = rightShoulder.copy({ 234 - translate: { x: shoulderX, y: -3 }, 235 - rotate: { x: TAU*3/16, z: -TAU/32 }, 236 - color: midnight, 237 - }); 238 - 239 - var rightArm = new Zdog.Shape({ 240 - path: [ 241 - { y: 0 }, 242 - { y: 14 }, 243 - ], 244 - addTo: rightShoulder, 245 - translate: { y: 16 }, 246 - rotate: { x: 2.12, z: -0 }, 247 - stroke: 8, 248 - color: skinMedium, 249 - }); 250 - 251 - var leftArm = rightArm.copy({ 252 - addTo: leftShoulder, 253 - color: skinDark, 254 - rotate: { x: TAU/4, z: TAU/8 }, 255 - }); 256 - 257 - var rightHand = new Zdog.Shape({ 258 - addTo: rightArm, 259 - translate: { x: -0.5, y: 14, z: 1 }, 260 - stroke: 10, 261 - color: skinMedium, 262 - }); 263 - 264 - // left hand 265 - rightHand.copy({ 266 - addTo: leftArm, 267 - color: skinDark, 268 - }); 269 - 270 - // jacketZip 271 - new Zdog.Ellipse({ 272 - addTo: torso, 273 - diameter: torso.stroke, 274 - quarters: 1, 275 - rotate: { y: TAU/4, x: -TAU/32 }, 276 - color: sky, 277 - stroke: 0.5, 278 - }); 279 - 280 - var neckY = -torso.stroke/2; 281 - var neck = new Zdog.Shape({ 282 - path: [ { y: neckY }, { y: neckY - 4 } ], 283 - addTo: torso, 284 - // translate: { y: } 285 - rotate: { x: TAU/16, y: TAU*3/16 }, 286 - stroke: 6, 287 - color: skinMedium, 288 - }); 289 - // chin 290 - var chin = new Zdog.Shape({ 291 - addTo: neck, 292 - translate: { y: neckY - 5, z: 2 }, 293 - stroke: 8, 294 - color: skinMedium, 295 - }); 296 - // forehead 297 - var forehead = new Zdog.Ellipse({ 298 - diameter: 2, 299 - addTo: chin, 300 - translate: { y: -4 }, 301 - stroke: 4, 302 - color: skinMedium, 303 - }); 304 - // hair big 305 - new Zdog.Shape({ 306 - path: [ 307 - { y: -1 }, 308 - { y: -7 }, 309 - ], 310 - addTo: chin, 311 - translate: { x: -2, y: -2, z: -3 }, 312 - stroke: 4, 313 - color: auburn, 314 - }); 315 - // hair small 316 - new Zdog.Shape({ 317 - path: [ 318 - { y: 0 }, 319 - { y: -6 }, 320 - ], 321 - addTo: chin, 322 - translate: { x: 1.25, y: -2, z: -3 }, 323 - stroke: 2.5, 324 - color: red, 325 - }); 326 - // hair back 327 - new Zdog.Ellipse({ 328 - diameter: 3, 329 - addTo: chin, 330 - translate: { y: -4, z: -4 }, 331 - stroke: 4, 332 - color: auburn, 333 - }); 334 - // smile 335 - new Zdog.Ellipse({ 336 - addTo: chin, 337 - quarters: 2, 338 - translate: { y: -1.5, z: 3 }, 339 - rotate: { z: TAU/4 }, 340 - scale: 3, 341 - fill: true, 342 - stroke: 0.5, 343 - color: white, 344 - closed: true, 345 - }); 346 - // eyes 347 - var eye = new Zdog.Ellipse({ 348 - addTo: forehead, 349 - quarters: 2, 350 - scale: 1, 351 - translate: { x: -1, y: 0.5, z: 2 }, 352 - rotate: { z: -TAU/4 }, 353 - closed: false, 354 - color: midnight, 355 - stroke: 0.38, 356 - fill: false, 357 - }); 358 - eye.copy({ 359 - translate: { x: 1, y: 0.5, z: 2 }, 360 - }); 361 - 362 - var ear = new Zdog.Ellipse({ 363 - diameter: 1.5, 364 - addTo: forehead, 365 - translate: { x: 3.5, y: 1, z: -1 }, 366 - rotate: { y: -TAU/8 }, 367 - stroke: 1, 368 - color: skinMedium, 369 - fill: true, 370 - }); 371 - ear.copy({ 372 - translate: { x: -3.5, y: 1, z: -1 }, 373 - rotate: { y: TAU/8 }, 374 - }); 375 - 376 - })(); 377 - 378 - // lady 379 - ( function() { 380 - 381 - var lady = new Zdog.Anchor({ 382 - addTo: ground, 383 - translate: { x : 24, z: 12 }, 384 - }); 385 - 386 - var hips = new Zdog.Shape({ 387 - addTo: lady, 388 - translate: { y: -38 }, 389 - stroke: 15, 390 - color: navy, 391 - }); 392 - 393 - var torsoAnchor = new Zdog.Anchor({ 394 - addTo: hips, 395 - rotate: { x: -TAU/8 }, 396 - }); 397 - 398 - var torso = new Zdog.Rect({ 399 - width: 1, 400 - height: 5, 401 - addTo: torsoAnchor, 402 - translate: { y: -9 }, 403 - stroke: 8, 404 - color: beigeLight, 405 - }); 406 - 407 - // ----- lady head ----- // 408 - 409 - var neck = new Zdog.Shape({ 410 - path: [ {}, { y: -2 }], 411 - addTo: torso, 412 - translate: { y: -7 }, 413 - stroke: 4, 414 - color: skinLight, 415 - }); 416 - 417 - var collar = new Zdog.RoundedRect({ 418 - width: 3, 419 - height: 5, 420 - cornerRadius: 1.5, 421 - addTo: neck, 422 - translate: { x: 1, y: 2, z: 0 }, 423 - rotate: { x: -TAU/4, z: TAU/8 }, 424 - color: white, 425 - fill: true, 426 - }); 427 - collar.copy({ 428 - translate: { x: -1, y: 2, z: 0 }, 429 - rotate: { x: -TAU/4, z: -TAU/8 }, 430 - }); 431 - 432 - var head = new Zdog.Anchor({ 433 - addTo: neck, 434 - translate: { y: -6 }, 435 - rotate: { x: TAU/8 }, 436 - }); 437 - // var faceGroup = new Zdog.Group({ 438 - // addTo: head, 439 - // }); 440 - // hair cap 441 - new Zdog.Hemisphere({ 442 - addTo: head, 443 - diameter: 11, 444 - color: midnight, 445 - stroke: 1.5, 446 - translate: { y: -1 }, 447 - rotate: { x: TAU/8 * 3, y: 0 }, 448 - }); 449 - // face 450 - new Zdog.Hemisphere({ 451 - addTo: head, 452 - diameter: 9, 453 - color: skinLight, 454 - backface: midnight, 455 - stroke: 0.5, 456 - translate: { y: -0.95 }, 457 - rotate: { x: TAU/8 * 3, y: TAU/2 }, 458 - }); 459 - // smile 460 - new Zdog.Ellipse({ 461 - addTo: head, 462 - diameter: 3, 463 - quarters: 1, 464 - translate: { y: 0.5, z: 4 }, 465 - rotate: { z: TAU * 3/8 }, 466 - color: skinDark, 467 - closed: false, 468 - stroke: 0.5, 469 - }); 470 - 471 - // hair locks 472 - new Zdog.RoundedRect({ 473 - width: 6, 474 - height: 10, 475 - cornerRadius: 3, 476 - addTo: head, 477 - translate: { y: 2, x: 4.5, z: -2 }, 478 - rotate: { y: TAU/4 }, 479 - fill: true, 480 - color: midnight, 481 - stroke: 2, 482 - }); 483 - // hairLock.copy({ 484 - // translate: { y: 8, x: 4.5, z: -2 }, 485 - // }); 486 - 487 - 488 - // glasses 489 - var glasses = new Zdog.Group({ 490 - addTo: head, 491 - translate: { y: -1, z: 5 }, 492 - }); 493 - 494 - var lens = new Zdog.Ellipse({ 495 - diameter: 4, 496 - addTo: glasses, 497 - translate: { x: -2.5 }, 498 - stroke: false, 499 - fill: true, 500 - color: '#603', 501 - }); 502 - lens.copy({ 503 - translate: { x: 2.5 }, 504 - }); 505 - 506 - var glassesRim = lens.copy({ 507 - stroke: 1, 508 - fill: false, 509 - color: auburn, 510 - }); 511 - glassesRim.copy({ 512 - translate: { x: 2.5 }, 513 - }); 514 - 515 - 516 - 517 - // ----- lady arms ----- // 518 - 519 - var leftWrist = { z: 14, y: -14 }; 520 - 521 - var leftArm = new Zdog.Shape({ 522 - path: [ 523 - { z: -0, y: 0 }, 524 - { z: 12, y: -2 }, // elbow 525 - leftWrist, 526 - // hack for z-sort probs 527 - { move: { x: 16, z: -16 } }, 528 - ], 529 - addTo: torso, 530 - translate: { x: 5, y: -3 }, 531 - closed: false, 532 - color: skinMedium, 533 - stroke: 4, 534 - }); 535 - 536 - // leftHand 537 - var leftHand = new Zdog.Shape({ 538 - path: [ { x: -1, z: -0.5 } ], 539 - addTo: leftArm, 540 - translate: leftWrist, 541 - color: skinMedium, 542 - stroke: 6, 543 - }); 544 - 545 - var phoneAnchor = new Zdog.Anchor({ 546 - addTo: leftHand, 547 - translate: { x: -2, y: -0, z: -4 }, 548 - rotate: { x: TAU/8 }, 549 - }); 550 - 551 - var phoneBack = new Zdog.Group({ 552 - addTo: phoneAnchor, 553 - }); 554 - var phoneFront = new Zdog.Group({ 555 - addTo: phoneAnchor, 556 - translate: { z: -0.5 }, 557 - }); 558 - // back phone panel 559 - var phonePanel = new Zdog.RoundedRect({ 560 - width: 4, 561 - height: 8, 562 - cornerRadius: 1, 563 - addTo: phoneBack, 564 - stroke: 0.5, 565 - color: bluePale, 566 - fill: true, 567 - }); 568 - // phone logo dot 569 - new Zdog.Ellipse({ 570 - diameter: 1.25, 571 - addTo: phoneBack, 572 - translate: { y: -1 }, 573 - fill: true, 574 - stroke: false, 575 - color: sky, 576 - }); 577 - // phone camera dot 578 - new Zdog.Shape({ 579 - addTo: phoneBack, 580 - translate: { x: -1, y: -3 }, 581 - color: midnight, 582 - stroke: 0.5, 583 - }); 584 - 585 - // z-sort hack 586 - new Zdog.Shape({ 587 - path: [ { z: 16 } ], 588 - addTo: phoneBack, 589 - visible: false, 590 - }); 591 - 592 - // phone front 593 - phonePanel.copy({ 594 - addTo: phoneFront, 595 - color: midnight, 596 - }); 597 - 598 - var rightWrist = { y: 24 }; 599 - 600 - var rightArm = leftArm.copy({ 601 - path: [ 602 - { y: 0 }, 603 - rightWrist, 604 - ], 605 - translate: { x: -4, y: -3 }, 606 - rotate: { z: TAU/16, x: TAU/32 }, 607 - color: skinLight, 608 - }); 609 - 610 - var rightHandPosition = new Zdog.Vector( rightWrist ).add({ x: -0.5, z: -1 }); 611 - 612 - var rightHand = leftHand.copy({ 613 - path: [{}], 614 - addTo: rightArm, 615 - translate: rightHandPosition, 616 - color: skinLight, 617 - }); 618 - 619 - var suitCase = new Zdog.Anchor({ 620 - addTo: rightHand, 621 - translate: { y: 12 }, 622 - rotate: { y: TAU/4 } 623 - }); 624 - 625 - var suitCaseFrontPanel = new Zdog.RoundedRect({ 626 - addTo: suitCase, 627 - width: 24, 628 - height: 14, 629 - cornerRadius: 2, 630 - translate: { z: 3 }, 631 - color: '#848', 632 - fill: true, 633 - }); 634 - suitCaseFrontPanel.copy({ 635 - translate: { z: -3 }, 636 - color: '#606', 637 - }); 638 - 639 - var suitCaseTopPanel = new Zdog.Rect({ 640 - addTo: suitCase, 641 - width: 20, 642 - height: 5, 643 - translate: { y: -7 }, 644 - rotate: { x: TAU/4 }, 645 - stroke: 0.5, 646 - fill: true, 647 - color: '#606', 648 - }); 649 - suitCaseTopPanel.copy({ 650 - translate: { y: 7 }, 651 - }); 652 - var suitCaseSidePanel = suitCaseTopPanel.copy({ 653 - width: 5, 654 - height: 10, 655 - translate: { x: 12 }, 656 - rotate: { y: TAU/4 }, 657 - }); 658 - suitCaseSidePanel.copy({ 659 - translate: { x: -12 }, 660 - }); 661 - // suit case filler 662 - new Zdog.Rect({ 663 - addTo: suitCase, 664 - width: 20, 665 - height: 10, 666 - stroke: 4, 667 - color: '#606', 668 - }); 669 - // suit case handle 670 - var suitCaseHandle = new Zdog.Shape({ 671 - addTo: suitCase, 672 - path: [ 673 - {}, 674 - { arc: [ 675 - { x: 1, y: 0 }, 676 - { x: 1, y: 1 }, 677 - ]}, 678 - { x: 1, y: 3 }, 679 - ], 680 - translate: { x: 3, y: -11 }, 681 - stroke: 1.5, 682 - color: midnight, 683 - closed: false, 684 - }); 685 - suitCaseHandle.copy({ 686 - scale: { x: -1 }, 687 - translate: { x: -3, y: -11 }, 688 - }); 689 - 690 - // ---- leg ---- // 691 - 692 - // left leg 693 - var leftAnkle = { y: 28 }; 694 - var leftLeg = new Zdog.Shape({ 695 - addTo: hips, 696 - path: [ { y: 0 }, leftAnkle ], 697 - translate: { x: 3.5, y: 4, z: 0 }, 698 - stroke: 7, 699 - rotate: { x: -TAU/8 }, 700 - color: midnight, 701 - }); 702 - 703 - // right thigh 704 - var rightKnee = { y: 16 }; 705 - var rightThigh = new Zdog.Shape({ 706 - addTo: hips, 707 - path: [ { y: 0 }, rightKnee ], 708 - translate: { x: -3.5, y: 4, z: 0 }, 709 - stroke: 7, 710 - rotate: { x: TAU/8 }, 711 - color: navy, 712 - }); 713 - // rightShin 714 - var rightAnkle = { y: 10 }; 715 - var rightShin = new Zdog.Shape({ 716 - addTo: rightThigh, 717 - path: [ { y: 0 }, rightAnkle ], 718 - translate: rightKnee, 719 - stroke: 7, 720 - rotate: { x: -TAU/8 }, 721 - color: navy, 722 - }); 723 - 724 - // lady feet 725 - var rightFoot = new Zdog.Shape({ 726 - addTo: rightShin, 727 - path: [ { y: 2 }, { y: 8 } ], 728 - translate: rightAnkle, 729 - stroke: 4, 730 - color: skinLight, 731 - }); 732 - // heel 733 - new Zdog.Shape({ 734 - addTo: rightFoot, 735 - path: [ { x: -1 }, { x: 1 } ], 736 - translate: { y: 5, z: -3 }, 737 - stroke: 4, 738 - color: beigeLight, 739 - }); 740 - // sole edge 741 - var soleEdge = new Zdog.Shape({ 742 - addTo: rightFoot, 743 - path: [ 744 - { x: -2, z: -2 }, 745 - { arc: [ 746 - { x: -2, z: -2, y: 5 }, 747 - { x: 0, z: 2, y: 5 } 748 - ]}, 749 - ], 750 - translate: { y: 6 }, 751 - stroke: 2, 752 - fill: false, 753 - closed: false, 754 - color: beigeLight, 755 - }); 756 - soleEdge.copy({ 757 - scale: { x: -1 }, 758 - }); 759 - 760 - // heel spike 761 - new Zdog.Shape({ 762 - addTo: rightFoot, 763 - path: [ {}, { y: 5 } ], 764 - translate: { y: 6, z: -4 }, 765 - stroke: 2, 766 - color: beigeLight, 767 - }); 768 - rightFoot.copyGraph({ 769 - addTo: leftLeg, 770 - translate: leftAnkle, 771 - color: skinMedium, 772 - }); 773 - 774 - })(); 775 - 776 - ( function() { 777 - 778 - 779 - // big puff 780 - var cloud = new Zdog.Shape({ 781 - addTo: illo, 782 - translate: { x: 34, y: -26, z: -20 }, 783 - rotate: { y: -sceneStartRotation.y }, 784 - stroke: 16, 785 - color: white, 786 - }); 787 - 788 - // left small puff 789 - var smallPuff = new Zdog.Shape({ 790 - addTo: cloud, 791 - translate: { x: -9, y: 4, z: 4 }, 792 - stroke: 8, 793 - color: white, 794 - }); 795 - smallPuff.copy({ 796 - translate: { x: 9, y: 5, z: 6 }, 797 - stroke: 10, 798 - }); 799 - 800 - var disk = new Zdog.RoundedRect({ 801 - addTo: cloud, 802 - width: 26, 803 - height: 12, 804 - cornerRadius: 6, 805 - translate: { x: -6, y: 7, z: 4 }, 806 - rotate: { x: TAU/4 }, 807 - stroke: 3, 808 - color: white, 809 - fill: true, 810 - }); 811 - disk.copy({ 812 - translate: { x: 6, y: 9, z: 8 }, 813 - }); 814 - 815 - // sun 816 - new Zdog.Shape({ 817 - addTo: cloud, 818 - translate: { x: -13, y: 0, z: -14 }, 819 - stroke: 8, 820 - color: beigeLight, 821 - }); 822 - 823 - })(); 824 - 825 - // -- animate --- // 826 - 827 - var t = 0; 828 - var tSpeed = 1/240; 829 - 830 - function animate() { 831 - // update 832 - if ( isSpinning ) { 833 - t += tSpeed; 834 - var theta = Zdog.easeInOut( t % 1 ) * TAU; 835 - illo.rotate.y = -theta + sceneStartRotation.y; 836 - } 837 - 838 - illo.updateRenderGraph(); 839 - requestAnimationFrame( animate ); 840 - } 841 - 842 - animate(); 843 - 844 - // ----- inputs ----- // 845 - 846 - document.querySelector('.reset-button').onclick = function() { 847 - illo.rotate.set( sceneStartRotation ); 848 - };
-75
demo/davey-nippu/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>davey nippu</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #09D; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - 29 - a { color: white; } 30 - a:hover { color: #606; } 31 - 32 - button { 33 - background: #848; 34 - color: white; 35 - font-size: 14px; 36 - font-family: inherit; 37 - border: none; 38 - border-radius: 3px; 39 - padding: 8px 10px; 40 - } 41 - 42 - button:hover { 43 - background: #606; 44 - cursor: pointer; 45 - } 46 - 47 - </style> 48 - 49 - </head> 50 - <body> 51 - 52 - <div class="container"> 53 - <canvas class="illo"></canvas> 54 - <p><a href="http://robindavey.co.uk/post/162551722511">Original illustration by Robin Davey</a></p> 55 - <p><button class="reset-button">Reset</button></p> 56 - </div> 57 - 58 - <script src="../../js/boilerplate.js"></script> 59 - <script src="../../js/canvas-renderer.js"></script> 60 - <script src="../../js/svg-renderer.js"></script> 61 - <script src="../../js/vector.js"></script> 62 - <script src="../../js/anchor.js"></script> 63 - <script src="../../js/path-command.js"></script> 64 - <script src="../../js/shape.js"></script> 65 - <script src="../../js/rect.js"></script> 66 - <script src="../../js/rounded-rect.js"></script> 67 - <script src="../../js/ellipse.js"></script> 68 - <script src="../../js/group.js"></script> 69 - <script src="../../js/hemisphere.js"></script> 70 - <script src="../../js/dragger.js"></script> 71 - <script src="../../js/illustration.js"></script> 72 - <script src="davey-nippu.js"></script> 73 - 74 - </body> 75 - </html>
-484
demo/fizzy-bear/fizzy-bear.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - // unibody canvas for compositing 5 - var unibodyCanvas = document.createElement('canvas'); 6 - var bodyLinesCanvas = document.createElement('canvas'); 7 - // document.body.appendChild( unibodyCanvas ); 8 - // document.body.appendChild( bodyLinesCanvas ); 9 - var w = 88; 10 - var h = 88; 11 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 12 - var zoom = Math.min( 6, Math.floor( minWindowSize / w ) ); 13 - 14 - var canvasWidth = illoElem.width = w * zoom; 15 - var canvasHeight = illoElem.height = h * zoom; 16 - unibodyCanvas.width = bodyLinesCanvas.width = canvasWidth; 17 - unibodyCanvas.height = bodyLinesCanvas.height = canvasHeight; 18 - 19 - var camera = new Zdog.Anchor(); 20 - var isSpinning = true; 21 - var TAU = Zdog.TAU; 22 - 23 - var mainIllo = new Zdog.Illustration({ 24 - element: illoElem, 25 - zoom: zoom, 26 - dragRotate: camera, 27 - onDragStart: function() { 28 - isSpinning = false; 29 - }, 30 - }); 31 - 32 - var unibodyIllo = new Zdog.Illustration({ 33 - element: unibodyCanvas, 34 - zoom: zoom, 35 - }); 36 - 37 - var bodyLinesIllo = new Zdog.Illustration({ 38 - element: bodyLinesCanvas, 39 - zoom: zoom, 40 - }); 41 - 42 - 43 - var jumpRotation = new Zdog.Vector({ 44 - x: 12/360 * TAU, 45 - y: -15/360 * TAU, 46 - z: -31/360 * TAU, 47 - }); 48 - 49 - // colors 50 - var magenta = '#C25'; 51 - var orange = '#E62'; 52 - var gold = '#EA0'; 53 - var blue = '#19F'; 54 - var black = '#333'; 55 - 56 - var bearAnchor = new Zdog.Anchor({ 57 - addTo: camera, 58 - }); 59 - 60 - var positiveAnchor = new Zdog.Group({ 61 - addTo: bearAnchor, 62 - updateSort: true, 63 - }); 64 - var outlineAnchor = new Zdog.Group({ 65 - addTo: bearAnchor, 66 - }); 67 - var bodySectionsAnchor = new Zdog.Group({ 68 - addTo: bearAnchor, 69 - updateSort: true, 70 - }); 71 - 72 - // -- illustration shapes --- // 73 - var positiveUnibody, rightLegCutInA, rightLegCutInB, bodyCutIn, 74 - backLegCutIn, crotchCutIn; 75 - 76 - var bodyWidth = 6; 77 - var bodyHeight = 14; 78 - var bodyLineWidth = 28; 79 - 80 - [ false, true ].forEach( function( isOutline ) { 81 - var anchor = isOutline ? outlineAnchor : positiveAnchor; 82 - var outlineWidth = isOutline ? 8 : 0; 83 - 84 - // unibody 85 - var unibody = new Zdog.Rect({ 86 - width: bodyWidth, 87 - height: bodyHeight, 88 - addTo: anchor, 89 - // translate: { y: -1 }, 90 - color: isOutline ? black : magenta, 91 - stroke: bodyLineWidth + outlineWidth, 92 - fill: true, 93 - }); 94 - 95 - if ( !isOutline ) { 96 - // set positiveUnibody 97 - positiveUnibody = unibody; 98 - // body cut-in 99 - // cut-in points 100 - var ciA = new Zdog.Vector({ z: 0, y: -23 }); 101 - var ciB = new Zdog.Vector({ z: 16, y: -7 }); 102 - var ciC = new Zdog.Vector({ z: 16, y: 7 }); 103 - var ciD = new Zdog.Vector({ z: 0, y: 23 }); 104 - // 45 degree points 105 - var topPoints = getQuarterArcPoints( ciA, ciB ); 106 - var bottomPoints = getQuarterArcPoints( ciD, ciC ); 107 - 108 - var cutInPath = [ 109 - topPoints[0], 110 - { bezier: [ topPoints[1], topPoints[2], ciB ] }, 111 - ciC, 112 - { bezier: [ bottomPoints[2], bottomPoints[1], bottomPoints[0] ] }, 113 - ]; 114 - 115 - bodyCutIn = new Zdog.Shape({ 116 - path: cutInPath, 117 - translate: { x: 3 }, 118 - addTo: unibody, 119 - color: black, 120 - closed: false, 121 - stroke: 4, 122 - }); 123 - 124 - } 125 - 126 - // right ear 127 - var ear = new Zdog.Ellipse({ 128 - diameter: 4, 129 - addTo: unibody, 130 - translate: { x: -14, y: -19, z: -2 }, 131 - color: isOutline ? black : magenta, 132 - stroke: 8 + outlineWidth, 133 - }); 134 - // left ear 135 - ear.copy({ 136 - translate: { x: 14, y: -19, z: -2 }, 137 - }); 138 - 139 - 140 - // face container 141 - var face = new Zdog.Anchor({ 142 - translate: { y: -2, z: 14 }, 143 - addTo: unibody, 144 - }); 145 - 146 - // snout 147 - new Zdog.Ellipse({ 148 - width: 8, 149 - height: 4, 150 - addTo: face, 151 - translate: { y: 4, z: 1 }, 152 - color: isOutline ? black : 'white', 153 - stroke: 6 + outlineWidth, 154 - fill: true, 155 - }); 156 - 157 - if ( !isOutline ) { 158 - // nose 159 - new Zdog.Shape({ 160 - path: [ 161 - { x: -1.5, y: 0 }, 162 - { x: 1.5, y: 0 }, 163 - { x: 0, y: 0.5 }, 164 - ], 165 - addTo: face, 166 - translate: { y: 1.5, z: 4 }, 167 - color: black, 168 - stroke: 3, 169 - fill: true, 170 - }); 171 - 172 - // right eye 173 - var eye = new Zdog.Shape({ 174 - path: [ 175 - { x: -4, y: 0 }, 176 - { arc: [ 177 - { x: -4, y: -4 }, 178 - { x: 0, y: -4 } 179 - ]}, 180 - { arc: [ 181 - { x: 4, y: -4 }, 182 - { x: 4, y: 0 } 183 - ]}, 184 - { arc: [ 185 - { x: 3, y: -1.5 }, 186 - { x: 0, y: -1.5 } 187 - ]}, 188 - { arc: [ 189 - { x: -3, y: -1.5 }, 190 - { x: -4, y: 0 } 191 - ]}, 192 - ], 193 - addTo: face, 194 - translate: { y: -3.25, x: -7.5, z: 0 }, 195 - scale: { x: 0.6, y: 0.5 }, 196 - color: black, 197 - stroke: 2, 198 - closed: false, 199 - fill: true, 200 - }); 201 - // left eye 202 - eye.copy({ 203 - translate: { y: -3.25, x: 7.5, z: 0 }, 204 - }); 205 - 206 - } 207 - 208 - 209 - // right arm 210 - new Zdog.Shape({ 211 - path: [ 212 - { x: -1 }, 213 - { x: -8 }, 214 - ], 215 - addTo: unibody, 216 - translate: { x: -17, y: 5 }, 217 - rotate: { y: 0.25 }, 218 - color: isOutline ? black : gold, 219 - stroke: 12 + outlineWidth, 220 - }); 221 - // left arm 222 - new Zdog.Shape({ 223 - path: [ 224 - { x: 0 }, 225 - { 226 - bezier: [ 227 - { x: 0, y: 0 }, 228 - { x: 5, y: -3 }, 229 - { x: 8, y: -11 }, 230 - ] 231 - } 232 - ], 233 - addTo: unibody, 234 - translate: { x: 18, y: 5 }, 235 - rotate: { x: 0.4 }, 236 - color: isOutline ? black : gold, 237 - stroke: 12 + outlineWidth, 238 - closed: false, 239 - }); 240 - 241 - // right leg 242 - var rightLeg = new Zdog.Shape({ 243 - path: [ 244 - { y: 4 }, 245 - { y: 15 }, 246 - ], 247 - addTo: unibody, 248 - translate: { x: -10, y: 13, z: -1 }, 249 - rotate: { z: 49/360 * TAU, x: -0.3 }, 250 - color: isOutline ? black : blue, 251 - stroke: 12 + outlineWidth, 252 - }); 253 - 254 - // right leg cut-in 255 - if ( !isOutline ) { 256 - rightLegCutInA = new Zdog.Shape({ 257 - path: [ 258 - { z: 8, y: 4 }, 259 - { z: 8, y: 15 }, 260 - // { 261 - // arc: [ 262 - // { z: -8, y: 23 }, 263 - // { z: 0, y: 23 }, 264 - // ] 265 - // } 266 - ], 267 - addTo: rightLeg, 268 - // rotate: { y: 1 }, 269 - closed: false, 270 - color: black, 271 - stroke: 4, 272 - }); 273 - rightLegCutInB = rightLegCutInA.copy({ 274 - scale: { z: -1 }, 275 - }); 276 - } 277 - 278 - 279 - // left leg 280 - var leftThigh = new Zdog.Shape({ 281 - path: [ 282 - { y: 2 }, 283 - { y: 12 }, 284 - ], 285 - addTo: unibody, 286 - translate: { x: 9, y: 13, z: -1 }, 287 - rotate: { z: 0.7, x: -0.4 }, 288 - color: isOutline ? black : blue, 289 - stroke: 12 + outlineWidth, 290 - }); 291 - // left shin 292 - var leftShin = new Zdog.Shape({ 293 - path: [ 294 - { y: 0 }, 295 - { y: 12 }, 296 - ], 297 - addTo: leftThigh, 298 - translate: leftThigh.path[1], 299 - rotate: { z: 0.2, x: -0.9 }, 300 - color: isOutline ? black : blue, 301 - stroke: 12 + outlineWidth, 302 - }); 303 - 304 - if ( !isOutline ) { 305 - backLegCutIn = new Zdog.Shape({ 306 - path: [ 307 - { z: 8, y: -14 }, 308 - { z: 8, y: -8 }, 309 - // { arc: [ 310 - // { z: -8, y: 0 }, 311 - // { z: 0, y: 0 }, 312 - // ]}, 313 - ], 314 - addTo: leftShin, 315 - translate: { y: 20 }, 316 - closed: false, 317 - // rotate: { y: 1 }, 318 - color: black, 319 - stroke: 4, 320 - }); 321 - 322 - crotchCutIn = new Zdog.Shape({ 323 - path: [ 324 - { x: -1.5, z: -2 }, 325 - { x: 1, z: 0 } 326 - ], 327 - scale: { x: 2 }, 328 - addTo: unibody, 329 - translate: { x: -5, y: 7+14+2 - 1.5, z: 2 }, 330 - color: black, 331 - stroke: 4, 332 - closed: false, 333 - }); 334 - } 335 - 336 - }); 337 - 338 - var unibodyHeight = bodyHeight + bodyLineWidth; // 28 + 14 = 42 339 - // section size = 42/4 == 10.5 340 - var sectionSize = unibodyHeight / 4; 341 - 342 - // body lines 343 - [ magenta, orange, gold, blue ].forEach( function( color, i ) { 344 - var stripeGroup = new Zdog.Group({ 345 - addTo: bodySectionsAnchor, 346 - translate: { y: ( i - 1.5 ) * 10.5 }, 347 - }); 348 - var cylinder = new Zdog.Cylinder({ 349 - diameter: bodyLineWidth, 350 - length: sectionSize, 351 - addTo: stripeGroup, 352 - translate: { x: -bodyWidth/2 }, 353 - rotate: { x: -TAU/4 }, 354 - color: color, 355 - fill: true, 356 - stroke: false, 357 - }); 358 - cylinder.copyGraph({ 359 - translate: { x: bodyWidth/2 }, 360 - }); 361 - // panel to cover cylinders overlap 362 - var panel = new Zdog.Rect({ 363 - width: bodyWidth, 364 - height: sectionSize, 365 - addTo: stripeGroup, 366 - translate: { z: bodyLineWidth/2 }, 367 - color: color, 368 - fill: true, 369 - stroke: false, 370 - }); 371 - panel.copy({ 372 - translate: { z: -bodyLineWidth/2 }, 373 - }); 374 - }); 375 - 376 - // unibody composited rendering 377 - var unibodyRender = positiveUnibody.render; 378 - var bodyLinesCtx = bodyLinesIllo.ctx; 379 - positiveUnibody.render = function( ctx ) { 380 - unibodyRender.call( positiveUnibody, unibodyIllo.ctx, Zdog.CanvasRenderer ); 381 - // render body lines separately, on its own canvas 382 - bodyLinesCtx.globalCompositeOperation = 'source-over'; 383 - bodySectionsAnchor.renderGraphCanvas( bodyLinesCtx ); 384 - // composite bodyLines in unibody 385 - bodyLinesCtx.restore(); 386 - bodyLinesCtx.globalCompositeOperation = 'destination-in'; 387 - bodyLinesCtx.drawImage( unibodyCanvas, 0, 0 ); 388 - // draw unibody composite on to canvas 389 - ctx.restore(); 390 - ctx.drawImage( bodyLinesCanvas, 0, 0 ); 391 - // re-zoom 392 - mainIllo.ctx.save(); 393 - mainIllo.ctx.translate( mainIllo.width/2, mainIllo.height/2 ); 394 - var scale = mainIllo.pixelRatio * mainIllo.zoom; 395 - mainIllo.ctx.scale( scale, scale ); 396 - }; 397 - 398 - // -- animate --- // 399 - 400 - var t = 0; 401 - 402 - function animate() { 403 - update(); 404 - render(); 405 - requestAnimationFrame( animate ); 406 - } 407 - 408 - animate(); 409 - 410 - // -- update -- // 411 - 412 - function update() { 413 - if ( isSpinning ) { 414 - t += 1/180; 415 - var easeT = Zdog.easeInOut( t % 1, 3 ); 416 - camera.rotate.y = easeT*TAU*2 + jumpRotation.y; 417 - } 418 - 419 - camera.normalizeRotate(); 420 - var cameraRY = camera.rotate.y; 421 - // update cut-in rotates 422 - rightLegCutInA.rotate.y = -1.2 - cameraRY; 423 - rightLegCutInB.rotate.y = -1.2 - cameraRY; 424 - backLegCutIn.rotate.y = -1.4 - cameraRY; 425 - 426 - var isCameraYFront = cameraRY < TAU/4 || cameraRY > TAU *3/4; 427 - var isCameraYRight = cameraRY > TAU/2; 428 - bodyCutIn.rotate.y = isCameraYFront == isCameraYRight ? -1.5 : 1.5; 429 - bodyCutIn.rotate.y -= cameraRY; 430 - bodyCutIn.translate.x = isCameraYRight ? 3 : -3; 431 - 432 - crotchCutIn.visible = cameraRY < TAU/4 || cameraRY > TAU *7/8; 433 - 434 - // update cameras 435 - camera.updateGraph(); 436 - } 437 - 438 - // -- render -- // 439 - 440 - setJumpRotate(); 441 - 442 - function render() { 443 - var ctx = mainIllo.ctx; 444 - mainIllo.prerenderCanvas(); 445 - unibodyIllo.prerenderCanvas(); 446 - bodyLinesIllo.prerenderCanvas(); 447 - 448 - outlineAnchor.renderGraphCanvas( ctx ); 449 - positiveAnchor.renderGraphCanvas( ctx ); 450 - 451 - mainIllo.postrenderCanvas(); 452 - unibodyIllo.postrenderCanvas(); 453 - bodyLinesIllo.postrenderCanvas(); 454 - } 455 - 456 - // ----- inputs ----- // 457 - 458 - document.querySelector('.flat-button').onclick = function() { 459 - camera.rotate.set({}); 460 - }; 461 - 462 - document.querySelector('.jump-button').onclick = setJumpRotate; 463 - 464 - function setJumpRotate() { 465 - camera.rotate.set( jumpRotation ); 466 - } 467 - 468 - function getQuarterArcPoints( a, b ) { 469 - var start = new Zdog.Vector({ 470 - z: Zdog.lerp( a.z, b.z, 5/7 ), 471 - y: Zdog.lerp( a.y, b.y, 2/7 ), 472 - }); 473 - // control points 474 - var cp0 = new Zdog.Vector({ 475 - z: Zdog.lerp( a.z, b.z, 24/28 ), 476 - y: Zdog.lerp( a.y, b.y, 12/28 ), 477 - }); 478 - var cp1 = new Zdog.Vector({ 479 - z: b.z, 480 - y: Zdog.lerp( a.y, b.y, 5/7 ), 481 - }); 482 - 483 - return [ start, cp0, cp1 ]; 484 - }
-59
demo/fizzy-bear/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>fizzy-bear</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #19F; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0 auto; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - <p> 37 - <button class="flat-button">View flat</button> 38 - <button class="jump-button">View jump</button> 39 - </p> 40 - 41 - </div> 42 - 43 - <script src="../../js/boilerplate.js"></script> 44 - <script src="../../js/canvas-renderer.js"></script> 45 - <script src="../../js/vector.js"></script> 46 - <script src="../../js/path-command.js"></script> 47 - <script src="../../js/anchor.js"></script> 48 - <script src="../../js/shape.js"></script> 49 - <script src="../../js/ellipse.js"></script> 50 - <script src="../../js/rect.js"></script> 51 - <script src="../../js/rounded-rect.js"></script> 52 - <script src="../../js/group.js"></script> 53 - <script src="../../js/cylinder.js"></script> 54 - <script src="../../js/dragger.js"></script> 55 - <script src="../../js/illustration.js"></script> 56 - <script src="fizzy-bear.js"></script> 57 - 58 - </body> 59 - </html>
-50
demo/fps-counter.js
··· 1 - ( function() { 2 - 3 - var outputElem = document.createElement('div'); 4 - outputElem.style.fontFamily = 'monospace'; 5 - outputElem.style.fontSize = '20px'; 6 - outputElem.style.position = 'absolute'; 7 - outputElem.style.top = '10px'; 8 - outputElem.style.left = '10px'; 9 - 10 - var prevTickTime = new Date(); 11 - var prevUpdateTime = new Date(); 12 - 13 - var tickTimeDeltas = []; 14 - 15 - function tick() { 16 - var now = new Date(); 17 - var tickTimeDelta = now - prevTickTime; 18 - tickTimeDeltas.push( tickTimeDelta ); 19 - 20 - var updateTimeDelta = now - prevUpdateTime; 21 - // update every half second 22 - if ( updateTimeDelta > 500 ) { 23 - update( now ); 24 - } 25 - prevTickTime = now; 26 - requestAnimationFrame( tick ); 27 - } 28 - 29 - function update( now ) { 30 - var avgDelta = averageArray( tickTimeDeltas ); 31 - outputElem.textContent = Math.round( 1000 / avgDelta ); 32 - 33 - // reset 34 - tickTimeDeltas = []; 35 - prevUpdateTime = now; 36 - } 37 - 38 - function averageArray( ary ) { 39 - var sum = 0; 40 - var length = ary.length; 41 - for ( var i=0; i < length; i++ ) { 42 - sum += ary[i]; 43 - } 44 - return sum / length; 45 - } 46 - 47 - document.body.appendChild( outputElem ); 48 - tick(); 49 - 50 - })();
-111
demo/gear-icon/gear-icon.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 7 - var zoom = Math.floor( minWindowSize / w ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - var isSpinning = true; 11 - var TAU = Zdog.TAU; 12 - 13 - var illo = new Zdog.Illustration({ 14 - element: illoElem, 15 - zoom: zoom, 16 - rotate: { x: -TAU/8 }, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // -- illustration shapes --- // 24 - 25 - var teeth = 8; 26 - var frontZ = { z: 3 }; 27 - var backZ = { z: -3 }; 28 - 29 - var colorA = '#EA0'; 30 - var colorB = '#345'; 31 - 32 - var gearPath = ( function() { 33 - var path = []; 34 - var teethCount = teeth * 4; 35 - for ( var i=0; i < teethCount; i++ ) { 36 - var isOuter = i % 4 < 2; 37 - var radius = isOuter ? 12 : 9.5; 38 - var theta = Math.ceil( i/2 ) * 2; 39 - theta += i % 2 ? -0.2 : 0.2; 40 - theta = ( theta/teethCount + 1/teethCount ) * TAU ; 41 - path.push({ 42 - x: Math.cos( theta ) * radius, 43 - y: Math.sin( theta ) * radius, 44 - }); 45 - } 46 - return path; 47 - })(); 48 - 49 - var gear = new Zdog.Anchor({ 50 - addTo: illo, 51 - rotate: { x: TAU/4 }, 52 - }); 53 - 54 - var gearSide = new Zdog.Anchor({ 55 - addTo: gear, 56 - translate: frontZ, 57 - }); 58 - // gear face 59 - new Zdog.Shape({ 60 - addTo: gearSide, 61 - path: gearPath, 62 - color: colorA, 63 - backface: false, 64 - fill: true, 65 - stroke: 1/zoom, 66 - closed: false, 67 - // visible: false, 68 - }); 69 - // nub 70 - new Zdog.Cylinder({ 71 - addTo: gearSide, 72 - diameter: 6, 73 - length: 2, 74 - color: colorB, 75 - backface: 'white', 76 - translate: { z: 1 }, 77 - fill: true, 78 - stroke: false, 79 - }); 80 - 81 - gearSide.copyGraph({ 82 - rotate: { y: TAU/2 }, 83 - translate: backZ, 84 - }); 85 - 86 - gearPath.forEach( function( corner, i ) { 87 - var nextCorner = gearPath[ i + 1 ] || gearPath[0]; 88 - new Zdog.Shape({ 89 - addTo: gear, 90 - path: [ 91 - new Zdog.Vector( corner ).add( frontZ ), 92 - new Zdog.Vector( corner ).add( backZ ), 93 - new Zdog.Vector( nextCorner ).add( backZ ), 94 - new Zdog.Vector( nextCorner ).add( frontZ ), 95 - ], 96 - color: i % 2 ? colorA : colorB, 97 - fill: true, 98 - stroke: 1/zoom, 99 - }); 100 - }); 101 - 102 - // -- animate --- // 103 - 104 - function animate() { 105 - illo.rotate.y += isSpinning ? +TAU/240 : 0; 106 - illo.updateRenderGraph(); 107 - requestAnimationFrame( animate ); 108 - } 109 - 110 - animate(); 111 -
-52
demo/gear-icon/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>gear-icon</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/cylinder.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="gear-icon.js"></script> 50 - 51 - </body> 52 - </html>
-960
demo/happy-town/happy-town.js
··· 1 - /* globals makeBuilding, lilPyramid, hedge, red, blue, navy, gold, white */ 2 - 3 - // -------------------------- demo -------------------------- // 4 - 5 - var illoElem = document.querySelector('.illo'); 6 - var w = 160; 7 - var h = 160; 8 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 9 - var zoom = Math.min( 6, Math.floor( minWindowSize / w ) ); 10 - illoElem.setAttribute( 'width', w * zoom ); 11 - illoElem.setAttribute( 'height', h * zoom ); 12 - 13 - var isSpinning = true; 14 - var TAU = Zdog.TAU; 15 - 16 - var illo = new Zdog.Illustration({ 17 - element: illoElem, 18 - zoom: zoom, 19 - rotate: { y: TAU/8 }, 20 - dragRotate: true, 21 - onDragStart: function() { 22 - isSpinning = false; 23 - }, 24 - }); 25 - 26 - // default to flat, filled shapes 27 - [ Zdog.Shape, Zdog.Rect, Zdog.Ellipse ].forEach( function( ItemClass ) { 28 - ItemClass.defaults.fill = true; 29 - ItemClass.defaults.stroke = false; 30 - }); 31 - 32 - // -- illustration shapes --- // 33 - 34 - var quarterView = 1/Math.sin(TAU/8); 35 - 36 - // anchor 37 - var town = new Zdog.Group({ 38 - addTo: illo, 39 - translate: { y: 36 }, 40 - scale: { x: quarterView, z: quarterView }, 41 - updateSort: true, 42 - }); 43 - 44 - // ----- front building ----- // 45 - 46 - var frontAnchor = new Zdog.Anchor({ 47 - addTo: town, 48 - translate: { x: 16, y: -4, z: 20 }, 49 - }); 50 - 51 - var frontBuilding = makeBuilding({ 52 - width: 22, 53 - depth: 16, 54 - height: 20, 55 - addTo: frontAnchor, 56 - gable: 'ew', 57 - southWindows: [ 3, 1 ], 58 - eastWindows: [ 2, 2 ], 59 - westWindows: [ 2, 2 ], 60 - northWindows: [ 3, 2 ], 61 - }); 62 - 63 - // east gable dot 64 - var gableDot = new Zdog.Ellipse({ 65 - diameter: 2, 66 - addTo: frontBuilding.eastWall, 67 - color: blue, 68 - translate: { y: -20 }, 69 - }); 70 - // west gable dot 71 - gableDot.copy({ 72 - addTo: frontBuilding.westWall, 73 - color: navy, 74 - }); 75 - 76 - // south doors 77 - var door = new Zdog.Shape({ 78 - path: [ 79 - { x: -2.5, y: 0 }, 80 - { x: -2.5, y: -5.5 }, 81 - { arc: [ 82 - { x: -2.5, y: -8 }, 83 - { x: 0, y: -8 }, 84 - ]}, 85 - { arc: [ 86 - { x: 2.5, y: -8 }, 87 - { x: 2.5, y: -5.5 }, 88 - ]}, 89 - { x: 2.5, y: 0 }, 90 - ], 91 - addTo: frontBuilding.southWall, 92 - translate: { x: -4.5 }, 93 - color: navy, 94 - }); 95 - door.copy({ 96 - translate: { x: 4.5 }, 97 - }); 98 - 99 - [ -1, 1 ].forEach( function( zSide ) { 100 - var frontGableGroup = new Zdog.Group({ 101 - addTo: frontAnchor, 102 - translate: { y: -20, z: -8*zSide }, 103 - }); 104 - 105 - // front building gable 106 - new Zdog.Shape({ 107 - path: [ 108 - { x: 0, y: -6 }, 109 - { x: -6, y: 0 }, 110 - { x: 6, y: 0 }, 111 - ], 112 - addTo: frontGableGroup, 113 - translate: { y: 1 }, 114 - color: zSide == -1 ? red : gold, 115 - }); 116 - 117 - gableDot.copy({ 118 - addTo: frontGableGroup, 119 - translate: { y: -2 }, 120 - color: zSide == -1 ? navy : red, 121 - }); 122 - 123 - var frontGableSide = new Zdog.Shape({ 124 - path: [ 125 - { x: 0, y: 0, z: 0 }, 126 - { x: 5, y: 5, z: 0 }, 127 - { x: 0, y: 0, z: 5*zSide }, 128 - ], 129 - addTo: frontAnchor, 130 - translate: { y: -25, z: -8*zSide }, 131 - color: gold, 132 - }); 133 - frontGableSide.copy({ 134 - scale: { x: -1 }, 135 - color: navy, 136 - }); 137 - 138 - }); 139 - 140 - 141 - // ----- left building ----- // 142 - 143 - var leftAnchor = new Zdog.Anchor({ 144 - addTo: town, 145 - translate: { x: -13, y: -10, z: 23 }, 146 - }); 147 - 148 - var leftBuilding = makeBuilding({ 149 - width: 16, 150 - depth: 22, 151 - height: 20, 152 - addTo: leftAnchor, 153 - gable: 'ns', 154 - southWindows: [ 2, 2 ], 155 - eastWindows: [ 3, 2 ], 156 - westWindows: [ 3, 1 ], 157 - northWindows: [ 2, 2 ], 158 - }); 159 - 160 - door.copy({ 161 - addTo: leftBuilding.westWall, 162 - translate: { x: -4.5 }, 163 - }); 164 - door.copy({ 165 - addTo: leftBuilding.westWall, 166 - translate: { x: 4.5 }, 167 - }); 168 - 169 - // ----- cupola ----- // 170 - 171 - var cupolaNSPanel = new Zdog.Shape({ 172 - path: [ 173 - { x: -1, y: 0 }, 174 - { x: 3, y: 0 }, 175 - { x: 3, y: 9 }, 176 - { x: -1, y: 5 }, 177 - // HACK add point to sort in front of roof 178 - { move: { x: 8, z: 4 } }, 179 - ], 180 - addTo: leftAnchor, 181 - translate: { y: -34, z: 3 }, 182 - color: red, 183 - }); 184 - cupolaNSPanel.copy({ 185 - scale: { x: -1 }, 186 - }); 187 - cupolaNSPanel.copy({ 188 - scale: { z: -1 }, 189 - translate: { y: -34, z: -3 }, 190 - color: gold, 191 - }); 192 - cupolaNSPanel.copy({ 193 - translate: { y: -34, z: -3 }, 194 - scale: { x: -1, z: -1 }, 195 - color: gold, 196 - }); 197 - 198 - [ -1, 1 ].forEach( function( xSide ) { 199 - var group = new Zdog.Group({ 200 - addTo: leftAnchor, 201 - translate: { y: -34, x: 3*xSide }, 202 - }); 203 - // ew panel 204 - new Zdog.Shape({ 205 - path: [ 206 - { z: 3, y: 0 }, 207 - { z: 0, y: -3 }, 208 - { z: -3, y: 0 }, 209 - { z: -3, y: 9 }, 210 - { z: 3, y: 9 }, 211 - // HACK add point to sort in front of roof 212 - { move: { x: 16*xSide } }, 213 - ], 214 - addTo: group, 215 - color: xSide == -1 ? blue : white, 216 - }); 217 - gableDot.copy({ 218 - addTo: group, 219 - translate: { y: 3 }, 220 - rotate: { y: TAU/4 }, 221 - color: xSide == -1 ? navy : blue, 222 - }); 223 - }); 224 - 225 - // cupola roof panel 226 - var cupolaRoofPanel = new Zdog.Shape({ 227 - path: [ 228 - { x: -3, y: -3, z: 0 }, 229 - { x: 3, y: -3, z: 0 }, 230 - { x: 3, y: 0, z: 3 }, 231 - { x: -3, y: 0, z: 3 }, 232 - ], 233 - addTo: leftAnchor, 234 - translate: { y: -34 }, 235 - color: navy, 236 - }); 237 - cupolaRoofPanel.copy({ 238 - scale: { z: -1 }, 239 - color: red, 240 - }); 241 - 242 - 243 - // ----- left building slopes ----- // 244 - 245 - // east slope 246 - var leftEWSlope = new Zdog.Shape({ 247 - path: [ 248 - { x: 0, y: 0, z: 11 }, 249 - { x: 0, y: 0, z: -11 }, 250 - { x: 6, y: 6, z: -11 }, 251 - { x: 6, y: 6, z: 11 }, 252 - ], 253 - addTo: leftAnchor, 254 - translate: { x: 8 }, 255 - color: gold, 256 - }); 257 - // west slope 258 - leftEWSlope.copy({ 259 - scale: { x: -1 }, 260 - translate: { x: -8 }, 261 - color: gold, 262 - }); 263 - 264 - // south slope 265 - new Zdog.Shape({ 266 - path: [ 267 - { z: 0, y: 0, x: -8 }, 268 - { z: 0, y: 0, x: 8 }, 269 - { z: 6, y: 6, x: 8 }, 270 - { z: 6, y: 6, x: -8 }, 271 - ], 272 - addTo: leftAnchor, 273 - translate: { z: 11 }, 274 - color: navy, 275 - }); 276 - 277 - // south east corner 278 - var leftCorner = new Zdog.Shape({ 279 - path: [ 280 - { x: 0, y: 0, z: 0 }, 281 - { x: 6, y: 6, z: 0 }, 282 - { x: 0, y: 6, z: 6 }, 283 - ], 284 - addTo: leftAnchor, 285 - translate: { x: 8, z: 11 }, 286 - color: red, 287 - }); 288 - // south west corner 289 - leftCorner.copy({ 290 - scale: { x: -1 }, 291 - translate: { x: -8, z: 11 }, 292 - color: blue, 293 - }); 294 - 295 - 296 - 297 - // ----- back tower ----- // 298 - 299 - var towerAnchor = new Zdog.Anchor({ 300 - addTo: town, 301 - translate: { x: -13, y: -24, z: -4 }, 302 - }); 303 - 304 - var tower = makeBuilding({ 305 - width: 16, 306 - depth: 16, 307 - height: 28, 308 - addTo: towerAnchor, 309 - gable: 'ns', 310 - southWindows: [ 2, 3 ], 311 - eastWindows: [ 2, 2 ], 312 - westWindows: [ 2, 3 ], 313 - northWindows: [ 2, 3 ], 314 - }); 315 - 316 - door.copy({ 317 - addTo: tower.eastWall, 318 - translate: { x: 0 }, 319 - color: blue, 320 - }); 321 - 322 - gableDot.copy({ 323 - addTo: tower.southWall, 324 - translate: { y: -29 }, 325 - color: navy, 326 - }); 327 - 328 - gableDot.copy({ 329 - addTo: tower.northWall, 330 - translate: { y: -29 }, 331 - color: red, 332 - }); 333 - 334 - var towerChimney = new Zdog.Shape({ 335 - addTo: towerAnchor, 336 - path: [ { y: 0 }, { y: 4 } ], 337 - translate: { x: -2, y: -37, z: 1 }, 338 - stroke: 2, 339 - color: navy, 340 - }); 341 - towerChimney.copy({ 342 - translate: { x: -2, y: -37, z: -3 }, 343 - }); 344 - 345 - // plume 346 - new Zdog.Shape({ 347 - path: [ 348 - { x: -3, y: 1 }, 349 - { arc: [ 350 - { x: -3, y: -1 }, 351 - { x: -1, y: -1 }, 352 - ]}, 353 - { x: 3, y: -1 }, 354 - { arc: [ 355 - { x: 3, y: 1 }, 356 - { x: 1, y: 1 }, 357 - ]}, 358 - ], 359 - addTo: towerAnchor, 360 - translate: { x: -2, y: -42, z: -6 }, 361 - rotate: { y: -TAU/4 }, 362 - stroke: 2, 363 - color: blue 364 - }); 365 - 366 - // ----- tower slopes ----- // 367 - 368 - // big east slope 369 - var towerEWSlope = new Zdog.Shape({ 370 - path: [ 371 - { x: 0, y: 0, z: 1 }, 372 - { x: 0, y: 0, z: -1 }, 373 - { x: 1, y: 1, z: -1 }, 374 - { x: 1, y: 1, z: 1 }, 375 - ], 376 - addTo: towerAnchor, 377 - translate: { x: 8 }, 378 - // size by scaling 379 - scale: { x: 20, y: 20, z: 8 }, 380 - color: gold, 381 - }); 382 - 383 - // south slope down to left building 384 - var towerNSSLope = new Zdog.Shape({ 385 - path: [ 386 - { z: 0, y: 0, x: 1 }, 387 - { z: 0, y: 0, x: -1 }, 388 - { z: 1, y: 1, x: -1 }, 389 - { z: 1, y: 1, x: 1 }, 390 - ], 391 - addTo: towerAnchor, 392 - translate: { z: 8 }, 393 - scale: { x: 8, y: 14, z: 8 }, 394 - color: navy, 395 - }); 396 - 397 - // south east corner 398 - new Zdog.Shape({ 399 - path: [ 400 - { x: 0, y: 0, z: 0 }, 401 - { x: 20, y: 20, z: 0 }, 402 - { x: 6, y: 20, z: 8 }, 403 - { x: 0, y: 14, z: 8 }, 404 - ], 405 - addTo: towerAnchor, 406 - translate: { x: 8, z: 8 }, 407 - color: red, 408 - }); 409 - 410 - // north slope 411 - towerNSSLope.copy({ 412 - translate: { z: -8 }, 413 - scale: { x: 8, y: 20, z: -7 }, 414 - color: gold, 415 - }); 416 - 417 - // north east corner 418 - new Zdog.Shape({ 419 - path: [ 420 - { x: 0, y: 0, z: 0 }, 421 - { x: 20, y: 20, z: 0 }, 422 - { x: 0, y: 20, z: -7 }, 423 - ], 424 - addTo: towerAnchor, 425 - translate: { x: 8, z: -8 }, 426 - color: gold, 427 - }); 428 - 429 - // west slope 430 - towerEWSlope.copy({ 431 - scale: { x: -12, y: 20, z: 8 }, 432 - translate: { x: -8 }, 433 - color: gold, 434 - }); 435 - 436 - // north west corner 437 - new Zdog.Shape({ 438 - path: [ 439 - { x: 0, y: 0, z: 0 }, 440 - { x: -12, y: 20, z: 0 }, 441 - { x: 0, y: 20, z: -7 }, 442 - ], 443 - addTo: towerAnchor, 444 - translate: { x: -8, z: -8 }, 445 - color: red, 446 - }); 447 - 448 - // south west corner back to left building 449 - new Zdog.Shape({ 450 - path: [ 451 - { x: 0, y: 0, z: 0 }, 452 - { x: -12, y: 20, z: 0 }, 453 - { x: -6, y: 20, z: 8 }, 454 - { x: 0, y: 14, z: 8 }, 455 - ], 456 - addTo: towerAnchor, 457 - translate: { x: -8, z: 8 }, 458 - color: blue, 459 - }); 460 - 461 - // ----- church ----- // 462 - 463 - var churchAnchor = new Zdog.Anchor({ 464 - addTo: town, 465 - translate: { x: -5, y: -4, z: -27 }, 466 - }); 467 - 468 - var church = makeBuilding({ 469 - isChurch: true, // special flag for roof 470 - width: 22, 471 - depth: 16, 472 - height: 28, 473 - addTo: churchAnchor, 474 - gable: 'ew', 475 - southWindows: [ 3, 2 ], 476 - eastWindows: [ 2, 2 ], 477 - northWindows: [ 3, 2 ], 478 - }); 479 - 480 - door.copy({ 481 - addTo: church.westWall, 482 - translate: { x: -3.5 }, 483 - }); 484 - door.copy({ 485 - addTo: church.westWall, 486 - translate: { x: 3.5 }, 487 - }); 488 - 489 - // big circle window 490 - new Zdog.Ellipse({ 491 - diameter: 8, 492 - addTo: church.westWall, 493 - translate: { y: -22 }, 494 - color: navy, 495 - }); 496 - 497 - // ----- bell tower ----- // 498 - 499 - ( function() { 500 - 501 - var bellTowerAnchor = new Zdog.Anchor({ 502 - addTo: churchAnchor, 503 - translate: { x: -7, y: -36, z: -4 }, 504 - }); 505 - 506 - // tower ledge 507 - new Zdog.Rect({ 508 - width: 8, 509 - height: 8, 510 - addTo: bellTowerAnchor, 511 - translate: { y: -12 }, 512 - rotate: { x: TAU/4 }, 513 - color: navy, 514 - }); 515 - 516 - var wallColors = [ red, white, gold, blue ]; 517 - var accentColors = [ navy, blue, red, navy ]; 518 - var roofColors = [ navy, gold, red, navy ]; 519 - 520 - for ( var i=0; i < 4; i++ ) { 521 - var wallAnchor = new Zdog.Anchor({ 522 - addTo: bellTowerAnchor, 523 - rotate: { y: TAU/4 * -i }, 524 - }); 525 - var bottomWallGroup = new Zdog.Group({ 526 - addTo: wallAnchor, 527 - translate: { z: 4 } 528 - }); 529 - 530 - var wallColor = wallColors[i]; 531 - var accentColor = accentColors[i]; 532 - var roofColor = roofColors[i]; 533 - 534 - // bottom wall 535 - new Zdog.Rect({ 536 - width: 8, 537 - height: 12, 538 - addTo: bottomWallGroup, 539 - translate: { y: -6 }, 540 - color: wallColor, 541 - }); 542 - // circle cut-out 543 - new Zdog.Ellipse({ 544 - diameter: 4, 545 - addTo: bottomWallGroup, 546 - translate: { y: -4 }, 547 - color: accentColor, 548 - }); 549 - // top stripe 550 - new Zdog.Rect({ 551 - width: 8, 552 - height: 2, 553 - addTo: bottomWallGroup, 554 - translate: { y: -9 }, 555 - color: accentColor, 556 - }); 557 - 558 - var topWallGroup = new Zdog.Group({ 559 - addTo: wallAnchor, 560 - translate: { y: -12, z: 3 }, 561 - }); 562 - // top wall 563 - new Zdog.Rect({ 564 - width: 6, 565 - height: 7, 566 - addTo: topWallGroup, 567 - translate: { y: -3.5 }, 568 - color: wallColor, 569 - }); 570 - // top window 571 - new Zdog.Rect({ 572 - width: 2, 573 - height: 5, 574 - addTo: topWallGroup, 575 - translate: { y: -2.5 }, 576 - color: accentColor, 577 - }); 578 - 579 - // roof 580 - new Zdog.Shape({ 581 - path: [ 582 - { x: 0, y: 0, z: 0 }, 583 - { x: -3, y: 6, z: 3 }, 584 - { x: 3, y: 6, z: 3 }, 585 - ], 586 - addTo: wallAnchor, 587 - translate: { y: -25 }, 588 - color: roofColor, 589 - }); 590 - } 591 - 592 - // roof connectors 593 - // south, white side 594 - new Zdog.Shape({ 595 - path: [ 596 - { z: 4, y: 0 }, 597 - { z: -4, y: -1 }, 598 - { z: -4, y: 8 }, 599 - ], 600 - addTo: bellTowerAnchor, 601 - translate: { x: 4 }, 602 - color: white, 603 - }); 604 - // east gold side 605 - var connector = new Zdog.Rect({ 606 - width: 8, 607 - height: 10, 608 - addTo: bellTowerAnchor, 609 - translate: { z: -4, y: 4 }, 610 - color: gold, 611 - }); 612 - // north blue side 613 - connector.copy({ 614 - translate: { x: -4, y: 4 }, 615 - rotate: { y: TAU/4 }, 616 - color: blue, 617 - }); 618 - 619 - })(); 620 - 621 - // ----- hill ----- // 622 - 623 - new Zdog.Shape({ 624 - path: [ 625 - { x: 0, y: 2 }, 626 - { x: 10, y: 2 }, 627 - { bezier: [ 628 - { x: 14, y: 2 }, 629 - { x: 20, y: 10 }, 630 - { x: 24, y: 10 }, 631 - ]}, 632 - { x: 30, y: 10 }, 633 - { arc: [ 634 - { x: 34, y: 10 }, 635 - { x: 34, y: 14 }, 636 - ]}, 637 - // bring it back into hill 638 - { x: 14, y: 14, z: 0 }, 639 - ], 640 - addTo: town, 641 - translate: { x: -6, y: -20, z: -12 }, 642 - stroke: 4, 643 - color: gold, 644 - }); 645 - 646 - // ----- lil pyramids ----- // 647 - 648 - // front in front of left building 649 - lilPyramid({ 650 - addTo: town, 651 - translate: { x: 6, z: 35, y: -4 }, 652 - }); 653 - 654 - // behind left building 655 - 656 - lilPyramid({ 657 - addTo: town, 658 - translate: { x: -34, z: 20, y: -4 }, 659 - }); 660 - 661 - 662 - // front right 663 - lilPyramid({ 664 - addTo: town, 665 - translate: { x: 35, z: 8, y: -4 }, 666 - }); 667 - 668 - lilPyramid({ 669 - addTo: town, 670 - translate: { x: 31, z: -2, y: -4 }, 671 - }); 672 - // in front of church 673 - lilPyramid({ 674 - addTo: town, 675 - translate: { x: 22, z: -28, y: -4 }, 676 - }); 677 - 678 - // ----- hedges ----- // 679 - 680 - // to right of front building 681 - hedge({ 682 - addTo: town, 683 - translate: { x: 24, y: -4, z: 4 }, 684 - }); 685 - 686 - // right of church 687 - hedge({ 688 - addTo: town, 689 - translate: { x: -4, y: -4, z: -42 }, 690 - }); 691 - // in between tower & church 692 - hedge({ 693 - addTo: town, 694 - translate: { x: -30, y: -4, z: -18 }, 695 - // color: gold, 696 - }); 697 - 698 - hedge({ 699 - addTo: town, 700 - translate: { x: 9, y: -4, z: -17 }, 701 - // color: gold, 702 - }); 703 - 704 - 705 - // ----- sun ----- // 706 - 707 - new Zdog.Shape({ 708 - addTo: town, 709 - translate: { x: -6, y: -52, z: -42 }, 710 - stroke: 6, 711 - color: gold, 712 - }); 713 - 714 - // ----- sky particles ----- // 715 - 716 - // dot above left building 717 - var skyDot = new Zdog.Shape({ 718 - translate: { x: -3, y: -48, z: 42 }, 719 - addTo: town, 720 - stroke: 2, 721 - color: white, 722 - }); 723 - 724 - // in front of church 725 - skyDot.copy({ 726 - translate: { x: 30, y: -28, z: -28 }, 727 - }); 728 - 729 - var skyDiamond = new Zdog.Shape({ 730 - path: [ 731 - { x: 0, y: -1 }, 732 - { x: 1, y: 0 }, 733 - { x: 0, y: 1 }, 734 - { x: -1, y: 0 }, 735 - ], 736 - addTo: town, 737 - translate: { x: -27, y: -45, z: 29 }, 738 - scale: 0.75, 739 - stroke: 0.5, 740 - color: white, 741 - }); 742 - skyDiamond.copy({ 743 - rotate: { y: TAU/4 }, 744 - }); 745 - 746 - var skyDiamond2 = skyDiamond.copy({ 747 - translate: { x: 8, y: -34, z: -42 }, 748 - }); 749 - skyDiamond2.copy({ 750 - rotate: { y: TAU/4, }, 751 - }); 752 - 753 - var skyStar = new Zdog.Shape({ 754 - path: [ 755 - { x: 0, y: -1 }, 756 - { arc: [ 757 - { x: 0, y: 0 }, 758 - { x: 1, y: 0 }, 759 - ]}, 760 - { arc: [ 761 - { x: 0, y: 0 }, 762 - { x: 0, y: 1 }, 763 - ]}, 764 - { arc: [ 765 - { x: 0, y: 0 }, 766 - { x: -1, y: 0 }, 767 - ]}, 768 - { arc: [ 769 - { x: 0, y: 0 }, 770 - { x: 0, y: -1 }, 771 - ]}, 772 - ], 773 - addTo: town, 774 - translate: { x: -39, y: -51, z: 12 }, 775 - scale: 1.5, 776 - stroke: 1, 777 - color: white, 778 - }); 779 - skyStar.copy({ 780 - rotate: { y: TAU/4 }, 781 - }); 782 - 783 - // up front 784 - var skyStar2 = skyStar.copy({ 785 - translate: { x: 29, y: -42, z: 30 }, 786 - color: white, 787 - }); 788 - skyStar2.copy({ 789 - rotate: { y: TAU/4 }, 790 - }); 791 - 792 - // ----- clouds ----- // 793 - 794 - var cloud = new Zdog.Ellipse({ 795 - addTo: town, 796 - diameter: 3, 797 - quarters: 2, 798 - translate: { x: -30, y: -56, z: 10 }, 799 - rotate: { y: TAU/4, z: -TAU/4 }, 800 - stroke: 2, 801 - closed: true, 802 - color: white, 803 - }); 804 - cloud.copy({ 805 - translate: { x: -30, y: -57, z: 6 }, 806 - }); 807 - cloud.copy({ 808 - translate: { x: -30, y: -56, z: 2 }, 809 - }); 810 - 811 - // line underneath 812 - new Zdog.Shape({ 813 - addTo: town, 814 - path: [ { x: -1 }, { x: 1 } ], 815 - translate: { x: -30, y: -56, z: 6 }, 816 - scale: { x: 2 }, 817 - rotate: { y: TAU/4 }, 818 - stroke: 2, 819 - color: white, 820 - }); 821 - 822 - // ----- flat earth ----- // 823 - 824 - var flatEarth = new Zdog.Ellipse({ 825 - diameter: 128, 826 - addTo: illo, 827 - translate: town.translate, 828 - rotate: { x: TAU/4 }, 829 - stroke: 8, 830 - color: navy, 831 - }); 832 - 833 - // ----- sky ----- // 834 - 835 - var sky = new Zdog.Group({ 836 - addTo: illo, 837 - translate: town.translate, 838 - // translate: { y: 2 }, 839 - }); 840 - 841 - ( function() { 842 - var topYs = [ 843 - -64, -64, -52, -52, 844 - -44, -44, -36, -36, 845 - -44, -44, -52, -52, 846 - -60, -60, -52, -52, 847 - ]; 848 - var bottomYs = [ 849 - -24, -24, -16, -16, 850 - -8, -8, -0, -0, 851 - -8, -8, -16, -16, 852 - -24, -24, -32, -32, 853 - ]; 854 - var radius = 64; 855 - var skyPanelCount = topYs.length; 856 - var angle = TAU / skyPanelCount; 857 - var panelWidth = Math.tan( angle/2 ) * radius * 2; 858 - for ( var i=0; i < skyPanelCount; i++ ) { 859 - var nextI = (i + 1) % skyPanelCount; 860 - var topYA = topYs[ i ]; 861 - var topYB = topYs[ nextI ]; 862 - var bottomYA = bottomYs[ i ]; 863 - var bottomYB = bottomYs[ nextI ]; 864 - var panelAnchor = new Zdog.Anchor({ 865 - addTo: sky, 866 - rotate: { y: angle * i - TAU/4 }, 867 - translate: { y: 1 }, 868 - }); 869 - new Zdog.Shape({ 870 - path: [ 871 - { x: -panelWidth/2, y: topYA }, 872 - { bezier: [ 873 - { x: 0, y: topYA }, 874 - { x: 0, y: topYB }, 875 - { x: panelWidth/2, y: topYB }, 876 - ]}, 877 - { x: panelWidth/2, y: bottomYB }, 878 - { bezier: [ 879 - { x: 0, y: bottomYB }, 880 - { x: 0, y: bottomYA }, 881 - { x: -panelWidth/2, y: bottomYA }, 882 - ]}, 883 - ], 884 - addTo: panelAnchor, 885 - translate: { z: -radius }, 886 - color: blue, 887 - stroke: 1, 888 - backface: false, 889 - }); 890 - } 891 - })(); 892 - 893 - // -- animate --- // 894 - 895 - var t = 0; 896 - var tSpeed = 1/120; 897 - var then = new Date() - 1/60; 898 - 899 - function animate() { 900 - update(); 901 - render(); 902 - requestAnimationFrame( animate ); 903 - } 904 - 905 - animate(); 906 - 907 - // -- update -- // 908 - 909 - function update() { 910 - var now = new Date(); 911 - var delta = now - then; 912 - 913 - if ( isSpinning ) { 914 - t += tSpeed * delta/60; 915 - var theta = Zdog.easeInOut( t % 1 ) * TAU; 916 - var rev = 1; 917 - var spin = -theta * rev + TAU/8; 918 - var extraRotation = TAU * rev * Math.floor( ( t % 4 ) ); 919 - illo.rotate.y = spin - extraRotation; 920 - var everyOtherCycle = t % 2 < 1; 921 - illo.rotate.x = everyOtherCycle ? 0 : ( Math.cos( theta ) * -0.5 + 0.5 ) * TAU * -1/8; 922 - } 923 - illo.normalizeRotate(); 924 - 925 - // rotate 926 - illo.updateGraph(); 927 - 928 - then = now; 929 - } 930 - 931 - // -- render -- // 932 - 933 - function render() { 934 - var ctx = illo.ctx; 935 - illo.prerenderCanvas(); 936 - 937 - // render shapes 938 - var isCameraXUp = illo.rotate.x < 0 || illo.rotate.x > TAU/2; 939 - 940 - sky.renderGraphCanvas( ctx ); 941 - 942 - // HACK sort flat earth & town shapes manually 943 - if ( isCameraXUp ) { 944 - flatEarth.renderGraphCanvas( ctx ); 945 - } 946 - town.renderGraphCanvas( ctx ); 947 - if ( !isCameraXUp ) { 948 - flatEarth.renderGraphCanvas( ctx ); 949 - } 950 - 951 - illo.postrenderCanvas(); 952 - ctx.restore(); 953 - } 954 - 955 - // ----- inputs ----- // 956 - 957 - document.querySelector('.reset-button').onclick = function() { 958 - isSpinning = false; 959 - illo.rotate.set({ x: 0, y: TAU/8 }); 960 - };
-24
demo/happy-town/hedge.js
··· 1 - function hedge( options ) { 2 - var anchor = new Zdog.Anchor({ 3 - addTo: options.addTo, 4 - translate: options.translate, 5 - }); 6 - 7 - var ball = new Zdog.Shape({ 8 - path: [ { y: 0 }, { y: -1 } ], 9 - addTo: anchor, 10 - translate: { y: -2.5 }, 11 - stroke: 5, 12 - color: options.color || navy, 13 - }); 14 - 15 - ball.copy({ 16 - stroke: 4, 17 - translate: { y: -5 }, 18 - }); 19 - 20 - ball.copy({ 21 - stroke: 2.5, 22 - translate: { y: -7.5 }, 23 - }); 24 - }
-65
demo/happy-town/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>happy town</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - <p><button class="reset-button">Reset</button></p> 37 - </div> 38 - 39 - <script src="../../js/boilerplate.js"></script> 40 - <script src="../../js/canvas-renderer.js"></script> 41 - <script src="../../js/vector.js"></script> 42 - <script src="../../js/path-command.js"></script> 43 - <script src="../../js/anchor.js"></script> 44 - <script src="../../js/shape.js"></script> 45 - <script src="../../js/ellipse.js"></script> 46 - <script src="../../js/rect.js"></script> 47 - <script src="../../js/group.js"></script> 48 - <script src="../../js/dragger.js"></script> 49 - <script src="../../js/illustration.js"></script> 50 - <script src="../fps-counter.js"></script> 51 - <script> 52 - // colors 53 - var red = '#F44'; 54 - var navy = '#247'; 55 - var blue = '#5AE'; 56 - var gold = '#FB3'; 57 - var white = 'white'; 58 - </script> 59 - <script src="make-building.js"></script> 60 - <script src="lil-pyramid.js"></script> 61 - <script src="hedge.js"></script> 62 - <script src="happy-town.js"></script> 63 - 64 - </body> 65 - </html>
-32
demo/happy-town/lil-pyramid.js
··· 1 - // -------------------------- lilPyramid -------------------------- // 2 - 3 - function lilPyramid( options ) { 4 - var anchor = new Zdog.Anchor({ 5 - addTo: options.addTo, 6 - translate: options.translate, 7 - }); 8 - 9 - var panel = new Zdog.Shape({ 10 - path: [ 11 - { x: 0, y: -3, z: 0 }, 12 - { x: 3, y: 0, z: 0 }, 13 - { x: 0, y: 0, z: 3 }, 14 - ], 15 - addTo: anchor, 16 - color: red, 17 - }); 18 - 19 - panel.copy({ 20 - rotate: { y: TAU/4 }, 21 - color: red, 22 - }); 23 - panel.copy({ 24 - rotate: { y: TAU/2 }, 25 - color: navy, 26 - }); 27 - panel.copy({ 28 - rotate: { y: TAU * 3/4 }, 29 - color: navy, 30 - }); 31 - 32 - }
-169
demo/happy-town/make-building.js
··· 1 - /* globals red, blue, navy, gold, white */ 2 - 3 - // -------------------------- makeBuilding -------------------------- // 4 - 5 - function makeBuilding( options ) { 6 - 7 - var wallX = options.width/2; 8 - var wallY = options.height; 9 - var wallZ = options.depth/2; 10 - 11 - // collect walls 12 - var building = {}; 13 - 14 - // south/noth walls 15 - [ true, false ].forEach( function( isSouth ) { 16 - var wallTZ = isSouth ? -wallZ : wallZ; 17 - var wallGroup = new Zdog.Group({ 18 - addTo: options.addTo, 19 - translate: { z: -wallTZ }, 20 - }); 21 - 22 - var wallPath = [ 23 - { x: -wallX, y: -wallY } 24 - ]; 25 - 26 - if ( options.gable == 'ns' ) { 27 - wallPath.push({ x: 0, y: -wallY - wallX }); 28 - } 29 - 30 - wallPath = wallPath.concat([ 31 - { x: wallX, y: -wallY }, 32 - { x: wallX, y: 0 }, 33 - { x: -wallX, y: 0 }, 34 - ]); 35 - 36 - // wall 37 - new Zdog.Shape({ 38 - path: wallPath, 39 - addTo: wallGroup, 40 - color: isSouth ? red : gold, 41 - }); 42 - 43 - var windowColor = isSouth ? navy : red; 44 - var windowProperty = isSouth ? 'southWindows' : 'northWindows'; 45 - handleWindows( options, windowProperty, wallGroup, windowColor ); 46 - 47 - var wallProperty = isSouth ? 'southWall' : 'northWall'; 48 - building[ wallProperty ] = wallGroup; 49 - 50 - }); 51 - 52 - // east/west wall 53 - [ true, false ].forEach( function( isWest ) { 54 - var wallGroup = new Zdog.Group({ 55 - addTo: options.addTo, 56 - translate: { x: isWest ? -wallX : wallX }, 57 - rotate: { y: TAU/4 }, 58 - }); 59 - 60 - var wallPath = [ 61 - { x: -wallZ, y: -wallY } 62 - ]; 63 - 64 - if ( options.gable == 'ew' ) { 65 - wallPath.push({ x: 0, y: -wallY - wallZ }); 66 - } 67 - 68 - wallPath = wallPath.concat([ 69 - { x: wallZ, y: -wallY }, 70 - { x: wallZ, y: 0 }, 71 - { x: -wallZ, y: 0 }, 72 - ]); 73 - 74 - // wall 75 - new Zdog.Shape({ 76 - path: wallPath, 77 - addTo: wallGroup, 78 - color: isWest ? blue : white, 79 - }); 80 - 81 - var windowColor = isWest ? navy : blue; 82 - var windowProperty = isWest ? 'westWindows' : 'eastWindows'; 83 - handleWindows( options, windowProperty, wallGroup, windowColor ); 84 - 85 - var wallProperty = isWest ? 'westWall' : 'eastWall'; 86 - building[ wallProperty ] = wallGroup; 87 - }); 88 - 89 - 90 - var roofMakers = { 91 - ns: function() { 92 - var y0 = -wallY - wallX; 93 - var roofPanel = new Zdog.Shape({ 94 - path: [ 95 - { x: 0, y: y0, z: wallZ }, 96 - { x: 0, y: y0, z: -wallZ }, 97 - { x: wallX, y: -wallY, z: -wallZ }, 98 - { x: wallX, y: -wallY, z: wallZ }, 99 - ], 100 - addTo: options.addTo, 101 - color: gold, 102 - }); 103 - roofPanel.copy({ 104 - scale: { x: -1 }, 105 - color: navy, 106 - }); 107 - }, 108 - 109 - ew: function() { 110 - var y0 = -wallY - wallZ; 111 - var xA = options.isChurch ? -wallX + 8 : -wallX; 112 - var roofPanel = new Zdog.Shape({ 113 - path: [ 114 - { z: 0, y: y0, x: xA }, 115 - { z: 0, y: y0, x: wallX }, 116 - { z: -wallZ, y: -wallY, x: wallX }, 117 - { z: -wallZ, y: -wallY, x: xA }, 118 - ], 119 - addTo: options.addTo, 120 - color: red, 121 - }); 122 - roofPanel.copy({ 123 - path: [ 124 - { z: 0, y: y0, x: -wallX }, 125 - { z: 0, y: y0, x: wallX }, 126 - { z: -wallZ, y: -wallY, x: wallX }, 127 - { z: -wallZ, y: -wallY, x: -wallX }, 128 - ], 129 - scale: { z: -1 }, 130 - color: navy, 131 - }); 132 - }, 133 - }; 134 - 135 - var roofMaker = roofMakers[ options.gable ]; 136 - if ( roofMaker ) { 137 - roofMaker(); 138 - } 139 - 140 - return building; 141 - } 142 - 143 - function handleWindows( options, windowProperty, wallGroup, color ) { 144 - var windowOption = options[ windowProperty ]; 145 - if ( !windowOption ) { 146 - return; 147 - } 148 - 149 - var columns = windowOption[0]; 150 - var rows = windowOption[1]; 151 - // var windowPaths = []; 152 - for ( var row=0; row < rows; row++ ) { 153 - for ( var col=0; col < columns; col++ ) { 154 - var x = ( col - (columns-1)/2 ) * 6; 155 - var y = -options.height + (row + 0.75) * 8; 156 - var windowPath = [ 157 - { x: x + -1, y: y + -2 }, 158 - { x: x + 1, y: y + -2 }, 159 - { x: x + 1, y: y + 2 }, 160 - { x: x + -1, y: y + 2 }, 161 - ]; 162 - new Zdog.Shape({ 163 - path: windowPath, 164 - addTo: wallGroup, 165 - color: color, 166 - }); 167 - } 168 - } 169 - }
-104
demo/hemisphere-ball/hemisphere-ball.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 10, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // colors 24 - var yellow = '#ED0'; 25 - var gold = '#EA0'; 26 - var orange = '#E62'; 27 - var garnet = '#C25'; 28 - var eggplant = '#636'; 29 - 30 - // -- illustration shapes --- // 31 - 32 - var hemi = new Zdog.Hemisphere({ 33 - diameter: 13, 34 - addTo: illo, 35 - translate: { y: -16 }, 36 - rotate: { x: -TAU/4 }, 37 - color: garnet, 38 - backface: eggplant, 39 - stroke: false, 40 - }); 41 - hemi.copy({ 42 - translate: { y: 16 }, 43 - rotate: { x: TAU/4 }, 44 - color: garnet, 45 - backface: eggplant, 46 - }); 47 - 48 - var colorWheel = [ eggplant, garnet, orange, gold, yellow, ]; 49 - 50 - [ -1, 1 ].forEach( function( ySide ) { 51 - for ( var i=0; i < 5; i++ ) { 52 - var rotor1 = new Zdog.Anchor({ 53 - addTo: illo, 54 - rotate: { y: TAU/5 * i }, 55 - }); 56 - var rotor2 = new Zdog.Anchor({ 57 - addTo: rotor1, 58 - rotate: { x: TAU/6 }, 59 - }); 60 - 61 - hemi.copy({ 62 - addTo: rotor2, 63 - translate: { y: 16*ySide }, 64 - rotate: { x: TAU/4*ySide }, 65 - color: colorWheel[i], 66 - backface: colorWheel[ (i+7) % 5 ], 67 - }); 68 - } 69 - }); 70 - 71 - // -- animate --- // 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 - 79 - var t = 0; 80 - 81 - function animate() { 82 - rotate(); 83 - illo.updateRenderGraph(); 84 - requestAnimationFrame( animate ); 85 - } 86 - 87 - animate(); 88 - 89 - // -- update -- // 90 - 91 - function rotate() { 92 - if ( !isSpinning ) { 93 - return; 94 - } 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; 104 - }
-51
demo/hemisphere-ball/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>hemisphere ball</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #FDB; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/group.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/hemisphere.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="hemisphere-ball.js"></script> 49 - 50 - </body> 51 - </html>
-52
demo/inside-house/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>inside house</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/rect.js"></script> 46 - <script src="../../js/group.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="inside-house.js"></script> 50 - 51 - </body> 52 - </html>
-163
demo/inside-house/inside-house.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 8, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - // default to flat, filled shapes 15 - [ Zdog.Shape, Zdog.Rect, Zdog.Ellipse ].forEach( function( ItemClass ) { 16 - ItemClass.defaults.fill = true; 17 - ItemClass.defaults.stroke = false; 18 - ItemClass.defaults.backface = false; 19 - ItemClass.defaults.front = { z: 1 }; 20 - }); 21 - 22 - var illo = new Zdog.Illustration({ 23 - element: illoElem, 24 - zoom: zoom, 25 - dragRotate: true, 26 - onDragStart: function() { 27 - isSpinning = false; 28 - }, 29 - }); 30 - 31 - // -- house --- // 32 - 33 - var house = new Zdog.Anchor({ 34 - addTo: illo, 35 - scale: 10, 36 - }); 37 - 38 - var nsWall = new Zdog.Shape({ 39 - path: [ 40 - { x: -1, y: -1 }, 41 - { x: 0, y: -2 }, 42 - { x: 1, y: -1 }, 43 - { x: 1, y: 1 }, 44 - { x: -1, y: 1 }, 45 - ], 46 - addTo: house, 47 - translate: { z: -1 }, 48 - fill: true, 49 - color: 'hsla(45, 100%, 50%, 0.6)', 50 - }); 51 - 52 - nsWall.copy({ 53 - translate: { z: 1 }, 54 - rotate: { y: TAU/2 }, 55 - }); 56 - 57 - var ewWall = new Zdog.Rect({ 58 - width: 2, 59 - height: 2, 60 - addTo: house, 61 - translate: { x: -1 }, 62 - rotate: { y: -TAU/4 }, 63 - fill: true, 64 - color: 'hsla(210, 100%, 50%, 0.6)', 65 - }); 66 - 67 - ewWall.copy({ 68 - translate: { x: 1 }, 69 - rotate: { y: TAU/4 }, 70 - }); 71 - 72 - // floor 73 - new Zdog.Shape({ 74 - path: [ 75 - { x: -1, z: -1 }, 76 - { x: 1, z: -1 }, 77 - { x: 1, z: 1 }, 78 - { x: -1, z: 1 }, 79 - ], 80 - addTo: house, 81 - backface: true, 82 - translate: { y: 1 }, 83 - // front: { y: Zdog.Shape.defaults.front.z * -1 }, 84 - fill: true, 85 - color: 'hsla(120, 100%, 40%, 0.8)', 86 - }); 87 - 88 - // roof 89 - var roofLength = Math.sqrt(2); 90 - var roof = new Zdog.Shape({ 91 - path: [ 92 - { x: 0, y: -1 }, 93 - { x: roofLength, y: -1 }, 94 - { x: roofLength, y: 1 }, 95 - { x: 0, y: 1 }, 96 - ], 97 - addTo: house, 98 - translate: { y: -2 }, 99 - rotate: { x: -TAU/4, y: TAU/8 }, 100 - fill: true, 101 - color: 'hsla(0, 100%, 60%, 0.6)', 102 - }); 103 - 104 - roof.copy({ 105 - scale: { x: -1 }, 106 - rotate: { x: -TAU/4, y: -TAU/8 }, 107 - }); 108 - 109 - // -- chair --- // 110 - 111 - var chair = new Zdog.Group({ 112 - addTo: illo, 113 - scale: 2, 114 - translate: { y: 5 }, 115 - }); 116 - // chair back 117 - var chairLegs = new Zdog.Shape({ 118 - path: [ 119 - { x: -1, y: 2 }, 120 - { x: -1, y: -2 }, 121 - { x: 1, y: -2 }, 122 - { x: 1, y: 2 }, 123 - ], 124 - addTo: chair, 125 - translate: { z: 1 }, 126 - closed: false, 127 - stroke: 1, 128 - fill: false, 129 - color: '#333', 130 - backface: true, 131 - }); 132 - // chair front 133 - chairLegs.copy({ 134 - path: [ 135 - { x: -1, y: 2 }, 136 - { x: -1, y: 0 }, 137 - { x: 1, y: 0 }, 138 - { x: 1, y: 2 }, 139 - ], 140 - translate: { z: -1 }, 141 - }); 142 - // chair seat 143 - new Zdog.Rect({ 144 - width: 2, 145 - height: 2, 146 - addTo: chair, 147 - rotate: { x: TAU/4 }, 148 - stroke: 1, 149 - fill: true, 150 - color: '#333', 151 - backface: true, 152 - }); 153 - 154 - // -- animate --- // 155 - 156 - function animate() { 157 - illo.rotate.y += isSpinning ? +TAU/240 : 0; 158 - illo.updateRenderGraph(); 159 - requestAnimationFrame( animate ); 160 - } 161 - 162 - animate(); 163 -
-68
demo/little-forest/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>little forest</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #313; 19 - color: white; 20 - font-family: sans-serif; 21 - text-align: center; 22 - cursor: move; 23 - } 24 - 25 - .illo { 26 - display: block; 27 - margin: 0px auto 20px; 28 - } 29 - 30 - button { 31 - background: #525; 32 - color: white; 33 - font-size: 14px; 34 - font-family: inherit; 35 - border: none; 36 - border-radius: 3px; 37 - padding: 8px 10px; 38 - } 39 - 40 - button:hover { 41 - background: #936; 42 - cursor: pointer; 43 - } 44 - </style> 45 - 46 - </head> 47 - <body> 48 - 49 - <div class="container"> 50 - <canvas class="illo"></canvas> 51 - <p><button class="reset-button">Reset</button></p> 52 - </div> 53 - 54 - <script src="../../js/boilerplate.js"></script> 55 - <script src="../../js/canvas-renderer.js"></script> 56 - <script src="../../js/vector.js"></script> 57 - <script src="../../js/path-command.js"></script> 58 - <script src="../../js/anchor.js"></script> 59 - <script src="../../js/shape.js"></script> 60 - <script src="../../js/ellipse.js"></script> 61 - <script src="../../js/rect.js"></script> 62 - <script src="../../js/group.js"></script> 63 - <script src="../../js/dragger.js"></script> 64 - <script src="../../js/illustration.js"></script> 65 - <script src="little-forest.js"></script> 66 - 67 - </body> 68 - </html>
-760
demo/little-forest/little-forest.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 360; 5 - var h = 360; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight - 40 ); 7 - var zoom = Math.min( 3, Math.floor( minWindowSize / (w/2) ) / 2 ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // colors 24 - var midnight = '#313'; 25 - var eggplant = '#525'; 26 - var magenta = '#936'; 27 - var amber = '#D65'; 28 - var gold = '#FA6'; 29 - var white = '#FFF'; 30 - 31 - var layerSpace = 56; 32 - 33 - // -- illustration shapes --- // 34 - 35 - // background 36 - var background = new Zdog.Shape({ 37 - translate: { z: layerSpace*-2 }, 38 - visible: false, 39 - addTo: illo, 40 - }); 41 - 42 - var bgStripe = new Zdog.Rect({ 43 - width: 180, 44 - height: 44, 45 - addTo: background, 46 - translate: { y: -40, z: -24 }, 47 - color: magenta, 48 - stroke: 12, 49 - fill: true, 50 - }); 51 - // magenta circle 52 - var bgCircle = new Zdog.Ellipse({ 53 - diameter: 96, 54 - addTo: background, 55 - translate: { y: -16, z: -24 }, 56 - color: magenta, 57 - stroke: 24, 58 - fill: true, 59 - }); 60 - 61 - // amber stripe 62 - bgStripe.copy({ 63 - translate: { y: -8 }, 64 - color: amber, 65 - }); 66 - // amber circle 67 - bgCircle.copy({ 68 - diameter: 64, 69 - translate: { y: -16, }, 70 - color: amber, 71 - }); 72 - 73 - // gold bg stripe 74 - bgStripe.copy({ 75 - height: 60, 76 - addTo: background, 77 - translate: { y: 32, z: 24 }, 78 - color: gold, 79 - }); 80 - // gold circle 81 - bgCircle.copy({ 82 - width: 32, 83 - height: 32, 84 - translate: { y: -16, z: 24 }, 85 - color: gold, 86 - }); 87 - 88 - // sun 89 - new Zdog.Shape({ 90 - addTo: background, 91 - translate: { y: -16, z: 48 }, 92 - stroke: 24, 93 - color: white, 94 - }); 95 - 96 - // ----- midBackground ----- // 97 - 98 - var midBackground = new Zdog.Group({ 99 - addTo: illo, 100 - translate: { z: layerSpace*-1 }, 101 - }); 102 - 103 - var midBGDot = new Zdog.Shape({ 104 - addTo: midBackground, 105 - translate: { x: -36, y: 18 }, 106 - stroke: 24, 107 - color: amber, 108 - }); 109 - midBGDot.copy({ 110 - translate: { x: -24, y: 24 }, 111 - }); 112 - midBGDot.copy({ 113 - translate: { x: -6, y: 26 }, 114 - }); 115 - midBGDot.copy({ 116 - translate: { x: 12, y: 16 }, 117 - }); 118 - midBGDot.copy({ 119 - translate: { x: 28, y: 12 }, 120 - }); 121 - midBGDot.copy({ 122 - translate: { x: 48, y: 20 }, 123 - }); 124 - 125 - var midBGBigDot = midBGDot.copy({ 126 - stroke: 48, 127 - translate: { x: -52, y: 40 }, 128 - }); 129 - midBGBigDot.copy({ 130 - translate: { x: 20, y: 40 }, 131 - }); 132 - midBGBigDot.copy({ 133 - stroke: 40, 134 - translate: { x: 56, y: 40 }, 135 - }); 136 - midBGBigDot.copy({ 137 - stroke: 40, 138 - translate: { x: -16, y: 48 }, 139 - }); 140 - 141 - // ----- midground ----- // 142 - 143 - var midground = new Zdog.Anchor({ 144 - addTo: illo, 145 - }); 146 - 147 - var midgroundGroundA = new Zdog.Shape({ 148 - path: [ 149 - { x: -96, y: 10 }, 150 - { x: -86, y: 10 }, 151 - { arc: [ 152 - { x: -60, y: 42 }, 153 - { x: -26, y: 42 }, 154 - ]}, 155 - { x: -26, y: 74 }, 156 - { x: -96, y: 74 }, 157 - ], 158 - addTo: midground, 159 - color: magenta, 160 - stroke: 48, 161 - fill: true, 162 - }); 163 - midgroundGroundA.copy({ 164 - path: [ 165 - { x: -26, y: 42 }, 166 - { arc: [ 167 - { x: -8, y: 74 }, 168 - { x: 36, y: 74 }, 169 - ]}, 170 - { x: 96, y: 74 }, 171 - { x: -26, y: 74 }, 172 - ], 173 - }); 174 - 175 - function tree( groupOptions, options ) { 176 - options = Zdog.extend( options, groupOptions ); 177 - var treeW = options.width/2; 178 - var treeH = options.height/2; 179 - 180 - var pointA = { x: 0, y: -treeH }; 181 - var pointB = { x: treeW, y: treeH }; 182 - var pointC = { x: -treeW, y: treeH }; 183 - 184 - var treeOptions = Zdog.extend({ 185 - path: [ 186 - pointA, 187 - { bezier: [ 188 - pointA, 189 - { x: treeW, y: treeH*1/3 }, 190 - pointB, 191 - ]}, 192 - pointC, 193 - { bezier: [ 194 - { x: -treeW, y: treeH*1/3 }, 195 - pointA, 196 - pointA, 197 - ]}, 198 - ], 199 - fill: true, 200 - }, options ); 201 - 202 - var treePlane = new Zdog.Shape( treeOptions ); 203 - treePlane.copy({ 204 - rotate: { y: TAU/4 }, 205 - }); 206 - 207 - } 208 - 209 - var midgroundTree = { 210 - addTo: midground, 211 - color: magenta, 212 - stroke: 2, 213 - }; 214 - 215 - tree( midgroundTree, { 216 - width: 10, 217 - height: 24, 218 - translate: { x: -86, y: -14, z: -8 }, 219 - }); 220 - 221 - tree( midgroundTree, { 222 - width: 16, 223 - height: 36, 224 - translate: { x: -70, y: -12, z: 14 }, 225 - }); 226 - 227 - tree( midgroundTree, { 228 - width: 10, 229 - height: 24, 230 - translate: { x: -60, y: -4 }, 231 - }); 232 - 233 - tree( midgroundTree, { 234 - width: 10, 235 - height: 24, 236 - translate: { x: -26, y: 12, z: -8 }, 237 - }); 238 - 239 - tree( midgroundTree, { 240 - width: 10, 241 - height: 24, 242 - translate: { x: -18, y: 18, z: 2 }, 243 - }); 244 - 245 - var lonelyTranslate = { x: 32, y: 24 }; 246 - 247 - tree( midgroundTree, { 248 - width: 16, 249 - height: 36, 250 - translate: lonelyTranslate, 251 - }); 252 - // lonely tree stump 253 - new Zdog.Shape({ 254 - path: [ 255 - { y: 18 }, 256 - { y: 28 }, 257 - ], 258 - addTo: midground, 259 - translate: lonelyTranslate, 260 - color: magenta, 261 - stroke: 4, 262 - }); 263 - 264 - 265 - tree( midgroundTree, { 266 - width: 10, 267 - height: 24, 268 - translate: { x: 64, y: 40, z: 6 }, 269 - }); 270 - tree( midgroundTree, { 271 - width: 10, 272 - height: 24, 273 - translate: { x: 72, y: 44, z: -2 }, 274 - }); 275 - 276 - // ----- midForeground ----- // 277 - 278 - var midForeground = new Zdog.Anchor({ 279 - addTo: illo, 280 - translate: { z: layerSpace }, 281 - }); 282 - 283 - // midForeground ground part A 284 - var midForegroundGround = new Zdog.Shape({ 285 - path: [ 286 - { x: 96, y: 26 }, 287 - { x: 72, y: 26 }, 288 - { arc: [ 289 - { x: 56, y: 50 }, 290 - { x: 18, y: 50 }, 291 - ]}, 292 - { x: 18, y: 90 }, 293 - { x: 96, y: 90 }, 294 - ], 295 - addTo: midForeground, 296 - color: eggplant, 297 - stroke: 48, 298 - fill: true, 299 - }); 300 - midForegroundGround.copy({ 301 - path: [ 302 - { x: 18, y: 50 }, 303 - { arc: [ 304 - { x: -16, y: 90 }, 305 - { x: -48, y: 72 }, 306 - ]}, 307 - { x: -64, y: 56 }, 308 - { x: -96, y: 48 }, 309 - { x: -96, y: 90 }, 310 - { x: 18, y: 90 }, 311 - ], 312 - }); 313 - 314 - var midForeBall = new Zdog.Shape({ 315 - addTo: midForeground, 316 - translate: { x: -92, y: 18 }, 317 - stroke: 20, 318 - color: eggplant, 319 - }); 320 - midForeBall.copy({ 321 - translate: { x: -104, y: 28 }, 322 - }); 323 - midForeBall.copy({ 324 - translate: { x: -84, y: 28 }, 325 - stroke: 24, 326 - }); 327 - midForeBall.copy({ 328 - translate: { x: -74, y: 20 }, 329 - }); 330 - midForeBall.copy({ 331 - translate: { x: -60, y: 28 }, 332 - }); 333 - midForeBall.copy({ 334 - translate: { x: -50, y: 36 }, 335 - }); 336 - midForeBall.copy({ 337 - translate: { x: -44, y: 46 }, 338 - }); 339 - 340 - var midForeTree = { 341 - addTo: midForeground, 342 - color: eggplant, 343 - stroke: 2, 344 - }; 345 - 346 - tree( midForeTree, { 347 - width: 10, 348 - height: 24, 349 - translate: { x: -12, y: 42 }, 350 - }); 351 - tree( midForeTree, { 352 - width: 10, 353 - height: 24, 354 - translate: { x: 10, y: 22, z: 2 }, 355 - }); 356 - tree( midForeTree, { 357 - width: 16, 358 - height: 36, 359 - translate: { x: 22, y: 18, z: -6 }, 360 - }); 361 - 362 - tree( midForeTree, { 363 - width: 16, 364 - height: 36, 365 - translate: { x: 76, y: -6, z: 12 }, 366 - }); 367 - tree( midForeTree, { 368 - width: 10, 369 - height: 24, 370 - translate: { x: 86, y: -4, z: -10 }, 371 - }); 372 - 373 - // ----- foregroundA ----- // 374 - 375 - var foregroundA = new Zdog.Shape({ 376 - path: [ 377 - { x: -96, y: 52 }, 378 - { x: -84, y: 52 }, 379 - { arc: [ 380 - { x: -72, y: 72 }, 381 - { x: -44, y: 72 }, 382 - ]}, 383 - { arc: [ 384 - { x: -32, y: 90 }, 385 - { x: 0, y: 90 }, 386 - ]}, 387 - { x: -96, y: 90 }, 388 - ], 389 - addTo: illo, 390 - translate: { z: layerSpace*2 }, 391 - color: midnight, 392 - stroke: 48, 393 - fill: true, 394 - }); 395 - 396 - var foregroundTree = { 397 - color: midnight, 398 - stroke: 2, 399 - }; 400 - 401 - tree( foregroundTree, { 402 - addTo: foregroundA, 403 - width: 18, 404 - height: 44, 405 - translate: { x: -80, y: 18 }, 406 - }); 407 - 408 - var foreTree1Translate = { x: -44, y: 14 }; 409 - tree( foregroundTree, { 410 - addTo: foregroundA, 411 - width: 18, 412 - height: 44, 413 - translate: { x: -44, y: 14 }, 414 - }); 415 - // trunk 416 - new Zdog.Shape({ 417 - path: [ 418 - { y: 22 }, 419 - { y: 38 }, 420 - ], 421 - addTo: foregroundA, 422 - translate: foreTree1Translate, 423 - stroke: 6, 424 - color: midnight, 425 - }); 426 - 427 - tree( foregroundTree, { 428 - addTo: foregroundA, 429 - width: 16, 430 - height: 36, 431 - translate: { x: -2, y: 64 }, 432 - }); 433 - 434 - var grassBlade = new Zdog.Shape({ 435 - path: [ 436 - // semi-circle outside on left 437 - { x: 0, y: 1 }, 438 - { arc: [ 439 - { x: -1, y: 1 }, 440 - { x: -1, y: 0 }, 441 - ]}, 442 - { arc: [ 443 - { x: -1, y: -1 }, 444 - { x: 0, y: -1 }, 445 - ]}, 446 - // shallow semi-circle back 447 - { arc: [ 448 - { x: -0.5, y: -0.7 }, 449 - { x: -0.5, y: 0 }, 450 - ]}, 451 - { arc: [ 452 - { x: -0.5, y: 0.7 }, 453 - { x: 0, y: 1 }, 454 - ]}, 455 - ], 456 - addTo: foregroundA, 457 - translate: { x: -20, y: 56 }, 458 - scale: 8, 459 - rotate: { z: 0.6 }, 460 - color: midnight, 461 - stroke: 1, 462 - fill: true, 463 - closed: false, 464 - }); 465 - grassBlade.copy({ 466 - translate: { x: -33, y: 50 }, 467 - rotate: { z: TAU/2 + 0.2 }, 468 - }); 469 - 470 - grassBlade.copy({ 471 - translate: { x: -62, y: 40 }, 472 - rotate: { z: 0.8 }, 473 - scale: 7, 474 - }); 475 - 476 - grassBlade.copy({ 477 - translate: { x: -64, y: 35 }, 478 - rotate: { z: 0.4 }, 479 - scale: 7, 480 - }); 481 - 482 - // ----- foregroundB ----- // 483 - 484 - var foregroundB = new Zdog.Shape({ 485 - path: [ 486 - { x: 96, y: 52 }, 487 - { arc: [ 488 - { x: 80, y: 72 }, 489 - { x: 56, y: 72 }, 490 - ]}, 491 - { arc: [ 492 - { x: 40, y: 90 }, 493 - { x: 8, y: 90 }, 494 - ]}, 495 - { x: 0, y: 90 }, 496 - { x: 96, y: 90 }, 497 - ], 498 - addTo: illo, 499 - translate: { z: layerSpace*2 }, 500 - color: midnight, 501 - stroke: 48, 502 - fill: true, 503 - }); 504 - 505 - tree( foregroundTree, { 506 - addTo: foregroundB, 507 - width: 16, 508 - height: 36, 509 - translate: { x: 10, y: 54 }, 510 - }); 511 - 512 - // big tree 513 - var bigTreeTranslate = { x: 58, y: 2 }; 514 - tree( foregroundTree, { 515 - addTo: foregroundB, 516 - width: 20, 517 - height: 64, 518 - translate: bigTreeTranslate, 519 - }); 520 - // big tree trunk 521 - new Zdog.Shape({ 522 - path: [ 523 - { y: 32 }, 524 - { y: 48 }, 525 - ], 526 - addTo: foregroundB, 527 - translate: bigTreeTranslate, 528 - stroke: 6, 529 - color: midnight, 530 - }); 531 - 532 - tree( foregroundTree, { 533 - addTo: foregroundB, 534 - width: 16, 535 - height: 36, 536 - translate: { x: 86, y: 26 }, 537 - }); 538 - 539 - grassBlade.copy({ 540 - addTo: foregroundB, 541 - scale: 12, 542 - translate: { x: 46, y: 54 }, 543 - rotate: { z: 0 }, 544 - }); 545 - grassBlade.copy({ 546 - addTo: foregroundB, 547 - scale: 10, 548 - translate: { x: 28, y: 58 }, 549 - rotate: { z: TAU/2 - 0.4 }, 550 - }); 551 - 552 - // ----- particles ----- // 553 - 554 - var particle = new Zdog.Shape({ 555 - addTo: illo, 556 - translate: { x: -70, y: -50, z: layerSpace*-0.25 }, 557 - stroke: 4, 558 - color: gold, 559 - }); 560 - particle.copy({ 561 - translate: { x: 68, y: -28, z: layerSpace*0.5 }, 562 - }); 563 - particle.copy({ 564 - translate: { x: -70, y: 2, z: layerSpace*0.75 }, 565 - color: amber, 566 - }); 567 - particle.copy({ 568 - translate: { x: 74, y: 14, z: layerSpace*1.5 }, 569 - }); 570 - particle.copy({ 571 - translate: { x: -24, y: 34, z: layerSpace*1.75 }, 572 - }); 573 - particle.copy({ 574 - translate: { x: 34, y: 34, z: layerSpace*1.9 }, 575 - color: amber, 576 - }); 577 - particle.copy({ 578 - translate: { x: 22, y: 40, z: layerSpace*2.2 }, 579 - }); 580 - 581 - // ----- clouds ----- // 582 - 583 - var twoCloud = new Zdog.Shape({ 584 - path: [ 585 - { x: -20, y: 0 }, 586 - { bezier: [ 587 - { x: -13, y: 0 }, 588 - { x: -12, y: -4 }, 589 - { x: -10, y: -4 }, 590 - ]}, 591 - { bezier: [ 592 - { x: -8, y: -4 }, 593 - { x: -8, y: -2 }, 594 - { x: -4, y: -2 }, 595 - ]}, 596 - { bezier: [ 597 - { x: 0, y: -2 }, 598 - { x: 1, y: -6 }, 599 - { x: 4, y: -6 }, 600 - ]}, 601 - { bezier: [ 602 - { x: 7, y: -6 }, 603 - { x: 6, y: 0 }, 604 - { x: 20, y: 0 }, 605 - ]}, 606 - ], 607 - addTo: illo, 608 - translate: { x: -84, y: -38, z: layerSpace*-1 }, 609 - rotate: { y: -TAU*1/16 }, 610 - scale: { x: 1/Math.cos(TAU*1/16) }, 611 - stroke: 4, 612 - color: white, 613 - fill: true, 614 - }); 615 - 616 - twoCloud.copy({ 617 - translate: { x: -38, y: -22, z: layerSpace*-0.5 }, 618 - rotate: { y: -TAU*1/8 }, 619 - scale: { x: 1/Math.cos(TAU*1/8) * -1 }, 620 - }); 621 - 622 - // triple cloud 623 - new Zdog.Shape({ 624 - path: [ 625 - { x: -32, y: 0 }, 626 - { x: -28, y: 0 }, 627 - { bezier: [ 628 - { x: -22, y: 0 }, 629 - { x: -20, y: -6 }, 630 - { x: -16, y: -6 }, 631 - ]}, 632 - { bezier: [ 633 - { x: -12, y: -6 }, 634 - { x: -12, y: -2 }, 635 - { x: -8, y: -2 }, 636 - ]}, 637 - { bezier: [ 638 - { x: -4, y: -2 }, 639 - { x: -4, y: -6 }, 640 - { x: 0, y: -6 }, 641 - ]}, 642 - { bezier: [ 643 - { x: 4, y: -6 }, 644 - { x: 4, y: -2 }, 645 - { x: 8, y: -2 }, 646 - ]}, 647 - { bezier: [ 648 - { x: 12, y: -2 }, 649 - { x: 12, y: -6 }, 650 - { x: 16, y: -6 }, 651 - ]}, 652 - { bezier: [ 653 - { x: 20, y: -6 }, 654 - { x: 22, y: 0 }, 655 - { x: 28, y: 0 }, 656 - ]}, 657 - { x: 32, y: 0 }, 658 - ], 659 - addTo: illo, 660 - translate: { x: 72, y: -52, z: layerSpace*-1 }, 661 - rotate: { y: TAU * 1/16 }, 662 - scale: { x: 1/Math.cos(TAU * -1/16) }, 663 - stroke: 4, 664 - color: white, 665 - fill: true, 666 - }); 667 - 668 - // ----- stars ----- // 669 - 670 - var starA = new Zdog.Shape({ 671 - path: [ 672 - { x: 0, y: -4 }, 673 - { arc: [ 674 - { x: 0, y: 0 }, 675 - { x: 4, y: 0 }, 676 - ]}, 677 - { arc: [ 678 - { x: 0, y: 0 }, 679 - { x: 0, y: 4 }, 680 - ]}, 681 - { arc: [ 682 - { x: 0, y: 0 }, 683 - { x: -4, y: 0 }, 684 - ]}, 685 - { arc: [ 686 - { x: 0, y: 0 }, 687 - { x: 0, y: -4 }, 688 - ]}, 689 - ], 690 - addTo: illo, 691 - translate: { x: -50, y: -50, z: layerSpace*-1.5 }, 692 - color: gold, 693 - stroke: 2, 694 - fill: true, 695 - }); 696 - starA.copy({ 697 - rotate: { y: TAU/4 }, 698 - }); 699 - 700 - var starB = starA.copy({ 701 - translate: { x: 42, y: -20, z: -layerSpace*0.5 }, 702 - }); 703 - starB.copy({ 704 - rotate: { y: TAU/4 }, 705 - }); 706 - 707 - // ----- bird ----- // 708 - 709 - new Zdog.Shape({ 710 - path: [ 711 - { x: -6, y: -4 }, 712 - { x: -4, y: -4 }, 713 - { arc: [ 714 - { x: 0, y: -4 }, 715 - { x: 0, y: 0 }, 716 - ]}, 717 - { arc: [ 718 - { x: 0, y: -4 }, 719 - { x: 4, y: -4 }, 720 - ]}, 721 - { x: 6, y: -4 }, 722 - { move: { z: -2, y: 0 } }, 723 - { z: 3, y: 0 }, 724 - ], 725 - addTo: illo, 726 - translate: { x: 18, y: -30, z: layerSpace*-1 }, 727 - stroke: 3, 728 - color: midnight, 729 - closed: false, 730 - }); 731 - 732 - 733 - // -- animate --- // 734 - 735 - var t = 0; 736 - var tSpeed = 1/240; 737 - 738 - function animate() { 739 - // update 740 - if ( isSpinning ) { 741 - t += tSpeed; 742 - var theta = Zdog.easeInOut( t % 1 ) * TAU; 743 - var delta = TAU * -3/64; 744 - illo.rotate.y = Math.sin( theta ) * delta; 745 - illo.rotate.x = ( Math.cos( theta ) * -0.5 + 0.5 ) * delta; 746 - } 747 - 748 - illo.updateRenderGraph(); 749 - requestAnimationFrame( animate ); 750 - } 751 - 752 - animate(); 753 - 754 - 755 - // ----- inputs ----- // 756 - 757 - document.querySelector('.reset-button').onclick = function() { 758 - isSpinning = false; 759 - illo.rotate.set({}); 760 - };
-41
demo/madeline/bokeh-shape.js
··· 1 - var BokehShape = Zdog.Shape.subclass({ 2 - bokehSize: 5, 3 - bokehLimit: 64, 4 - }); 5 - 6 - BokehShape.prototype.updateBokeh = function() { 7 - // bokeh 0 -> 1 8 - this.bokeh = Math.abs( this.sortValue ) / this.bokehLimit; 9 - this.bokeh = Math.max( 0, Math.min( 1, this.bokeh ) ); 10 - return this.bokeh; 11 - }; 12 - 13 - BokehShape.prototype.getLineWidth = function() { 14 - return this.stroke + this.bokehSize * this.bokeh * this.bokeh; 15 - }; 16 - 17 - BokehShape.prototype.getBokehAlpha = function() { 18 - var alpha = 1 - this.bokeh; 19 - alpha *= alpha; 20 - return alpha * 0.8 + 0.2; 21 - }; 22 - 23 - BokehShape.prototype.renderCanvasDot = function( ctx ) { 24 - this.updateBokeh(); 25 - ctx.globalAlpha = this.getBokehAlpha(); // set opacity 26 - Zdog.Shape.prototype.renderCanvasDot.apply( this, arguments ); 27 - ctx.globalAlpha = 1; // reset 28 - }; 29 - 30 - BokehShape.prototype.renderPath = function( ctx, renderer ) { 31 - this.updateBokeh(); 32 - // set opacity 33 - if ( renderer.isCanvas ) { 34 - ctx.globalAlpha = this.getBokehAlpha(); 35 - } 36 - Zdog.Shape.prototype.renderPath.apply( this, arguments ); 37 - // reset opacity 38 - if ( renderer.isCanvas ) { 39 - ctx.globalAlpha = 1; 40 - } 41 - };
-55
demo/madeline/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>madeline</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #435; 19 - color: white; 20 - font-family: sans-serif; 21 - text-align: center; 22 - } 23 - 24 - .illo { 25 - display: block; 26 - margin: 0 auto; 27 - cursor: move; 28 - } 29 - </style> 30 - 31 - </head> 32 - <body> 33 - 34 - <div class="container"> 35 - <canvas class="illo"></canvas> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../fps-counter.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="bokeh-shape.js"></script> 50 - <script src="make-madeline.js"></script> 51 - <script src="make-bird.js"></script> 52 - <script src="madeline.js"></script> 53 - 54 - </body> 55 - </html>
-238
demo/madeline/madeline.js
··· 1 - /* globals makeMadeline, BokehShape, makeBird */ 2 - 3 - // -------------------------- demo -------------------------- // 4 - 5 - var illoElem = document.querySelector('.illo'); 6 - var w = 160; 7 - var h = 160; 8 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 9 - var zoom = Math.min( 5, Math.floor( minWindowSize / w ) ); 10 - illoElem.setAttribute( 'width', w * zoom ); 11 - illoElem.setAttribute( 'height', h * zoom ); 12 - 13 - var isSpinning = true; 14 - var TAU = Zdog.TAU; 15 - 16 - var illo = new Zdog.Illustration({ 17 - element: illoElem, 18 - zoom: zoom, 19 - rotate: { y: -TAU/4 }, 20 - dragRotate: true, 21 - onDragStart: function() { 22 - isSpinning = false; 23 - }, 24 - }); 25 - 26 - var madColor = { 27 - skin: '#FD9', 28 - hair: '#D53', 29 - parkaLight: '#67F', 30 - parkaDark: '#35D', 31 - tight: '#742', 32 - eye: '#333', 33 - }; 34 - var badColor = { 35 - skin: '#EBC', 36 - hair: '#D4B', 37 - parkaLight: '#85A', 38 - parkaDark: '#527', 39 - tight: '#412', 40 - eye: '#D02', 41 - }; 42 - 43 - var glow = 'hsla(60, 100%, 80%, 0.3)'; 44 - var featherGold = '#FE5'; 45 - 46 - // -- illustration shapes --- // 47 - 48 - makeMadeline( true, madColor, { 49 - addTo: illo, 50 - }); 51 - makeMadeline( false, badColor, { 52 - addTo: illo, 53 - rotate: { y: TAU/2 }, 54 - }); 55 - 56 - 57 - // ----- feather ----- // 58 - 59 - var feather = new Zdog.Group({ 60 - addTo: illo, 61 - rotate: { y: -TAU/4 }, 62 - }); 63 - 64 - ( function() { 65 - 66 - var featherPartCount = 8; 67 - var radius = 12; 68 - var angleX = (TAU/featherPartCount) / 2; 69 - var sector = (TAU * radius)/2 / featherPartCount; 70 - 71 - for ( var i=0; i < featherPartCount; i++ ) { 72 - var curve = Math.cos( (i/featherPartCount) * TAU*3/4 + TAU*1/4 ); 73 - var x = 4 - curve*2; 74 - var y0 = sector/2; 75 - // var y2 = -sector/2; 76 - var isLast = i == featherPartCount - 1; 77 - var y3 = isLast ? sector * -1 : -y0; 78 - var z1 = -radius + 2 + curve*-1.5; 79 - var z2 = isLast ? -radius : -radius; 80 - var barb = new Zdog.Shape({ 81 - path: [ 82 - { x: 0, y: y0, z: -radius }, 83 - { x: x, y: -sector/2, z: z1 }, 84 - { x: x, y: -sector*3/4, z: z1 }, 85 - { x: 0, y: y3, z: z2 }, 86 - ], 87 - addTo: feather, 88 - rotate: { x: angleX * -i + TAU/8 }, 89 - stroke: 1, 90 - color: featherGold, 91 - fill: true, 92 - }); 93 - barb.copy({ 94 - scale: { x: -1 }, 95 - }); 96 - } 97 - 98 - // rachis 99 - var rachis = new Zdog.Ellipse({ 100 - addTo: feather, 101 - diameter: radius*2, 102 - quarters: 2, 103 - rotate: { y: -TAU/4 }, 104 - stroke: 2, 105 - color: featherGold, 106 - }); 107 - rachis.copy({ 108 - stroke: 8, 109 - color: glow, 110 - rotate: { y: -TAU/4, x: -0.5 } 111 - }); 112 - })(); 113 - 114 - // ----- rods ----- // 115 - 116 - ( function() { 117 - 118 - var rodCount = 14; 119 - for ( var i=0; i < rodCount; i++ ) { 120 - var zRotor = new Zdog.Anchor({ 121 - addTo: illo, 122 - rotate: { z: TAU/rodCount * i }, 123 - }); 124 - 125 - var y0 = 32; 126 - var y1 = y0 + 2 + Math.random()*24; 127 - new BokehShape({ 128 - path: [ 129 - { y: y0 }, 130 - { y: y1 }, 131 - ], 132 - addTo: zRotor, 133 - rotate: { x: ( Math.random() * 2 - 1 ) * TAU/8 }, 134 - color: madColor.skin, 135 - stroke: 1, 136 - bokehSize: 6, 137 - bokehLimit: 70, 138 - }); 139 - } 140 - 141 - })(); 142 - 143 - // dots 144 - 145 - ( function() { 146 - var dotCount = 64; 147 - 148 - for ( var i=0; i < dotCount; i++ ) { 149 - var yRotor = new Zdog.Anchor({ 150 - addTo: illo, 151 - rotate: { y: TAU/dotCount * i }, 152 - }); 153 - 154 - new BokehShape({ 155 - path: [ 156 - { z: 40*(1 - Math.random()*Math.random()) + 32 }, 157 - ], 158 - addTo: yRotor, 159 - rotate: { x: ( Math.random() * 2 - 1 ) * TAU*3/16 }, 160 - color: badColor.skin, 161 - stroke: 1 + Math.random(), 162 - bokehSize: 6, 163 - bokehLimit: 74, 164 - }); 165 - } 166 - 167 - })(); 168 - 169 - // ----- birds ----- // 170 - 171 - var birdRotor = new Zdog.Anchor({ 172 - addTo: illo, 173 - rotate: { y: TAU*-1/8 }, 174 - }); 175 - 176 - makeBird({ 177 - addTo: birdRotor, 178 - color: madColor.parkaLight, 179 - spin: TAU/2, 180 - }); 181 - 182 - makeBird({ 183 - addTo: birdRotor, 184 - color: featherGold, 185 - spin: -TAU * 3/8, 186 - }); 187 - 188 - makeBird({ 189 - addTo: birdRotor, 190 - color: 'white', 191 - spin: -TAU/4, 192 - }); 193 - 194 - makeBird({ 195 - addTo: birdRotor, 196 - color: madColor.hair, 197 - spin: -TAU/8, 198 - }); 199 - 200 - makeBird({ 201 - addTo: birdRotor, 202 - color: madColor.parkaDark, 203 - spin: TAU/8, 204 - }); 205 - 206 - // -- animate --- // 207 - 208 - var isSpinning = true; 209 - var rotateSpeed = -TAU/60; 210 - var xClock = 0; 211 - var then = new Date() - 1/60; 212 - 213 - function animate() { 214 - update(); 215 - illo.renderGraph(); 216 - requestAnimationFrame( animate ); 217 - } 218 - 219 - animate(); 220 - 221 - // -- update -- // 222 - 223 - function update() { 224 - var now = new Date(); 225 - var delta = now - then; 226 - // auto rotate 227 - if ( isSpinning ) { 228 - var theta = rotateSpeed/60 * delta * -1; 229 - illo.rotate.y += theta; 230 - xClock += theta/4; 231 - illo.rotate.x = Math.sin( xClock ) * TAU/12; 232 - } 233 - 234 - illo.updateGraph(); 235 - 236 - then = now; 237 - } 238 -
-96
demo/madeline/make-bird.js
··· 1 - function makeBird( options ) { 2 - 3 - var spin = options.spin || 0; 4 - 5 - var arrow = new Zdog.Anchor({ 6 - addTo: options.addTo, 7 - scale: 2/3, 8 - rotate: { z: spin }, 9 - }); 10 - 11 - var bird = new Zdog.Group({ 12 - addTo: arrow, 13 - translate: { x: 87 }, 14 - rotate: { x: -spin }, 15 - }); 16 - 17 - // bird body 18 - new Zdog.Shape({ 19 - path: [ 20 - { x: -3, y: 0 }, 21 - { arc: [ 22 - { x: -2, y: 1.5 }, 23 - { x: 0, y: 1.5 }, 24 - ]}, 25 - { arc: [ 26 - { x: 2, y: 1.5 }, 27 - { x: 2, y: 0 }, 28 - ]}, 29 - ], 30 - addTo: bird, 31 - translate: { x: 0.5 }, 32 - stroke: 3, 33 - color: options.color, 34 - fill: true, 35 - }); 36 - 37 - // bird head 38 - new Zdog.Shape({ 39 - translate: { x: 4, y: -1 }, 40 - addTo: bird, 41 - stroke: 4, 42 - color: options.color, 43 - }); 44 - 45 - // beak 46 - new Zdog.Shape({ 47 - path: [ 48 - { x: 0, y: -1 }, 49 - { x: 3, y: 0 }, 50 - { x: 0, y: 1 }, 51 - ], 52 - addTo: bird, 53 - translate: { x: 5, y: -1 }, 54 - stroke: 1, 55 - color: options.color, 56 - fill: true, 57 - }); 58 - 59 - // tail feather 60 - new Zdog.Shape({ 61 - path: [ 62 - { x: -3, z: -2 }, 63 - { x: 0, z: 0 }, 64 - { x: -3, z: 2 }, 65 - ], 66 - addTo: bird, 67 - translate: { x: -4, y: 0 }, 68 - stroke: 2, 69 - color: options.color, 70 - fill: true, 71 - }); 72 - 73 - var wing = new Zdog.Shape({ 74 - path: [ 75 - { x: 3, y: 0 }, 76 - { x: -1, y: -9 }, 77 - { arc: [ 78 - { x: -5, y: -4 }, 79 - { x: -3, y: 0 }, 80 - ]}, 81 - ], 82 - addTo: bird, 83 - translate: { z: -1.5}, 84 - rotate: { x: TAU/8 }, 85 - stroke: 1, 86 - color: options.color, 87 - fill: true, 88 - }); 89 - 90 - wing.copy({ 91 - translate: { z: 1.5}, 92 - scale: { z: -1 }, 93 - rotate: { x: -TAU/8 }, 94 - }); 95 - 96 - }
-311
demo/madeline/make-madeline.js
··· 1 - /* jshint unused: false */ 2 - 3 - var TAU = Zdog.TAU; 4 - 5 - function makeMadeline( isGood, colors, options ) { 6 - 7 - var rotor = new Zdog.Anchor( options ); 8 - 9 - var body = new Zdog.Group({ 10 - addTo: rotor, 11 - rotate: { x: -TAU/8 }, 12 - translate: { z: -48 }, 13 - updateSort: true, 14 - }); 15 - 16 - var head = new Zdog.Anchor({ 17 - addTo: body, 18 - translate: { y: -11, z: -2 }, 19 - rotate: { x: TAU/8 }, 20 - }); 21 - 22 - // face 23 - var face = new Zdog.Ellipse({ 24 - diameter: 6, 25 - addTo: head, 26 - translate: { z: 4 }, 27 - stroke: 8, 28 - color: colors.skin, 29 - }); 30 - 31 - var eyeGroup = new Zdog.Group({ 32 - addTo: face, 33 - translate: { z: face.stroke/2 - 0.5 }, 34 - }); 35 - 36 - 37 - // eyes 38 - [ -1, 1 ].forEach( function( xSide ) { 39 - // cheek blush 40 - if ( isGood ) { 41 - new Zdog.Ellipse({ 42 - width: 2, 43 - height: 1.3, 44 - addTo: eyeGroup, 45 - translate: { x: 4.5*xSide, y: 3, z: -1 }, 46 - rotate: { y: -TAU/16*xSide }, 47 - stroke: 1, 48 - color: '#FA8', 49 - fill: true, 50 - }); 51 - } 52 - 53 - var eyeX = 3.5*xSide; 54 - 55 - // eye 56 - new Zdog.Ellipse({ 57 - width: 0.75, 58 - height: 1.5, 59 - addTo: eyeGroup, 60 - color: colors.eye, 61 - translate: { x: eyeX }, 62 - stroke: 2, 63 - fill: true, 64 - }); 65 - 66 - // eye brow 67 - new Zdog.Ellipse({ 68 - addTo: eyeGroup, 69 - height: 3, 70 - width: 1.2, 71 - quarters: 2, 72 - translate: { x: eyeX, y: -3 }, 73 - rotate: { z: -TAU/4 + 0.15*xSide * (isGood ? 1 : -1) }, 74 - color: colors.hair, 75 - stroke: 1, 76 - fill: false, 77 - closed: true, 78 - }); 79 - 80 - }); 81 - 82 - 83 - // hair ball 84 - new Zdog.Shape({ 85 - path: [ 86 - { x: -1 }, 87 - { x: 1 }, 88 - { z: -4 }, 89 - ], 90 - addTo: head, 91 - translate: { y: -4, z: -1 }, 92 - stroke: 18, 93 - color: colors.hair, 94 - }); 95 - 96 - var bang = new Zdog.Shape({ 97 - path: [ 98 - {}, 99 - { arc: [ 100 - { z: 4, y: 4 }, 101 - { z: 0, y: 8 }, 102 - ]}, 103 - ], 104 - addTo: head, 105 - translate: { x: 2, y: -7.5, z: 6 }, 106 - rotate: { x: 0.5, z: -0.5 }, 107 - stroke: 4, 108 - color: colors.hair, 109 - closed: false, 110 - }); 111 - bang.copy({ 112 - translate: { x: 5, y: -6, z: 5 }, 113 - rotate: { x: -0.3, z: -0.5 }, 114 - }); 115 - bang.copy({ 116 - translate: { x: 5, y: -6, z: 3 }, 117 - rotate: { y: -0.7, z: -1 }, 118 - }); 119 - 120 - // left side 121 - bang.copy({ 122 - translate: { x: -2, y: -7.5, z: 6 }, 123 - rotate: { x: 0, z: TAU/16*6 }, 124 - }); 125 - bang.copy({ 126 - translate: { x: -5, y: -6, z: 5 }, 127 - rotate: { x: 0, z: TAU/4 }, 128 - }); 129 - bang.copy({ 130 - translate: { x: -5, y: -6, z: 3 }, 131 - rotate: { y: 0.7, z: 1 }, 132 - }); 133 - 134 - // hair cover 135 - new Zdog.Shape({ 136 - path: [ 137 - { x: -3 }, 138 - { x: 3 }, 139 - ], 140 - addTo: head, 141 - stroke: 7, 142 - translate: { y: -8, z: 5 }, 143 - color: colors.hair, 144 - }); 145 - 146 - // trail locks 147 - 148 - var trailLock = new Zdog.Shape({ 149 - path: [ 150 - { y: -4, z: 0 }, 151 - { bezier: [ 152 - { y: -10, z: -14 }, 153 - { y: 0, z: -16 }, 154 - { y: 0, z: -26 } 155 - ]}, 156 - ], 157 - addTo: head, 158 - translate: { z: -4, y: 0 }, 159 - stroke: 10, 160 - color: colors.hair, 161 - closed: false, 162 - }); 163 - 164 - trailLock.copy({ 165 - translate: { x: -3, z: -4 }, 166 - rotate: { z: -TAU/8 }, 167 - stroke: 8, 168 - }); 169 - trailLock.copy({ 170 - translate: { x: 3, z: -4 }, 171 - rotate: { z: TAU/8 }, 172 - stroke: 8, 173 - }); 174 - trailLock.copy({ 175 - translate: { y: 2 }, 176 - // rotate: { z: TAU/2 }, 177 - scale: { y: 0.5 }, 178 - stroke: 8, 179 - }); 180 - 181 - // ----- torso ----- // 182 - 183 - // 2nd rib 184 - var torsoRib = new Zdog.Ellipse({ 185 - width: 12, 186 - height: 10, 187 - addTo: body, 188 - rotate: { x: -TAU/4 }, 189 - translate: { y: -1 }, 190 - stroke: 6, 191 - color: colors.parkaLight, 192 - fill: true, 193 - }); 194 - // neck rib 195 - torsoRib.copy({ 196 - width: 6, 197 - height: 6, 198 - translate: { y: -5 }, 199 - }); 200 - // 3rd rib 201 - torsoRib.copy({ 202 - translate: { y: 3 }, 203 - }); 204 - // 4th rib 205 - torsoRib.copy({ 206 - translate: { y: 7 }, 207 - color: colors.parkaDark, 208 - }); 209 - // waist 210 - new Zdog.Ellipse({ 211 - width: 10, 212 - height: 8, 213 - addTo: body, 214 - rotate: { x: -TAU/4 }, 215 - translate: { y: 11 }, 216 - stroke: 4, 217 - color: colors.tight, 218 - fill: true, 219 - }); 220 - 221 - // arms 222 - [ -1, 1 ].forEach( function( xSide ) { 223 - var isLeft = xSide == 1; 224 - // shoulder ball 225 - new Zdog.Shape({ 226 - addTo: body, 227 - stroke: 6, 228 - translate: { x: 6*xSide, y: -5, z: -1 }, 229 - color: colors.parkaLight, 230 - }); 231 - 232 - var shoulderJoint = new Zdog.Anchor({ 233 - addTo: body, 234 - translate: { x: 9*xSide, y: -3, z: -2 }, 235 - rotate: isLeft ? { x: TAU/8*3, z: -TAU/32 } : { z: TAU/16*2, x: -TAU/16*2 }, 236 - }); 237 - 238 - // top shoulder rib 239 - var armRib = new Zdog.Ellipse({ 240 - diameter: 2, 241 - rotate: { x: -TAU/4 }, 242 - addTo: shoulderJoint, 243 - translate: { x: 0*xSide }, 244 - stroke: 6, 245 - color: colors.parkaLight, 246 - fill: true, 247 - }); 248 - armRib.copy({ 249 - translate: { y: 4 }, 250 - }); 251 - 252 - var elbowJoint = new Zdog.Anchor({ 253 - addTo: shoulderJoint, 254 - translate: { y: 8 }, 255 - rotate: isLeft ? {} : { z: TAU/8 }, 256 - }); 257 - 258 - armRib.copy({ 259 - addTo: elbowJoint, 260 - translate: { x: 0, y: 0 }, 261 - }); 262 - armRib.copy({ 263 - addTo: elbowJoint, 264 - translate: { y: 4 }, 265 - color: colors.parkaDark, 266 - }); 267 - 268 - // hand 269 - new Zdog.Shape({ 270 - addTo: elbowJoint, 271 - translate: { y: 9, z: -1 }, 272 - stroke: 8, 273 - color: colors.skin, 274 - }); 275 - 276 - // ----- legs ----- // 277 - var knee = { y: 7 }; 278 - var thigh = new Zdog.Shape({ 279 - path: [ { y: 0 }, knee ], 280 - addTo: body, 281 - translate: { x: 4*xSide, y: 13 }, 282 - rotate: isLeft ? {} : { x: TAU/16*3, z: TAU/16 }, 283 - stroke: 8, 284 - color: colors.tight, 285 - }); 286 - 287 - var shin = new Zdog.Shape({ 288 - path: [ { y: 0 }, { y: 8 } ], 289 - addTo: thigh, 290 - stroke: 6, 291 - translate: knee, 292 - rotate: isLeft ? {} : { x: -TAU/16*5 }, 293 - color: colors.tight, 294 - }); 295 - 296 - }); 297 - 298 - // butt 299 - new Zdog.Shape({ 300 - path: [ 301 - { x: -3 }, 302 - { x: 3 }, 303 - ], 304 - visible: false, 305 - addTo: body, 306 - translate: { y: 11, z: -2 }, 307 - stroke: 8, 308 - color: colors.tight, 309 - }); 310 - 311 - }
-51
demo/mario/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>mario</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #FD0; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="mario.js"></script> 49 - 50 - </body> 51 - </html>
-463
demo/mario/mario.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 72; 5 - var h = 72; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 6, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - dragRotate: true, 18 - onDragStart: function() { 19 - isSpinning = false; 20 - }, 21 - }); 22 - 23 - // colors 24 - var colors = { 25 - eye: '#333', 26 - white: '#FFF', 27 - hair: '#631', 28 - overalls: '#24D', 29 - cloth: '#E11', 30 - skin: '#FC9', 31 - leather: '#A63', 32 - }; 33 - 34 - // -- illustration shapes --- // 35 - 36 - // head 37 - var head = new Zdog.Shape({ 38 - addTo: illo, 39 - translate: { y: -12, z: 1 }, 40 - color: colors.skin, 41 - stroke: 23, 42 - }); 43 - 44 - // nose 45 - new Zdog.Shape({ 46 - addTo: head, 47 - translate: { y: 5, z: 13 }, 48 - color: colors.skin, 49 - stroke: 7, 50 - }); 51 - 52 - 53 - 54 - // chin 55 - var chin = new Zdog.Shape({ 56 - addTo: head, 57 - path: [ 58 - { x: -5, y: 6, z: 4 }, 59 - { x: 0, y: 8.5, z: 6 } 60 - ], 61 - color: colors.skin, 62 - stroke: 10, 63 - }); 64 - chin.copy({ 65 - scale: { x: -1 }, 66 - }); 67 - 68 - // mouth 69 - new Zdog.Shape({ 70 - path: [ 71 - { x: -3, y: -3 }, 72 - { x: -1, y: -1 }, 73 - { x: 1, y: -1 }, 74 - { x: 3, y: -3 }, 75 - ], 76 - translate: { y: 12, z: 9 }, 77 - color: colors.cloth, 78 - fill: true, 79 - stroke: 2, 80 - addTo: head, 81 - }); 82 - 83 - 84 - var hat = new Zdog.Anchor({ 85 - addTo: head, 86 - translate: { y: -8 }, 87 - }); 88 - 89 - // hat front 90 - var hatFrontA = new Zdog.Vector({ x: -8, y: 0, z: 5 }); 91 - var hatFrontB = new Zdog.Vector({ x: -4, y: -3, z: 7 }); 92 - var hatFrontC = hatFrontB.copy().multiply({ x: -1 }); 93 - var hatFrontD = hatFrontA.copy().multiply({ x: -1 }); 94 - 95 - // hat front 96 - new Zdog.Shape({ 97 - path: [ 98 - hatFrontA, 99 - hatFrontB, 100 - hatFrontC, 101 - hatFrontD, 102 - ], 103 - color: colors.cloth, 104 - closed: false, 105 - fill: false, 106 - stroke: 11, 107 - addTo: hat, 108 - }); 109 - 110 - var hatTopFront = new Zdog.Vector({ x: 10, y: 1, z: 5 }); 111 - var hatTopBackA = new Zdog.Vector({ x: 7, y: 3, z: -10 }); 112 - var hatTopBackB = hatTopBackA.copy().multiply({ x: -1 }); 113 - 114 - // hat top 115 - new Zdog.Shape({ 116 - path: [ 117 - hatTopFront.copy().multiply({ x: -1 }), 118 - hatTopFront, 119 - hatTopBackA, 120 - hatTopBackB, 121 - ], 122 - color: colors.cloth, 123 - fill: true, 124 - stroke: 9, 125 - addTo: hat, 126 - }); 127 - // hat top back 128 - new Zdog.Shape({ 129 - path: [ 130 - hatTopBackA, 131 - hatTopBackB, 132 - ], 133 - color: colors.cloth, 134 - stroke: 9, 135 - addTo: hat, 136 - }); 137 - 138 - // hat top side 139 - var hatTopSide = new Zdog.Shape({ 140 - path: [ 141 - hatTopFront, 142 - hatTopBackA, 143 - ], 144 - color: colors.cloth, 145 - stroke: 9, 146 - addTo: hat, 147 - }); 148 - hatTopSide.copy({ 149 - scale: { x: -1 }, 150 - }); 151 - 152 - 153 - // hat top cover 154 - new Zdog.Shape({ 155 - path: [ 156 - { x: -3, y: 0, z: -8 }, 157 - { x: 3, y: 0, z: -8 }, 158 - { x: 3, y: -3, z: 4 }, 159 - { x: -3, y: -3, z: 4 }, 160 - ], 161 - color: colors.cloth, 162 - stroke: 6, 163 - addTo: hat, 164 - }); 165 - 166 - // hat brim 167 - // brim has left & right side 168 - var hatBrim = new Zdog.Shape({ 169 - path: [ 170 - { x: 10, y: 4, z: -0 }, 171 - { x: 8, y: 4, z: 5 }, 172 - { x: 0, y: 2, z: 9 }, 173 - { x: 0, y: 1, z: 2 }, 174 - ], 175 - translate: { z: 7 }, 176 - color: colors.cloth, 177 - fill: true, 178 - stroke: 4, 179 - addTo: hat, 180 - }); 181 - hatBrim.copy({ 182 - scale: { x: -1 }, 183 - }); 184 - 185 - // eyes pupil 186 - var eye = new Zdog.Shape({ 187 - path: [ 188 - { y: 2 }, 189 - { y: 4 }, 190 - ], 191 - translate: { x: 5, z: 9 }, 192 - color: colors.eye, 193 - stroke: 3, 194 - addTo: head, 195 - }); 196 - eye.copy({ 197 - translate: { x: -5, z: 9 }, 198 - }); 199 - 200 - var brow = new Zdog.Shape({ 201 - path: [ 202 - { x: 3, y: 0, z: -0 }, 203 - { x: 1.5, y: -0.5, z: 1 }, 204 - { x: 0, y: 0, z: 1 }, 205 - ], 206 - translate: { x: 4, y: -1.5, z: 9 }, 207 - color: colors.hair, 208 - closed: false, 209 - stroke: 2.5, 210 - addTo: head, 211 - }); 212 - brow.copy({ 213 - scale: { x: -1 }, 214 - translate: { x: -4, y: -1.5, z: 9 }, 215 - }); 216 - 217 - var mustache = new Zdog.Group({ 218 - addTo: head, 219 - translate: { y: 6.5, z: 10 }, 220 - }); 221 - // mustache line 222 - new Zdog.Shape({ 223 - path: [ 224 - { x: 2, y: 1, z: 1.5 }, 225 - { x: 6.5, y: 0, z: -0 }, 226 - ], 227 - color: colors.hair, 228 - stroke: 3, 229 - addTo: mustache, 230 - }); 231 - // mustache sections 232 - var mustacheSection = new Zdog.Shape({ 233 - translate: { x: 1.75, y: 1.5, z: 1 }, 234 - color: colors.hair, 235 - stroke: 4, 236 - addTo: mustache, 237 - }); 238 - mustacheSection.copy({ 239 - translate: { x: 4.5, y: 1, z: 0.75 } 240 - }); 241 - 242 - mustache.copyGraph({ 243 - scale: { x: -1 }, 244 - }); 245 - 246 - var sideburns = new Zdog.Shape({ 247 - path: [ 248 - { y: 0, z: 0 }, 249 - { y: -4, z: 1.5 }, 250 - { y: -4, z: 1 }, 251 - { y: -1, z: 2 }, 252 - ], 253 - translate: { x: 10, y: 3, z: 2 }, 254 - color: colors.hair, 255 - closed: false, 256 - fill: true, 257 - stroke: 3, 258 - addTo: head, 259 - }); 260 - sideburns.copy({ 261 - translate: sideburns.translate.copy().multiply({ x: -1 }), 262 - }); 263 - 264 - var ear = new Zdog.Shape({ 265 - path: [ 266 - { x: 0, y: 0, z: -0 }, 267 - { x: 0, y: -4, z: -0 }, 268 - { x: 1, y: -4, z: -2 }, 269 - { x: 0, y: 0, z: -1 }, 270 - ], 271 - translate: { x: 10, y: 4, z: -2 }, 272 - color: colors.skin, 273 - fill: true, 274 - stroke: 4, 275 - addTo: head, 276 - }); 277 - ear.copy({ 278 - scale: { x: -1 }, 279 - translate: ear.translate.copy().multiply({ x: -1 }), 280 - }); 281 - 282 - var sideHair = new Zdog.Anchor({ 283 - addTo: head, 284 - }); 285 - 286 - // hair side panel 287 - new Zdog.Shape({ 288 - path: [ 289 - { x: 4, y: -7, z: -1 }, 290 - { x: 3, y: 0, z: -0 }, 291 - { x: 0, y: 0, z: -5 }, 292 - { x: 2, y: -6.5, z: -6 }, 293 - ], 294 - translate: { x: 5, y: 7, z: -5 }, 295 - color: colors.hair, 296 - fill: true, 297 - stroke: 3, 298 - addTo: sideHair, 299 - }); 300 - // hair balls 301 - var hairBall = new Zdog.Shape({ 302 - translate: { x: 6, y: 8, z: -8 }, 303 - color: colors.hair, 304 - stroke: 6, 305 - addTo: sideHair, 306 - }); 307 - hairBall.copy({ 308 - translate: { x: 2, y: 8, z: -10 }, 309 - }); 310 - 311 - sideHair.copyGraph({ 312 - scale: { x: -1 }, 313 - }); 314 - 315 - // hair back panel 316 - new Zdog.Shape({ 317 - path: [ 318 - { x: 5, y: 0, z: -0 }, 319 - { x: 6, y: -6.5, z: -1 }, 320 - { x: -6, y: -6.5, z: -1 }, 321 - { x: -5, y: 0, z: -0 }, 322 - ], 323 - translate: { y: 7, z: -10 }, 324 - color: colors.hair, 325 - fill: true, 326 - stroke: 3, 327 - addTo: head, 328 - }); 329 - 330 - 331 - var body = new Zdog.Shape({ 332 - translate: { x: 0, y: 10, z: 1 }, 333 - color: colors.overalls, 334 - stroke: 20, 335 - addTo: illo, 336 - }); 337 - 338 - // right arm 339 - var rightShoulder = { x: -8, y: -8, z: -3 }; 340 - var rightWrist = new Zdog.Vector({ x: -14, y: -17, z: -0 }); 341 - new Zdog.Shape({ 342 - path: [ 343 - rightShoulder, 344 - rightWrist, 345 - ], 346 - color: colors.cloth, 347 - stroke: 8, 348 - addTo: body, 349 - }); 350 - 351 - // right hand 352 - new Zdog.Shape({ 353 - path: [ 354 - { x: -17, y: -23, z: 1 }, 355 - ], 356 - color: colors.white, 357 - stroke: 12, 358 - addTo: body, 359 - }); 360 - 361 - // left arm 362 - var leftShoulder = { x: 6, y: -7, z: -4 }; 363 - var leftElbow = { x: 8, y: -4, z: -8 }; 364 - new Zdog.Shape({ 365 - path: [ 366 - leftShoulder, 367 - leftElbow, 368 - ], 369 - color: colors.cloth, 370 - stroke: 8, 371 - addTo: body, 372 - }); 373 - new Zdog.Shape({ 374 - path: [ 375 - leftElbow, 376 - { x: 12, y: -2, z: -9 }, 377 - ], 378 - color: colors.cloth, 379 - stroke: 8, 380 - addTo: body, 381 - }); 382 - // left hand 383 - new Zdog.Shape({ 384 - path: [ 385 - { x: 17, y: 1, z: -8 }, 386 - ], 387 - color: colors.white, 388 - stroke: 12, 389 - addTo: body, 390 - }); 391 - 392 - new Zdog.Shape({ 393 - path: [ 394 - leftShoulder, 395 - rightShoulder, 396 - ], 397 - color: colors.cloth, 398 - stroke: 8, 399 - addTo: body, 400 - }); 401 - 402 - // right leg 403 - var rightLeg = new Zdog.Shape({ 404 - path: [ 405 - { y: 4, z: 2 }, 406 - { y: 10, z: 1 }, 407 - { y: 12, z: -0 } 408 - ], 409 - translate: { x: -5 }, 410 - closed: false, 411 - color: colors.overalls, 412 - stroke: 10, 413 - addTo: body, 414 - }); 415 - 416 - var shoe = new Zdog.Rect({ 417 - addTo: rightLeg, 418 - width: 4, 419 - height: 7, 420 - translate: { y: 15.5, z: -4 }, 421 - fill: true, 422 - color: colors.leather, 423 - stroke: 6, 424 - }); 425 - 426 - // toe ball 427 - new Zdog.Shape({ 428 - addTo: shoe, 429 - translate: { y: 3, z: 2.5 }, 430 - color: colors.leather, 431 - stroke: 11, 432 - }); 433 - 434 - // left leg 435 - var leftLeg = new Zdog.Shape({ 436 - path: [ 437 - { y: 4, z: 2 }, 438 - { y: 2, z: 7 }, 439 - { y: 3, z: 11 }, 440 - ], 441 - translate: { x: 5 }, 442 - closed: false, 443 - color: colors.overalls, 444 - stroke: 10, 445 - addTo: body, 446 - }); 447 - 448 - shoe.copyGraph({ 449 - addTo: leftLeg, 450 - translate: { y: 2, z: 18 }, 451 - rotate: { x: TAU * (160/360) }, 452 - }); 453 - 454 - // -- animate --- // 455 - 456 - function animate() { 457 - illo.rotate.y += isSpinning ? -0.05 : 0; 458 - illo.updateRenderGraph(); 459 - requestAnimationFrame( animate ); 460 - } 461 - 462 - animate(); 463 -
-50
demo/mega-man/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>mega-man</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #EEE; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <!-- <p>Click &amp; drag to rotate</p> --> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/dragger.js"></script> 46 - <script src="../../js/illustration.js"></script> 47 - <script src="mega-man.js"></script> 48 - 49 - </body> 50 - </html>
-350
demo/mega-man/mega-man.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 72; 5 - var h = 72; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 7, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - var isSpinning = true; 11 - var TAU = Zdog.TAU; 12 - 13 - var illo = new Zdog.Illustration({ 14 - element: illoElem, 15 - zoom: zoom, 16 - dragRotate: true, 17 - onDragStart: function() { 18 - isSpinning = false; 19 - }, 20 - }); 21 - 22 - // colors 23 - var lightBlue = '#7CF'; 24 - var darkBlue = '#25C'; 25 - var skin = '#FCA'; 26 - 27 - // -- illustration shapes --- // 28 - 29 - // keep track of pupils to change position 30 - var pupils = {}; 31 - 32 - // head 33 - 34 - var head = new Zdog.Shape({ 35 - translate: { y: -20 }, 36 - rotate: { y: 0.5 }, 37 - stroke: 21, 38 - color: darkBlue, 39 - addTo: illo, 40 - }); 41 - 42 - // helmet details 43 - [ 1, 3, 4, 5, 6, 7, 8, 9 ].forEach( function( i ) { 44 - new Zdog.Shape({ 45 - path: [ 46 - { x: -1.25, y: -1.5, z: 11.25 }, 47 - { x: 1.25, y: -1.5, z: 11.25 }, 48 - { x: 1.25, y: 1.5, z: 11.25 }, 49 - { x: -1.25, y: 1.5, z: 11.25 }, 50 - ], 51 - rotate: { x: TAU/20 * i }, 52 - stroke: 2, 53 - fill: true, 54 - color: lightBlue, 55 - addTo: head, 56 - }); 57 - }); 58 - 59 - 60 - // upper body 61 - new Zdog.Shape({ 62 - path: [ 63 - { x: -2, y: -1.25 }, 64 - { x: 0, y: -1.5 }, 65 - { x: 2, y: -1.25 }, 66 - { x: 1.7, y: 0.5 }, 67 - { x: -1.7, y: 0.5 }, 68 - ], 69 - translate: { y: -4 }, 70 - stroke: 11, 71 - color: lightBlue, 72 - fill: true, 73 - addTo: illo, 74 - }); 75 - 76 - // undies 77 - 78 - var undieX = 4.5; 79 - var undieY0 = -1; 80 - var undieY1 = 0; 81 - var undieZ = 2.5; 82 - 83 - // front undie panel 84 - var undiePanel = new Zdog.Shape({ 85 - path: [ 86 - { x: -undieX, y: undieY0 }, 87 - { x: undieX, y: undieY0 }, 88 - { x: undieX, y: undieY1 }, 89 - { x: 0, y: 1.5 }, 90 - { x: -undieX, y: undieY1 }, 91 - ], 92 - translate: { y: 4, z: undieZ }, 93 - stroke: 5, 94 - color: darkBlue, 95 - fill: true, 96 - addTo: illo, 97 - }); 98 - 99 - undiePanel.copy({ 100 - translate: { y: 4, z: -undieZ }, 101 - }); 102 - 103 - // right undie panel 104 - var sideUndiePanel = new Zdog.Shape({ 105 - path: [ 106 - { y: undieY0, z: undieZ }, 107 - { y: undieY0, z: -undieZ }, 108 - { y: undieY1, z: -undieZ }, 109 - { y: undieY1, z: undieZ }, 110 - ], 111 - translate: { x: -undieX, y: 4, }, 112 - stroke: 5, 113 - color: darkBlue, 114 - fill: true, 115 - addTo: illo, 116 - }); 117 - // left 118 - sideUndiePanel.copy({ 119 - translate: { x: undieX, y: 4, }, 120 - }); 121 - 122 - // 123 - var shoulderX = 5; 124 - var shoulderY = -7; 125 - 126 - // right upper arm 127 - var rightUpperArm = new Zdog.Shape({ 128 - path: [ 129 - { x: 0 }, 130 - { x: -7 }, 131 - ], 132 - translate: { x: -shoulderX, y: shoulderY }, 133 - rotate: { z: -0.8, y: -0.6 }, 134 - stroke: 6, 135 - color: lightBlue, 136 - addTo: illo, 137 - }); 138 - 139 - var rightForeArm = new Zdog.Shape({ 140 - path: [ 141 - { x: -4 }, 142 - { x: -8 }, 143 - ], 144 - translate: rightUpperArm.path[1], 145 - rotate: { z: 1.4 }, 146 - stroke: 10, 147 - color: darkBlue, 148 - addTo: rightUpperArm, 149 - }); 150 - 151 - new Zdog.Shape({ 152 - path: [ 153 - { x: -4 }, 154 - ], 155 - translate: rightForeArm.path[1], 156 - rotate: { z: 0.3 }, 157 - stroke: 11, 158 - color: darkBlue, 159 - addTo: rightForeArm, 160 - }); 161 - 162 - // left arm, the gun arm 163 - var leftUpperArm = new Zdog.Shape({ 164 - path: [ 165 - { x: 0 }, 166 - { x: 11 }, 167 - ], 168 - translate: { x: shoulderX, y: shoulderY-0.5 }, 169 - rotate: { z: -0.2, y: 0.3 }, 170 - stroke: 6, 171 - color: lightBlue, 172 - addTo: illo, 173 - }); 174 - 175 - var leftForeArm = new Zdog.Shape({ 176 - path: [ 177 - { x: 5 }, 178 - { x: 10 }, 179 - ], 180 - translate: leftUpperArm.path[1], 181 - rotate: { z: -TAU/4 - leftUpperArm.rotate.z }, 182 - stroke: 11, 183 - color: darkBlue, 184 - addTo: leftUpperArm, 185 - }); 186 - 187 - new Zdog.Shape({ 188 - path: [ { x: 4 } ], 189 - translate: leftForeArm.path[1], 190 - stroke: 7, 191 - color: darkBlue, 192 - addTo: leftForeArm, 193 - }); 194 - 195 - [ -1, 1 ].forEach( function( xSide ) { 196 - // face panel 197 - var facePanel = new Zdog.Shape({ 198 - path: [ 199 - { x: 4*xSide, y: -4, z: -1 }, // top inside brow 200 - { arc: [ 201 - { x: 0*xSide, y: -4, z: 0.5 }, 202 - { x: 0*xSide, y: 1, z: 1 }, // widows peak 203 - ]}, 204 - { x: 0*xSide, y: 1, z: 1 }, // nose 205 - { x: 0*xSide, y: 5.5, z: -1 }, // chin front 206 - { arc: [ 207 - { x: 7*xSide, y: 5.5, z: -4 }, // jaw 208 - { x: 7*xSide, y: 0, z: -4 }, // far side 209 - ]}, 210 - { arc: [ 211 - { x: 7*xSide, y: -4, z: -4 }, // top back brow 212 - { x: 4*xSide, y: -4, z: -1 }, // top inside brow 213 - ]}, 214 - ], 215 - translate: { y: 4, z: 8.5 }, 216 - fill: true, 217 - stroke: 1, 218 - color: skin, 219 - addTo: head, 220 - }); 221 - 222 - // eye whites 223 - var eyeWhite = new Zdog.Ellipse({ 224 - width: 4, 225 - height: 5, 226 - addTo: facePanel, 227 - translate: { x: 3.75*xSide, y: -0.5, z: 0.5 }, 228 - rotate: { y: -0.2*xSide }, 229 - stroke: 1, 230 - fill: true, 231 - color: 'white', 232 - }); 233 - 234 - // pupils 235 - var pupil = new Zdog.Ellipse({ 236 - width: 1, 237 - height: 4, 238 - translate: { x: -0.4*xSide, y: -0.2, z: 1 }, 239 - rotate: { y: 0.2*xSide }, 240 - stroke: 1, 241 - fill: true, 242 - color: '#128', 243 - addTo: eyeWhite, 244 - }); 245 - // add to hash 246 - pupils[ xSide ] = pupil; 247 - 248 - // ear cone outer 249 - var earCone = new Zdog.Ellipse({ 250 - diameter: 5.5, 251 - translate: { x: 10*xSide, y: 3, z: -1 }, 252 - rotate: { y: (TAU/4+0.2)*-xSide, x: TAU/4, z: 1 }, 253 - fill: false, 254 - stroke: 2.5, 255 - color: lightBlue, 256 - addTo: head, 257 - }); 258 - 259 - // ear cone inner inner 260 - new Zdog.Ellipse({ 261 - diameter: 5, 262 - addTo: earCone, 263 - translate: { z: -1 }, 264 - color: '#C11', 265 - stroke: false, 266 - fill: true, 267 - }); 268 - 269 - // thigh 270 - var thigh = new Zdog.Shape({ 271 - path: [ { y: 0 }, { y: 3 } ], 272 - translate: { x: 4.5*xSide, y: 8 }, 273 - rotate: { z: -0.35*xSide, x: -0.1 }, 274 - stroke: 6, 275 - color: lightBlue, 276 - addTo: illo, 277 - }); 278 - 279 - // shin 280 - var shin = new Zdog.Shape({ 281 - path: [ 282 - { y: 5, z: 0 }, 283 - { y: 14, z: 2 }, 284 - { y: 14, z: -1 }, 285 - ], 286 - translate: thigh.path[1], 287 - rotate: { y: -0.5*xSide }, 288 - fill: true, 289 - stroke: 11, 290 - color: darkBlue, 291 - addTo: thigh, 292 - }); 293 - 294 - // sole 295 - new Zdog.Shape({ 296 - path: [ 297 - { y: 2.5, x: (0.5 + 2)*xSide, z: -3 }, 298 - { y: 2.5, x: (0.5 + -2)*xSide, z: -3 }, 299 - { y: 2.5, x: (0.5 + -1)*xSide, z: 5 }, 300 - { y: 2.5, x: (0.5 + 1)*xSide, z: 5 }, 301 - ], 302 - translate: shin.path[1], 303 - rotate: { z: 0.4*xSide, x: -0.1 }, 304 - fill: true, 305 - stroke: 7, 306 - color: darkBlue, 307 - addTo: shin, 308 - }); 309 - 310 - }); 311 - 312 - // -- animate --- // 313 - 314 - var isSpinning = true; 315 - 316 - function animate() { 317 - update(); 318 - illo.renderGraph(); 319 - requestAnimationFrame( animate ); 320 - } 321 - 322 - animate(); 323 - 324 - // -- update -- // 325 - 326 - function update() { 327 - illo.rotate.y += isSpinning ? -TAU/150 : 0; 328 - illo.normalizeRotate(); 329 - 330 - // change pupil position 331 - var isAngleXFlip = illo.rotate.x > TAU/4 && illo.rotate.x < TAU * 3/4; 332 - var angleXOffset = isAngleXFlip ? 0 : TAU/2; 333 - // angleXFlip *= 334 - var headAngleY = Zdog.modulo( illo.rotate.y + head.rotate.y + angleXOffset, TAU ); 335 - var headAngleX = Zdog.modulo( illo.rotate.x + angleXOffset, TAU ); 336 - var stareX = (headAngleY / TAU * 2 - 1) * 8; 337 - var stareY = (headAngleX / TAU * 2 - 1) * 8; 338 - stareX = Math.max( -2, Math.min( 2, stareX ) ); 339 - stareY = Math.max( -1, Math.min( 1, stareY ) ); 340 - stareY = isAngleXFlip ? -stareY : stareY; 341 - // console.log( stareX ); 342 - pupils[-1].translate.x = 0.4 + stareX; 343 - pupils[1].translate.x = -0.4 + stareX; 344 - pupils[-1].translate.y = -0.2 + stareY; 345 - pupils[1].translate.y = -0.2 + stareY; 346 - 347 - // rotate 348 - illo.updateGraph(); 349 - } 350 -
-51
demo/no-illo-canvas/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>no illo canvas</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - canvas { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="no-illo-canvas.js"></script> 49 - 50 - </body> 51 - </html>
-91
demo/no-illo-canvas/no-illo-canvas.js
··· 1 - // ------------------------- demo ------------------------- // 2 - 3 - var canvas = document.querySelector('canvas'); 4 - var ctx = canvas.getContext('2d'); 5 - var illoSize = 48; 6 - var zoom = 8; 7 - var canvasSize = canvas.width = canvas.height = illoSize * zoom; 8 - var isSpinning = true; 9 - var TAU = Zdog.TAU; 10 - 11 - var scene = new Zdog.Anchor(); 12 - 13 - // ----- model ----- // 14 - 15 - new Zdog.Rect({ 16 - width: 20, 17 - height: 20, 18 - addTo: scene, 19 - translate: { z: -10 }, 20 - stroke: 2, 21 - color: '#E21', 22 - }); 23 - 24 - new Zdog.Ellipse({ 25 - diameter: 16, 26 - addTo: scene, 27 - translate: { z: 10 }, 28 - stroke: 4, 29 - color: '#19F', 30 - }); 31 - 32 - new Zdog.Shape({ 33 - path: [ 34 - { x: 0, z: 1 }, 35 - { x: -1, z: -1 }, 36 - { x: 1, z: -1 }, 37 - ], 38 - scale: { x: 5, z: 5 }, 39 - addTo: scene, 40 - stroke: 2, 41 - fill: true, 42 - color: '#EA0', 43 - }); 44 - 45 - new Zdog.Shape({ 46 - addTo: scene, 47 - translate: { y: 8 }, 48 - stroke: 8, 49 - color: '#6A6', 50 - }); 51 - 52 - // ----- animate ----- // 53 - 54 - ctx.lineJoin = 'round'; 55 - ctx.lineCap = 'round'; 56 - 57 - function animate() { 58 - scene.rotate.y += isSpinning ? +TAU/150 : 0; 59 - scene.updateGraph(); 60 - render(); 61 - requestAnimationFrame( animate ); 62 - } 63 - 64 - function render() { 65 - ctx.clearRect( 0, 0, canvasSize, canvasSize ); 66 - ctx.save(); 67 - ctx.translate( canvasSize/2, canvasSize/2 ); 68 - ctx.scale( zoom, zoom ); 69 - scene.renderGraphCanvas( ctx ); 70 - ctx.restore(); 71 - } 72 - 73 - animate(); 74 - 75 - // ----- drag ----- // 76 - 77 - // click drag to rotate 78 - var dragStartRX, dragStartRY; 79 - 80 - new Zdog.Dragger({ 81 - startElement: canvas, 82 - onDragStart: function() { 83 - isSpinning = false; 84 - dragStartRX = scene.rotate.x; 85 - dragStartRY = scene.rotate.y; 86 - }, 87 - onDragMove: function( pointer, moveX, moveY ) { 88 - scene.rotate.x = dragStartRX - ( moveY / canvasSize * TAU ); 89 - scene.rotate.y = dragStartRY - ( moveX / canvasSize * TAU ); 90 - }, 91 - });
-50
demo/no-illo-svg/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>no illo svg</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - svg { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <svg></svg> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/svg-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="no-illo-svg.js"></script> 48 - 49 - </body> 50 - </html>
-90
demo/no-illo-svg/no-illo-svg.js
··· 1 - // ------------------------- demo ------------------------- // 2 - 3 - var svg = document.querySelector('svg'); 4 - var sceneSize = 48; 5 - var zoom = 8; 6 - var illoSize = sceneSize * zoom; 7 - svg.setAttribute( 'viewBox', -sceneSize/2 + ' ' + -sceneSize/2 + ' ' + 8 - sceneSize + ' ' + sceneSize ); 9 - svg.style.width = svg.style.height = illoSize + 'px'; 10 - 11 - var isSpinning = true; 12 - var TAU = Zdog.TAU; 13 - 14 - var scene = new Zdog.Anchor(); 15 - 16 - // ----- model ----- // 17 - 18 - new Zdog.Rect({ 19 - width: 20, 20 - height: 20, 21 - addTo: scene, 22 - translate: { z: -10 }, 23 - stroke: 2, 24 - color: '#E21', 25 - }); 26 - 27 - new Zdog.Ellipse({ 28 - diameter: 16, 29 - addTo: scene, 30 - translate: { z: 10 }, 31 - stroke: 4, 32 - color: '#19F', 33 - }); 34 - 35 - new Zdog.Shape({ 36 - path: [ 37 - { x: 0, z: 1 }, 38 - { x: -1, z: -1 }, 39 - { x: 1, z: -1 }, 40 - ], 41 - scale: { x: 5, z: 5 }, 42 - addTo: scene, 43 - stroke: 2, 44 - fill: true, 45 - color: '#EA0', 46 - }); 47 - 48 - 49 - new Zdog.Shape({ 50 - addTo: scene, 51 - translate: { y: 8 }, 52 - stroke: 8, 53 - color: '#6A6', 54 - }); 55 - 56 - 57 - 58 - // ----- animate ----- // 59 - 60 - function animate() { 61 - scene.rotate.y += isSpinning ? +TAU/150 : 0; 62 - scene.updateGraph(); 63 - render(); 64 - requestAnimationFrame( animate ); 65 - } 66 - 67 - function render() { 68 - // clear 69 - scene.renderGraphSvg( svg ); 70 - } 71 - 72 - animate(); 73 - 74 - // ----- drag ----- // 75 - 76 - // click drag to rotate 77 - var dragStartRX, dragStartRY; 78 - 79 - new Zdog.Dragger({ 80 - startElement: svg, 81 - onDragStart: function() { 82 - isSpinning = false; 83 - dragStartRX = scene.rotate.x; 84 - dragStartRY = scene.rotate.y; 85 - }, 86 - onDragMove: function( pointer, moveX, moveY ) { 87 - scene.rotate.x = dragStartRX - ( moveY / illoSize * TAU ); 88 - scene.rotate.y = dragStartRY - ( moveX / illoSize * TAU ); 89 - }, 90 - });
-52
demo/patties/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>template</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <svg class="illo"></svg> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/svg-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/anchor.js"></script> 42 - <script src="../../js/path-command.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/rect.js"></script> 46 - <script src="../../js/group.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="patties.js"></script> 50 - 51 - </body> 52 - </html>
-59
demo/patties/patties.js
··· 1 - // ------------------------- demo ------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var sceneSize = 48; 5 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 6 - var zoom = Math.floor( minWindowSize / sceneSize ); 7 - var illoSize = sceneSize * zoom; 8 - illoElem.setAttribute( 'width', illoSize ); 9 - illoElem.setAttribute( 'height', illoSize ); 10 - var isSpinning = true; 11 - var TAU = Zdog.TAU; 12 - 13 - var illo = new Zdog.Illustration({ 14 - element: illoElem, 15 - zoom: zoom, 16 - dragRotate: true, 17 - onDragStart: function() { 18 - isSpinning = false; 19 - }, 20 - }); 21 - 22 - // ----- model ----- // 23 - 24 - var rect = new Zdog.Rect({ 25 - width: 20, 26 - height: 20, 27 - addTo: illo, 28 - translate: { y: 2 }, 29 - rotate: { x: TAU/4 }, 30 - stroke: 2, 31 - color: '#E21', 32 - }); 33 - 34 - new Zdog.Ellipse({ 35 - diameter: 20, 36 - addTo: illo, 37 - translate: { y: -2 }, 38 - rotate: { x: TAU/4 }, 39 - stroke: 2, 40 - color: '#19F', 41 - }); 42 - 43 - new Zdog.Shape({ 44 - addTo: rect, 45 - translate: { y: -10, z: 2 }, 46 - stroke: 2, 47 - color: '#EA0', 48 - }) 49 - 50 - // ----- animate ----- // 51 - 52 - function animate() { 53 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 54 - illo.updateRenderGraph(); 55 - requestAnimationFrame( animate ); 56 - } 57 - 58 - animate(); 59 -
-1747
demo/placeholder-page/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>Zdog</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; 19 - color: #636; 20 - } 21 - 22 - .container { 23 - text-align: center; 24 - font-size: 20px; 25 - } 26 - 27 - h1 { 28 - color: #EA0; 29 - font-size: 60px; 30 - margin: 20px 0; 31 - } 32 - 33 - .tagline { 34 - 35 - } 36 - 37 - .zdog-canvas { 38 - display: block; 39 - margin: 0px auto; 40 - cursor: move; 41 - background: #FDB; 42 - border-radius: 50%; 43 - } 44 - </style> 45 - 46 - </head> 47 - <body> 48 - 49 - <div class="container"> 50 - <canvas class="zdog-canvas" width="240" height="240"></canvas> 51 - <h1>Zdog</h1> 52 - <p class="tagline">Round, flat, designer-friendly pseudo-3D engine</p> 53 - <p>Coming soon</p> 54 - </div> 55 - 56 - <script> 57 - 58 - /** 59 - * Boilerplate & utils 60 - */ 61 - 62 - ( function( root, factory ) { 63 - // universal module definition 64 - /* globals define, module */ 65 - if ( typeof define == 'function' && define.amd ) { 66 - // AMD 67 - define( factory ); 68 - } else if ( typeof module == 'object' && module.exports ) { 69 - // CommonJS 70 - module.exports = factory(); 71 - } else { 72 - // browser global 73 - root.Zdog = factory(); 74 - } 75 - 76 - }( this, function factory() { 77 - 78 - var Zdog = {}; 79 - 80 - Zdog.TAU = Math.PI * 2; 81 - 82 - Zdog.extend = function( a, b ) { 83 - for ( var prop in b ) { 84 - a[ prop ] = b[ prop ]; 85 - } 86 - return a; 87 - }; 88 - 89 - Zdog.lerp = function( a, b, t ) { 90 - return ( b - a ) * t + a; 91 - }; 92 - 93 - Zdog.modulo = function( num, div ) { 94 - return ( ( num % div ) + div ) % div; 95 - }; 96 - 97 - var powerMultipliers = { 98 - 2: function( a ) { 99 - return a * a; 100 - }, 101 - 3: function( a ) { 102 - return a * a * a; 103 - }, 104 - 4: function( a ) { 105 - return a * a * a * a; 106 - }, 107 - 5: function( a ) { 108 - return a * a * a * a * a; 109 - } 110 - }; 111 - 112 - Zdog.easeInOut = function( alpha, power ) { 113 - if ( power == 1 ) { 114 - return alpha; 115 - } 116 - alpha = Math.max( 0, Math.min( 1, alpha ) ); 117 - var isFirstHalf = alpha < 0.5; 118 - var slope = isFirstHalf ? alpha : 1 - alpha; 119 - slope = slope / 0.5; 120 - // make easing steeper with more multiples 121 - var powerMultiplier = powerMultipliers[ power ] || powerMultipliers[2]; 122 - var curve = powerMultiplier( slope ); 123 - curve = curve / 2; 124 - return isFirstHalf ? curve : 1 - curve; 125 - }; 126 - 127 - return Zdog; 128 - 129 - })); 130 - 131 - /** 132 - * CanvasRenderer 133 - */ 134 - 135 - ( function( root, factory ) { 136 - // universal module definition 137 - /* globals define, module */ 138 - if ( typeof define == 'function' && define.amd ) { 139 - // AMD 140 - define( factory ); 141 - } else if ( typeof module == 'object' && module.exports ) { 142 - // CommonJS 143 - module.exports = factory(); 144 - } else { 145 - // browser global 146 - root.Zdog.CanvasRenderer = factory(); 147 - } 148 - }( this, function factory() { 149 - 150 - var CanvasRenderer = { isCanvas: true }; 151 - 152 - CanvasRenderer.begin = function( ctx ) { 153 - ctx.beginPath(); 154 - }; 155 - 156 - CanvasRenderer.move = function( ctx, elem, point ) { 157 - ctx.moveTo( point.x, point.y ); 158 - }; 159 - 160 - CanvasRenderer.line = function( ctx, elem, point ) { 161 - ctx.lineTo( point.x, point.y ); 162 - }; 163 - 164 - CanvasRenderer.bezier = function( ctx, elem, cp0, cp1, end ) { 165 - ctx.bezierCurveTo( cp0.x, cp0.y, cp1.x, cp1.y, end.x, end.y ); 166 - }; 167 - 168 - CanvasRenderer.closePath = function( ctx ) { 169 - ctx.closePath(); 170 - }; 171 - 172 - CanvasRenderer.setPath = function() {}; 173 - 174 - CanvasRenderer.renderPath = function( ctx, elem, pathCommands, isClosed ) { 175 - this.begin( ctx, elem ); 176 - pathCommands.forEach( function( command ) { 177 - command.render( ctx, elem, CanvasRenderer ); 178 - }); 179 - if ( isClosed ) { 180 - this.closePath( ctx, elem ); 181 - } 182 - }; 183 - 184 - CanvasRenderer.stroke = function( ctx, elem, isStroke, color, lineWidth ) { 185 - if ( !isStroke ) { 186 - return; 187 - } 188 - ctx.strokeStyle = color; 189 - ctx.lineWidth = lineWidth; 190 - ctx.stroke(); 191 - }; 192 - 193 - CanvasRenderer.fill = function( ctx, elem, isFill, color ) { 194 - if ( !isFill ) { 195 - return; 196 - } 197 - ctx.fillStyle = color; 198 - ctx.fill(); 199 - }; 200 - 201 - CanvasRenderer.end = function() {}; 202 - 203 - return CanvasRenderer; 204 - 205 - })); 206 - 207 - /** 208 - * Vector 209 - */ 210 - 211 - ( function( root, factory ) { 212 - // universal module definition 213 - /* globals define, module, require */ 214 - if ( typeof define == 'function' && define.amd ) { 215 - // AMD 216 - define( [ './boilerplate' ], factory ); 217 - } else if ( typeof module == 'object' && module.exports ) { 218 - // CommonJS 219 - module.exports = factory( require('./boilerplate') ); 220 - } else { 221 - // browser global 222 - var Zdog = root.Zdog; 223 - Zdog.Vector = factory( Zdog ); 224 - } 225 - 226 - }( this, function factory( utils ) { 227 - 228 - function Vector( position ) { 229 - this.set( position ); 230 - } 231 - 232 - var TAU = utils.TAU; 233 - 234 - // 'pos' = 'position' 235 - Vector.prototype.set = function( pos ) { 236 - this.x = pos && pos.x || 0; 237 - this.y = pos && pos.y || 0; 238 - this.z = pos && pos.z || 0; 239 - return this; 240 - }; 241 - 242 - // set coordinates without sanitizing 243 - // vec.write({ y: 2 }) only sets y coord 244 - Vector.prototype.write = function( pos ) { 245 - if ( !pos ) { 246 - return this; 247 - } 248 - this.x = pos.x != undefined ? pos.x : this.x; 249 - this.y = pos.y != undefined ? pos.y : this.y; 250 - this.z = pos.z != undefined ? pos.z : this.z; 251 - return this; 252 - }; 253 - 254 - Vector.prototype.rotate = function( rotation ) { 255 - if ( !rotation ) { 256 - return; 257 - } 258 - this.rotateZ( rotation.z ); 259 - this.rotateY( rotation.y ); 260 - this.rotateX( rotation.x ); 261 - return this; 262 - }; 263 - 264 - Vector.prototype.rotateZ = function( angle ) { 265 - rotateProperty( this, angle, 'x', 'y' ); 266 - }; 267 - 268 - Vector.prototype.rotateX = function( angle ) { 269 - rotateProperty( this, angle, 'y', 'z' ); 270 - }; 271 - 272 - Vector.prototype.rotateY = function( angle ) { 273 - rotateProperty( this, angle, 'x', 'z' ); 274 - }; 275 - 276 - function rotateProperty( vec, angle, propA, propB ) { 277 - if ( !angle || angle % TAU === 0 ) { 278 - return; 279 - } 280 - var cos = Math.cos( angle ); 281 - var sin = Math.sin( angle ); 282 - var a = vec[ propA ]; 283 - var b = vec[ propB ]; 284 - vec[ propA ] = a*cos - b*sin; 285 - vec[ propB ] = b*cos + a*sin; 286 - } 287 - 288 - Vector.prototype.add = function( pos ) { 289 - if ( !pos ) { 290 - return this; 291 - } 292 - this.x += pos.x || 0; 293 - this.y += pos.y || 0; 294 - this.z += pos.z || 0; 295 - return this; 296 - }; 297 - 298 - Vector.prototype.subtract = function( pos ) { 299 - if ( !pos ) { 300 - return this; 301 - } 302 - this.x -= pos.x || 0; 303 - this.y -= pos.y || 0; 304 - this.z -= pos.z || 0; 305 - return this; 306 - }; 307 - 308 - Vector.prototype.multiply = function( pos ) { 309 - if ( pos == undefined ) { 310 - return this; 311 - } 312 - // multiple all values by same number 313 - if ( typeof pos == 'number' ) { 314 - this.x *= pos; 315 - this.y *= pos; 316 - this.z *= pos; 317 - } else { 318 - // multiply object 319 - this.x *= pos.x != undefined ? pos.x : 1; 320 - this.y *= pos.y != undefined ? pos.y : 1; 321 - this.z *= pos.z != undefined ? pos.z : 1; 322 - } 323 - return this; 324 - }; 325 - 326 - Vector.prototype.transform = function( translation, rotation, scale ) { 327 - this.multiply( scale ); 328 - this.rotate( rotation ); 329 - this.add( translation ); 330 - return this; 331 - }; 332 - 333 - Vector.prototype.lerp = function( pos, t ) { 334 - this.x = utils.lerp( this.x, pos.x || 0, t ); 335 - this.y = utils.lerp( this.y, pos.y || 0, t ); 336 - this.z = utils.lerp( this.z, pos.z || 0, t ); 337 - return this; 338 - }; 339 - 340 - Vector.prototype.magnitude = function() { 341 - var sum = this.x*this.x + this.y*this.y + this.z*this.z; 342 - return getMagnitudeSqrt( sum ); 343 - }; 344 - 345 - function getMagnitudeSqrt( sum ) { 346 - // PERF: check if sum ~= 1 and skip sqrt 347 - if ( Math.abs( sum - 1 ) < 0.00000001 ) { 348 - return 1; 349 - } 350 - return Math.sqrt( sum ); 351 - } 352 - 353 - Vector.prototype.magnitude2d = function() { 354 - var sum = this.x*this.x + this.y*this.y; 355 - return getMagnitudeSqrt( sum ); 356 - }; 357 - 358 - Vector.prototype.copy = function() { 359 - return new Vector( this ); 360 - }; 361 - 362 - return Vector; 363 - 364 - })); 365 - 366 - /** 367 - * Anchor 368 - */ 369 - 370 - ( function( root, factory ) { 371 - // universal module definition 372 - var depends = [ './boilerplate', './vector' ]; 373 - /* globals define, module, require */ 374 - if ( typeof define == 'function' && define.amd ) { 375 - // AMD 376 - define( depends, factory ); 377 - } else if ( typeof module == 'object' && module.exports ) { 378 - // CommonJS 379 - module.exports = factory.apply( root, depends.map( require ) ); 380 - } else { 381 - // browser global 382 - var Zdog = root.Zdog; 383 - Zdog.Anchor = factory( Zdog, Zdog.Vector ); 384 - } 385 - }( this, function factory( utils, Vector ) { 386 - 387 - var TAU = utils.TAU; 388 - var onePoint = { x: 1, y: 1, z: 1 }; 389 - 390 - function Anchor( options ) { 391 - this.create( options || {} ); 392 - } 393 - 394 - Anchor.prototype.create = function( options ) { 395 - // set defaults & options 396 - utils.extend( this, this.constructor.defaults ); 397 - this.setOptions( options ); 398 - 399 - // transform 400 - this.translate = new Vector( options.translate ); 401 - this.rotate = new Vector( options.rotate ); 402 - this.scale = new Vector( onePoint ).multiply( this.scale ); 403 - // origin 404 - this.origin = new Vector(); 405 - this.renderOrigin = new Vector(); 406 - // children 407 - this.children = []; 408 - if ( this.addTo ) { 409 - this.addTo.addChild( this ); 410 - } 411 - }; 412 - 413 - Anchor.defaults = {}; 414 - 415 - Anchor.optionKeys = Object.keys( Anchor.defaults ).concat([ 416 - 'rotate', 417 - 'translate', 418 - 'scale', 419 - 'addTo', 420 - ]); 421 - 422 - Anchor.prototype.setOptions = function( options ) { 423 - var optionKeys = this.constructor.optionKeys; 424 - 425 - for ( var key in options ) { 426 - if ( optionKeys.includes( key ) ) { 427 - this[ key ] = options[ key ]; 428 - } 429 - } 430 - }; 431 - 432 - Anchor.prototype.addChild = function( shape ) { 433 - var index = this.children.indexOf( shape ); 434 - if ( index != -1 ) { 435 - return; 436 - } 437 - shape.remove(); // remove previous parent 438 - shape.addTo = this; // keep parent reference 439 - this.children.push( shape ); 440 - }; 441 - 442 - Anchor.prototype.removeChild = function( shape ) { 443 - var index = this.children.indexOf( shape ); 444 - if ( index != -1 ) { 445 - this.children.splice( index, 1 ); 446 - } 447 - }; 448 - 449 - Anchor.prototype.remove = function() { 450 - if ( this.addTo ) { 451 - this.addTo.removeChild( this ); 452 - } 453 - }; 454 - 455 - // ----- update ----- // 456 - 457 - Anchor.prototype.update = function() { 458 - // update self 459 - this.reset(); 460 - // update children 461 - this.children.forEach( function( child ) { 462 - child.update(); 463 - }); 464 - this.transform( this.translate, this.rotate, this.scale ); 465 - }; 466 - 467 - Anchor.prototype.reset = function() { 468 - this.renderOrigin.set( this.origin ); 469 - }; 470 - 471 - Anchor.prototype.transform = function( translation, rotation, scale ) { 472 - this.renderOrigin.transform( translation, rotation, scale ); 473 - // transform children 474 - this.children.forEach( function( child ) { 475 - child.transform( translation, rotation, scale ); 476 - }); 477 - }; 478 - 479 - Anchor.prototype.updateGraph = function() { 480 - this.update(); 481 - this.checkFlatGraph(); 482 - this.flatGraph.forEach( function( item ) { 483 - item.updateSortValue(); 484 - }); 485 - // z-sort 486 - this.flatGraph.sort( Anchor.shapeSorter ); 487 - }; 488 - 489 - Anchor.shapeSorter = function( a, b ) { 490 - return a.sortValue - b.sortValue; 491 - }; 492 - 493 - Anchor.prototype.checkFlatGraph = function() { 494 - if ( !this.flatGraph ) { 495 - this.updateFlatGraph(); 496 - } 497 - }; 498 - 499 - Anchor.prototype.updateFlatGraph = function() { 500 - this.flatGraph = this.getFlatGraph(); 501 - }; 502 - 503 - // return Array of self & all child graph items 504 - Anchor.prototype.getFlatGraph = function() { 505 - var flatGraph = [ this ]; 506 - this.children.forEach( function( child ) { 507 - var childFlatGraph = child.getFlatGraph(); 508 - flatGraph = flatGraph.concat( childFlatGraph ); 509 - }); 510 - return flatGraph; 511 - }; 512 - 513 - Anchor.prototype.updateSortValue = function() { 514 - this.sortValue = this.renderOrigin.z; 515 - }; 516 - 517 - // ----- render ----- // 518 - 519 - Anchor.prototype.render = function() {}; 520 - 521 - Anchor.prototype.renderGraphCanvas = function( ctx ) { 522 - if ( !ctx ) { 523 - throw new Error( 'ctx is ' + ctx + '. ' + 524 - 'Canvas context required for render. Check .renderGraphCanvas( ctx ).' ); 525 - } 526 - this.checkFlatGraph(); 527 - this.flatGraph.forEach( function( item ) { 528 - item.render( ctx, Zdog.CanvasRenderer ); 529 - }); 530 - }; 531 - 532 - Anchor.prototype.renderGraphSvg = function( svg ) { 533 - if ( !svg ) { 534 - throw new Error( 'svg is ' + svg + '. ' + 535 - 'SVG required for render. Check .renderGraphSvg( svg ).' ); 536 - } 537 - this.checkFlatGraph(); 538 - this.flatGraph.forEach( function( item ) { 539 - item.render( svg, Zdog.SvgRenderer ); 540 - }); 541 - }; 542 - 543 - // ----- misc ----- // 544 - 545 - Anchor.prototype.copy = function( options ) { 546 - // copy options 547 - var itemOptions = {}; 548 - var optionKeys = this.constructor.optionKeys; 549 - optionKeys.forEach( function( key ) { 550 - itemOptions[ key ] = this[ key ]; 551 - }, this ); 552 - // add set options 553 - utils.extend( itemOptions, options ); 554 - var ItemClass = this.constructor; 555 - return new ItemClass( itemOptions ); 556 - }; 557 - 558 - Anchor.prototype.copyGraph = function( options ) { 559 - var clone = this.copy( options ); 560 - this.children.forEach( function( child ) { 561 - child.copyGraph({ 562 - addTo: clone, 563 - }); 564 - }); 565 - return clone; 566 - }; 567 - 568 - Anchor.prototype.normalizeRotate = function() { 569 - this.rotate.x = utils.modulo( this.rotate.x, TAU ); 570 - this.rotate.y = utils.modulo( this.rotate.y, TAU ); 571 - this.rotate.z = utils.modulo( this.rotate.z, TAU ); 572 - }; 573 - 574 - // ----- subclass ----- // 575 - 576 - function getSubclass( Super ) { 577 - return function( defaults ) { 578 - // create constructor 579 - function Item( options ) { 580 - this.create( options || {} ); 581 - } 582 - 583 - Item.prototype = Object.create( Super.prototype ); 584 - Item.prototype.constructor = Item; 585 - 586 - Item.defaults = utils.extend( {}, Super.defaults ); 587 - utils.extend( Item.defaults, defaults ); 588 - // create optionKeys 589 - Item.optionKeys = Super.optionKeys.slice(0); 590 - // add defaults keys to optionKeys, dedupe 591 - Object.keys( Item.defaults ).forEach( function( key ) { 592 - if ( !Item.optionKeys.includes( key ) ) { 593 - Item.optionKeys.push( key ); 594 - } 595 - }); 596 - 597 - Item.subclass = getSubclass( Item ); 598 - 599 - return Item; 600 - }; 601 - } 602 - 603 - Anchor.subclass = getSubclass( Anchor ); 604 - 605 - return Anchor; 606 - 607 - })); 608 - 609 - /** 610 - * PathCommand 611 - */ 612 - 613 - ( function( root, factory ) { 614 - // universal module definition 615 - /* globals define, module, require */ 616 - if ( typeof define == 'function' && define.amd ) { 617 - // AMD 618 - define( [ './vector' ], factory ); 619 - } else if ( typeof module == 'object' && module.exports ) { 620 - // CommonJS 621 - module.exports = factory( require('./vector') ); 622 - } else { 623 - // browser global 624 - var Zdog = root.Zdog; 625 - Zdog.PathCommand = factory( Zdog.Vector ); 626 - } 627 - }( this, function factory( Vector ) { 628 - 629 - function PathCommand( method, points, previousPoint ) { 630 - this.method = method; 631 - this.points = points.map( mapVectorPoint ); 632 - this.renderPoints = points.map( mapNewVector ); 633 - this.previousPoint = previousPoint; 634 - this.endRenderPoint = this.renderPoints[ this.renderPoints.length - 1 ]; 635 - // arc actions come with previous point & corner point 636 - // but require bezier control points 637 - if ( method == 'arc' ) { 638 - this.controlPoints = [ new Vector(), new Vector() ]; 639 - } 640 - } 641 - 642 - function mapVectorPoint( point ) { 643 - if ( point instanceof Vector ) { 644 - return point; 645 - } else { 646 - return new Vector( point ); 647 - } 648 - } 649 - 650 - function mapNewVector( point ) { 651 - return new Vector( point ); 652 - } 653 - 654 - PathCommand.prototype.reset = function() { 655 - // reset renderPoints back to orignal points position 656 - var points = this.points; 657 - this.renderPoints.forEach( function( renderPoint, i ) { 658 - var point = points[i]; 659 - renderPoint.set( point ); 660 - }); 661 - }; 662 - 663 - PathCommand.prototype.transform = function( translation, rotation, scale ) { 664 - this.renderPoints.forEach( function( renderPoint ) { 665 - renderPoint.transform( translation, rotation, scale ); 666 - }); 667 - }; 668 - 669 - PathCommand.prototype.render = function( ctx, elem, renderer ) { 670 - return this[ this.method ]( ctx, elem, renderer ); 671 - }; 672 - 673 - PathCommand.prototype.move = function( ctx, elem, renderer ) { 674 - return renderer.move( ctx, elem, this.renderPoints[0] ); 675 - }; 676 - 677 - PathCommand.prototype.line = function( ctx, elem, renderer ) { 678 - return renderer.line( ctx, elem, this.renderPoints[0] ); 679 - }; 680 - 681 - PathCommand.prototype.bezier = function( ctx, elem, renderer ) { 682 - var cp0 = this.renderPoints[0]; 683 - var cp1 = this.renderPoints[1]; 684 - var end = this.renderPoints[2]; 685 - return renderer.bezier( ctx, elem, cp0, cp1, end ); 686 - }; 687 - 688 - PathCommand.prototype.arc = function( ctx, elem, renderer ) { 689 - var prev = this.previousPoint; 690 - var corner = this.renderPoints[0]; 691 - var end = this.renderPoints[1]; 692 - var cp0 = this.controlPoints[0]; 693 - var cp1 = this.controlPoints[1]; 694 - cp0.set( prev ).lerp( corner, 9/16 ); 695 - cp1.set( end ).lerp( corner, 9/16 ); 696 - return renderer.bezier( ctx, elem, cp0, cp1, end ); 697 - }; 698 - 699 - return PathCommand; 700 - 701 - })); 702 - 703 - /** 704 - * Shape 705 - */ 706 - 707 - ( function( root, factory ) { 708 - // universal module definition 709 - var depends = [ './boilerplate', './vector', './path-command', './anchor' ]; 710 - /* globals define, module, require */ 711 - if ( typeof define == 'function' && define.amd ) { 712 - // AMD 713 - define( depends, factory ); 714 - } else if ( typeof module == 'object' && module.exports ) { 715 - // CommonJS 716 - module.exports = factory.apply( root, depends.map( require ) ); 717 - } else { 718 - // browser global 719 - var Zdog = root.Zdog; 720 - Zdog.Shape = factory( Zdog, Zdog.Vector, Zdog.PathCommand, Zdog.Anchor ); 721 - } 722 - }( this, function factory( utils, Vector, PathCommand, Anchor ) { 723 - 724 - var Shape = Anchor.subclass({ 725 - stroke: 1, 726 - fill: false, 727 - color: '#333', 728 - closed: true, 729 - visible: true, 730 - path: [ {} ], 731 - front: { z: 1 }, 732 - backface: true, 733 - }); 734 - 735 - Shape.prototype.create = function( options ) { 736 - Anchor.prototype.create.call( this, options ); 737 - this.updatePath(); 738 - // front 739 - this.front = new Vector( options.front || this.front ); 740 - this.renderFront = new Vector( this.front ); 741 - this.renderNormal = new Vector(); 742 - }; 743 - 744 - var actionNames = [ 745 - 'move', 746 - 'line', 747 - 'bezier', 748 - 'arc', 749 - ]; 750 - 751 - Shape.prototype.updatePath = function() { 752 - this.setPath(); 753 - this.updatePathCommands(); 754 - }; 755 - 756 - // place holder for Ellipse, Rect, etc. 757 - Shape.prototype.setPath = function() {}; 758 - 759 - // parse path into PathCommands 760 - Shape.prototype.updatePathCommands = function() { 761 - var previousPoint; 762 - this.pathCommands = this.path.map( function( pathPart, i ) { 763 - // pathPart can be just vector coordinates -> { x, y, z } 764 - // or path instruction -> { arc: [ {x0,y0,z0}, {x1,y1,z1} ] } 765 - var keys = Object.keys( pathPart ); 766 - var method = keys[0]; 767 - var points = pathPart[ method ]; 768 - // default to line if no instruction 769 - var isInstruction = keys.length == 1 && actionNames.includes( method ); 770 - if ( !isInstruction ) { 771 - method = 'line'; 772 - points = pathPart; 773 - } 774 - // munge single-point methods like line & move without arrays 775 - var isLineOrMove = method == 'line' || method == 'move'; 776 - var isPointsArray = Array.isArray( points ); 777 - if ( isLineOrMove && !isPointsArray ) { 778 - points = [ points ]; 779 - } 780 - 781 - // first action is always move 782 - method = i === 0 ? 'move' : method; 783 - // arcs require previous last point 784 - var command = new PathCommand( method, points, previousPoint ); 785 - // update previousLastPoint 786 - previousPoint = command.endRenderPoint; 787 - return command; 788 - }); 789 - }; 790 - 791 - // ----- update ----- // 792 - 793 - Shape.prototype.reset = function() { 794 - this.renderOrigin.set( this.origin ); 795 - this.renderFront.set( this.front ); 796 - // reset command render points 797 - this.pathCommands.forEach( function( command ) { 798 - command.reset(); 799 - }); 800 - }; 801 - 802 - Shape.prototype.transform = function( translation, rotation, scale ) { 803 - // calculate render points backface visibility & cone/hemisphere shapes 804 - this.renderOrigin.transform( translation, rotation, scale ); 805 - this.renderFront.transform( translation, rotation, scale ); 806 - this.renderNormal.set( this.renderOrigin ).subtract( this.renderFront ); 807 - // transform points 808 - this.pathCommands.forEach( function( command ) { 809 - command.transform( translation, rotation, scale ); 810 - }); 811 - // transform children 812 - this.children.forEach( function( child ) { 813 - child.transform( translation, rotation, scale ); 814 - }); 815 - }; 816 - 817 - 818 - Shape.prototype.updateSortValue = function() { 819 - var sortValueTotal = 0; 820 - this.pathCommands.forEach( function( command ) { 821 - sortValueTotal += command.endRenderPoint.z; 822 - }); 823 - // average sort value of all points 824 - // def not geometrically correct, but works for me 825 - this.sortValue = sortValueTotal / this.pathCommands.length; 826 - }; 827 - 828 - // ----- render ----- // 829 - 830 - Shape.prototype.render = function( ctx, renderer ) { 831 - var length = this.pathCommands.length; 832 - if ( !this.visible || !length ) { 833 - return; 834 - } 835 - // do not render if hiding backface 836 - this.isFacingBack = this.renderNormal.z > 0; 837 - if ( !this.backface && this.isFacingBack ) { 838 - return; 839 - } 840 - if ( !renderer ) { 841 - throw new Error( 'Zdog renderer required. Set to ' + renderer ); 842 - } 843 - // render dot or path 844 - var isDot = length == 1; 845 - if ( renderer.isCanvas && isDot ) { 846 - this.renderCanvasDot( ctx, renderer ); 847 - } else { 848 - this.renderPath( ctx, renderer ); 849 - } 850 - }; 851 - 852 - var TAU = utils.TAU; 853 - // Safari does not render lines with no size, have to render circle instead 854 - Shape.prototype.renderCanvasDot = function( ctx ) { 855 - var lineWidth = this.getLineWidth(); 856 - if ( !lineWidth ) { 857 - return; 858 - } 859 - ctx.fillStyle = this.getRenderColor(); 860 - var point = this.pathCommands[0].endRenderPoint; 861 - ctx.beginPath(); 862 - var radius = lineWidth/2; 863 - ctx.arc( point.x, point.y, radius, 0, TAU ); 864 - ctx.fill(); 865 - }; 866 - 867 - Shape.prototype.getLineWidth = function() { 868 - if ( !this.stroke ) { 869 - return 0; 870 - } 871 - if ( this.stroke == true ) { 872 - return 1; 873 - } 874 - return this.stroke; 875 - }; 876 - 877 - Shape.prototype.getRenderColor = function() { 878 - // use backface color if applicable 879 - var isBackfaceColor = typeof this.backface == 'string' && this.isFacingBack; 880 - var color = isBackfaceColor ? this.backface : this.color; 881 - return color; 882 - }; 883 - 884 - Shape.prototype.renderPath = function( ctx, renderer ) { 885 - var elem = this.getRenderElement( ctx, renderer ); 886 - var isTwoPoints = this.pathCommands.length == 2 && 887 - this.pathCommands[1].method == 'line'; 888 - var isClosed = !isTwoPoints && this.closed; 889 - var color = this.getRenderColor(); 890 - 891 - renderer.renderPath( ctx, elem, this.pathCommands, isClosed ); 892 - renderer.stroke( ctx, elem, this.stroke, color, this.getLineWidth() ); 893 - renderer.fill( ctx, elem, this.fill, color ); 894 - renderer.end( ctx, elem ); 895 - }; 896 - 897 - var svgURI = 'http://www.w3.org/2000/svg'; 898 - 899 - Shape.prototype.getRenderElement = function( ctx, renderer ) { 900 - if ( !renderer.isSvg ) { 901 - return; 902 - } 903 - if ( !this.svgElement ) { 904 - // create svgElement 905 - this.svgElement = document.createElementNS( svgURI, 'path'); 906 - this.svgElement.setAttribute( 'stroke-linecap', 'round' ); 907 - this.svgElement.setAttribute( 'stroke-linejoin', 'round' ); 908 - } 909 - return this.svgElement; 910 - }; 911 - 912 - return Shape; 913 - 914 - })); 915 - 916 - /** 917 - * Ellipse 918 - */ 919 - 920 - ( function( root, factory ) { 921 - // universal module definition 922 - /* globals define, module, require */ 923 - if ( typeof define == 'function' && define.amd ) { 924 - // AMD 925 - define( [ './shape' ], factory ); 926 - } else if ( typeof module == 'object' && module.exports ) { 927 - // CommonJS 928 - module.exports = factory( require('./shape') ); 929 - } else { 930 - // browser global 931 - var Zdog = root.Zdog; 932 - Zdog.Ellipse = factory( Zdog.Shape ); 933 - } 934 - 935 - }( this, function factory( Shape ) { 936 - 937 - var Ellipse = Shape.subclass({ 938 - diameter: 1, 939 - width: undefined, 940 - height: undefined, 941 - quarters: 4, 942 - closed: false, 943 - }); 944 - 945 - Ellipse.prototype.setPath = function() { 946 - var width = this.width != undefined ? this.width : this.diameter; 947 - var height = this.height != undefined ? this.height : this.diameter; 948 - var x = width / 2; 949 - var y = height / 2; 950 - this.path = [ 951 - { x: 0, y: -y }, 952 - { arc: [ // top right 953 - { x: x, y: -y }, 954 - { x: x, y: 0 }, 955 - ]} 956 - ]; 957 - // bottom right 958 - if ( this.quarters > 1 ) { 959 - this.path.push({ arc: [ 960 - { x: x, y: y }, 961 - { x: 0, y: y }, 962 - ]}); 963 - } 964 - // bottom left 965 - if ( this.quarters > 2 ) { 966 - this.path.push({ arc: [ 967 - { x: -x, y: y }, 968 - { x: -x, y: 0 }, 969 - ]}); 970 - } 971 - // top left 972 - if ( this.quarters > 3 ) { 973 - this.path.push({ arc: [ 974 - { x: -x, y: -y }, 975 - { x: 0, y: -y }, 976 - ]}); 977 - } 978 - }; 979 - 980 - Ellipse.prototype.updateSortValue = function() { 981 - Shape.prototype.updateSortValue.apply( this, arguments ); 982 - if ( this.quarters != 4 ) { 983 - return; 984 - } 985 - // ellipse is self closing, do not count last point twice 986 - var length = this.pathCommands.length; 987 - var lastPoint = this.pathCommands[ length - 1 ].endRenderPoint; 988 - this.sortValue -= lastPoint.z / length; 989 - }; 990 - 991 - return Ellipse; 992 - 993 - })); 994 - 995 - /** 996 - * Rect 997 - */ 998 - 999 - ( function( root, factory ) { 1000 - // universal module definition 1001 - /* globals define, module, require */ 1002 - if ( typeof define == 'function' && define.amd ) { 1003 - // AMD 1004 - define( [ './shape' ], factory ); 1005 - } else if ( typeof module == 'object' && module.exports ) { 1006 - // CommonJS 1007 - module.exports = factory( require('./shape') ); 1008 - } else { 1009 - // browser global 1010 - var Zdog = root.Zdog; 1011 - Zdog.Rect = factory( Zdog.Shape ); 1012 - } 1013 - }( this, function factory( Shape ) { 1014 - 1015 - var Rect = Shape.subclass({ 1016 - width: 1, 1017 - height: 1, 1018 - }); 1019 - 1020 - Rect.prototype.setPath = function() { 1021 - var x = this.width / 2; 1022 - var y = this.height / 2; 1023 - this.path = [ 1024 - { x: -x, y: -y }, 1025 - { x: x, y: -y }, 1026 - { x: x, y: y }, 1027 - { x: -x, y: y }, 1028 - ]; 1029 - }; 1030 - 1031 - return Rect; 1032 - 1033 - })); 1034 - 1035 - /** 1036 - * Group 1037 - */ 1038 - 1039 - ( function( root, factory ) { 1040 - // universal module definition 1041 - /* globals define, module, require */ 1042 - if ( typeof define == 'function' && define.amd ) { 1043 - // AMD 1044 - define( [ './anchor' ], factory ); 1045 - } else if ( typeof module == 'object' && module.exports ) { 1046 - // CommonJS 1047 - module.exports = factory( require('./anchor') ); 1048 - } else { 1049 - // browser global 1050 - var Zdog = root.Zdog; 1051 - Zdog.Group = factory( Zdog.Anchor ); 1052 - } 1053 - }( this, function factory( Anchor ) { 1054 - 1055 - var Group = Anchor.subclass({ 1056 - updateSort: false, 1057 - visible: true, 1058 - }); 1059 - 1060 - // ----- update ----- // 1061 - 1062 - Group.prototype.updateSortValue = function() { 1063 - var sortValueTotal = 0; 1064 - this.checkFlatGraph(); 1065 - this.flatGraph.forEach( function( item ) { 1066 - item.updateSortValue(); 1067 - sortValueTotal += item.sortValue; 1068 - }); 1069 - // average sort value of all points 1070 - // def not geometrically correct, but works for me 1071 - this.sortValue = sortValueTotal / this.flatGraph.length; 1072 - 1073 - if ( this.updateSort ) { 1074 - this.flatGraph.sort( Anchor.shapeSorter ); 1075 - } 1076 - }; 1077 - 1078 - // ----- render ----- // 1079 - 1080 - Group.prototype.render = function( ctx, renderer ) { 1081 - if ( !this.visible ) { 1082 - return; 1083 - } 1084 - 1085 - this.checkFlatGraph(); 1086 - this.flatGraph.forEach( function( item ) { 1087 - item.render( ctx, renderer ); 1088 - }); 1089 - }; 1090 - 1091 - // do not include children, group handles rendering & sorting internally 1092 - Group.prototype.getFlatGraph = function() { 1093 - return [ this ]; 1094 - }; 1095 - 1096 - // get flat graph only used for group 1097 - // do not include in parent flatGraphs 1098 - Group.prototype.updateFlatGraph = function() { 1099 - // do not include self 1100 - var flatGraph = []; 1101 - this.children.forEach( function( child ) { 1102 - var childFlatGraph = child.getFlatGraph(); 1103 - flatGraph = flatGraph.concat( childFlatGraph ); 1104 - }); 1105 - this.flatGraph = flatGraph; 1106 - }; 1107 - 1108 - return Group; 1109 - 1110 - })); 1111 - 1112 - /** 1113 - * Dragger 1114 - */ 1115 - 1116 - ( function( root, factory ) { 1117 - // universal module definition 1118 - /* globals define, module */ 1119 - if ( typeof define == 'function' && define.amd ) { 1120 - // AMD 1121 - define( factory ); 1122 - } else if ( typeof module == 'object' && module.exports ) { 1123 - // CommonJS 1124 - module.exports = factory(); 1125 - } else { 1126 - // browser global 1127 - root.Zdog.Dragger = factory(); 1128 - } 1129 - }( this, function factory() { 1130 - 1131 - // quick & dirty drag event stuff 1132 - // messes up if multiple pointers/touches 1133 - 1134 - // event support, default to mouse events 1135 - var downEvent = 'mousedown'; 1136 - var moveEvent = 'mousemove'; 1137 - var upEvent = 'mouseup'; 1138 - if ( window.PointerEvent ) { 1139 - // PointerEvent, Chrome 1140 - downEvent = 'pointerdown'; 1141 - moveEvent = 'pointermove'; 1142 - upEvent = 'pointerup'; 1143 - } else if ( 'ontouchstart' in window ) { 1144 - // Touch Events, iOS Safari 1145 - downEvent = 'touchstart'; 1146 - moveEvent = 'touchmove'; 1147 - upEvent = 'touchend'; 1148 - } 1149 - 1150 - function noop() {} 1151 - 1152 - function Dragger( options ) { 1153 - this.create( options || {} ); 1154 - } 1155 - 1156 - Dragger.prototype.create = function( options ) { 1157 - this.onDragStart = options.onDragStart || noop; 1158 - this.onDragMove = options.onDragMove || noop; 1159 - this.onDragEnd = options.onDragEnd || noop; 1160 - 1161 - this.bindDrag( options.startElement ); 1162 - }; 1163 - 1164 - Dragger.prototype.bindDrag = function( element ) { 1165 - element = this.getQueryElement( element ); 1166 - if ( element ) { 1167 - element.addEventListener( downEvent , this ); 1168 - } 1169 - }; 1170 - 1171 - Dragger.prototype.getQueryElement = function( element ) { 1172 - if ( typeof element == 'string' ) { 1173 - // with string, query selector 1174 - element = document.querySelector( element ); 1175 - } 1176 - return element; 1177 - }; 1178 - 1179 - Dragger.prototype.handleEvent = function( event ) { 1180 - var method = this[ 'on' + event.type ]; 1181 - if ( method ) { 1182 - method.call( this, event ); 1183 - } 1184 - }; 1185 - 1186 - Dragger.prototype.onmousedown = 1187 - Dragger.prototype.onpointerdown = function( event ) { 1188 - this.dragStart( event, event ); 1189 - }; 1190 - 1191 - Dragger.prototype.ontouchstart = function( event ) { 1192 - this.dragStart( event, event.changedTouches[0] ); 1193 - }; 1194 - 1195 - Dragger.prototype.dragStart = function( event, pointer ) { 1196 - event.preventDefault(); 1197 - this.dragStartX = pointer.pageX; 1198 - this.dragStartY = pointer.pageY; 1199 - window.addEventListener( moveEvent, this ); 1200 - window.addEventListener( upEvent, this ); 1201 - this.onDragStart( pointer ); 1202 - }; 1203 - 1204 - Dragger.prototype.ontouchmove = function( event ) { 1205 - // HACK, moved touch may not be first 1206 - this.dragMove( event, event.changedTouches[0] ); 1207 - }; 1208 - 1209 - Dragger.prototype.onmousemove = 1210 - Dragger.prototype.onpointermove = function( event ) { 1211 - this.dragMove( event, event ); 1212 - }; 1213 - 1214 - Dragger.prototype.dragMove = function( event, pointer ) { 1215 - event.preventDefault(); 1216 - var moveX = pointer.pageX - this.dragStartX; 1217 - var moveY = pointer.pageY - this.dragStartY; 1218 - this.onDragMove( pointer, moveX, moveY ); 1219 - }; 1220 - 1221 - Dragger.prototype.onmouseup = 1222 - Dragger.prototype.onpointerup = 1223 - Dragger.prototype.ontouchend = 1224 - Dragger.prototype.dragEnd = function(/* event */) { 1225 - window.removeEventListener( moveEvent, this ); 1226 - window.removeEventListener( upEvent, this ); 1227 - this.onDragEnd(); 1228 - }; 1229 - 1230 - return Dragger; 1231 - 1232 - })); 1233 - 1234 - /** 1235 - * Illustration 1236 - */ 1237 - 1238 - ( function( root, factory ) { 1239 - // universal module definition 1240 - var depends = [ './boilerplate', './anchor', './dragger' ]; 1241 - /* globals define, module, require */ 1242 - if ( typeof define == 'function' && define.amd ) { 1243 - // AMD 1244 - define( depends, factory ); 1245 - } else if ( typeof module == 'object' && module.exports ) { 1246 - // CommonJS 1247 - module.exports = factory.apply( root, depends.map( require ) ); 1248 - } else { 1249 - // browser global 1250 - var Zdog = root.Zdog; 1251 - Zdog.Illustration = factory( Zdog, Zdog.Anchor, Zdog.Dragger ); 1252 - } 1253 - }( this, function factory( utils, Anchor, Dragger ) { 1254 - 1255 - function noop() {} 1256 - var TAU = utils.TAU; 1257 - 1258 - var Illustration = Anchor.subclass({ 1259 - element: undefined, 1260 - centered: true, 1261 - zoom: 1, 1262 - dragRotate: false, 1263 - resize: false, 1264 - onPrerender: noop, 1265 - onDragStart: noop, 1266 - onDragMove: noop, 1267 - onDragEnd: noop, 1268 - onResize: noop, 1269 - }); 1270 - 1271 - utils.extend( Illustration.prototype, Dragger.prototype ); 1272 - 1273 - Illustration.prototype.create = function( options ) { 1274 - Anchor.prototype.create.call( this, options ); 1275 - Dragger.prototype.create.call( this, options ); 1276 - this.setElement( this.element ); 1277 - this.setDragRotate( this.dragRotate ); 1278 - this.setResize( this.resize ); 1279 - }; 1280 - 1281 - Illustration.prototype.setElement = function( element ) { 1282 - element = this.getQueryElement( element ); 1283 - if ( !element ) { 1284 - throw new Error( 'Zdog.Illustration element required. Set to ' + element ); 1285 - } 1286 - 1287 - var nodeName = element.nodeName.toLowerCase(); 1288 - if ( nodeName == 'canvas' ) { 1289 - this.setCanvas( element ); 1290 - } else if ( nodeName == 'svg' ) { 1291 - this.setSvg( element ); 1292 - } 1293 - }; 1294 - 1295 - Illustration.prototype.setSize = function( width, height ) { 1296 - width = Math.round( width ); 1297 - height = Math.round( height ); 1298 - if ( this.isCanvas ) { 1299 - this.setSizeCanvas( width, height ); 1300 - } else if ( this.isSvg ) { 1301 - this.setSizeSvg( width, height ); 1302 - } 1303 - }; 1304 - 1305 - Illustration.prototype.setResize = function( resize ) { 1306 - this.resize = resize; 1307 - // create resize event listener 1308 - if ( !this.resizeListener ) { 1309 - this.resizeListener = this.onWindowResize.bind( this ); 1310 - } 1311 - // add/remove event listener 1312 - if ( resize ) { 1313 - window.addEventListener( 'resize', this.resizeListener ); 1314 - this.onWindowResize(); 1315 - } else { 1316 - window.removeEventListener( 'resize', this.resizeListener ); 1317 - } 1318 - }; 1319 - 1320 - // TODO debounce this? 1321 - Illustration.prototype.onWindowResize = function() { 1322 - this.setMeasuredSize(); 1323 - this.onResize( this.width, this.height ); 1324 - }; 1325 - 1326 - Illustration.prototype.setMeasuredSize = function() { 1327 - var width, height; 1328 - var isFullscreen = this.resize == 'fullscreen'; 1329 - if ( isFullscreen ) { 1330 - width = window.innerWidth; 1331 - height = window.innerHeight; 1332 - } else { 1333 - var rect = this.element.getBoundingClientRect(); 1334 - width = rect.width; 1335 - height = rect.height; 1336 - } 1337 - this.setSize( width, height ); 1338 - }; 1339 - 1340 - // ----- render ----- // 1341 - 1342 - Illustration.prototype.renderGraph = function( item ) { 1343 - if ( this.isCanvas ) { 1344 - this.renderGraphCanvas( item ); 1345 - } else if ( this.isSvg ) { 1346 - this.renderGraphSvg( item ); 1347 - } 1348 - }; 1349 - 1350 - // combo method 1351 - Illustration.prototype.updateRenderGraph = function( item ) { 1352 - this.updateGraph(); 1353 - this.renderGraph( item ); 1354 - }; 1355 - 1356 - // ----- canvas ----- // 1357 - 1358 - Illustration.prototype.setCanvas = function( element ) { 1359 - this.element = element; 1360 - this.isCanvas = true; 1361 - // update related properties 1362 - this.ctx = this.element.getContext('2d'); 1363 - // set initial size 1364 - this.setSizeCanvas( element.width, element.height ); 1365 - }; 1366 - 1367 - Illustration.prototype.setSizeCanvas = function( width, height ) { 1368 - this.width = width; 1369 - this.height = height; 1370 - // up-rez for hi-DPI devices 1371 - var pixelRatio = this.pixelRatio = window.devicePixelRatio || 1; 1372 - this.element.width = this.canvasWidth = width * pixelRatio; 1373 - this.element.height = this.canvasHeight = height * pixelRatio; 1374 - if ( pixelRatio > 1 ) { 1375 - this.element.style.width = width + 'px'; 1376 - this.element.style.height = height + 'px'; 1377 - } 1378 - }; 1379 - 1380 - Illustration.prototype.renderGraphCanvas = function( item ) { 1381 - item = item || this; 1382 - this.prerenderCanvas(); 1383 - Anchor.prototype.renderGraphCanvas.call( item, this.ctx ); 1384 - this.postrenderCanvas(); 1385 - }; 1386 - 1387 - Illustration.prototype.prerenderCanvas = function() { 1388 - var ctx = this.ctx; 1389 - ctx.lineCap = 'round'; 1390 - ctx.lineJoin = 'round'; 1391 - ctx.clearRect( 0, 0, this.canvasWidth, this.canvasHeight ); 1392 - ctx.save(); 1393 - if ( this.centered ) { 1394 - ctx.translate( this.width/2, this.height/2 ); 1395 - } 1396 - var scale = this.pixelRatio * this.zoom; 1397 - ctx.scale( scale, scale ); 1398 - this.onPrerender( ctx ); 1399 - }; 1400 - 1401 - Illustration.prototype.postrenderCanvas = function () { 1402 - this.ctx.restore(); 1403 - }; 1404 - 1405 - // ----- svg ----- // 1406 - 1407 - Illustration.prototype.setSvg = function( element ) { 1408 - this.element = element; 1409 - this.isSvg = true; 1410 - this.pixelRatio = 1; 1411 - // set initial size from width & height attributes 1412 - var width = element.getAttribute('width'); 1413 - var height = element.getAttribute('height'); 1414 - this.setSizeSvg( width, height ); 1415 - }; 1416 - 1417 - Illustration.prototype.setSizeSvg = function( width, height ) { 1418 - this.width = width; 1419 - this.height = height; 1420 - var viewWidth = width / this.zoom; 1421 - var viewHeight = height / this.zoom; 1422 - var viewX = this.centered ? -viewWidth/2 : 0; 1423 - var viewY = this.centered ? -viewHeight/2 : 0; 1424 - this.element.setAttribute( 'viewBox', viewX + ' ' + viewY + ' ' + 1425 - viewWidth + ' ' + viewHeight ); 1426 - if ( this.resize ) { 1427 - // remove size attributes, let size be determined by viewbox 1428 - this.element.removeAttribute('width'); 1429 - this.element.removeAttribute('height'); 1430 - } else { 1431 - this.element.setAttribute( 'width', width ); 1432 - this.element.setAttribute( 'height', height ); 1433 - } 1434 - }; 1435 - 1436 - Illustration.prototype.renderGraphSvg = function( item ) { 1437 - item = item || this; 1438 - empty( this.element ); 1439 - this.onPrerender( this.element ); 1440 - Anchor.prototype.renderGraphSvg.call( item, this.element ); 1441 - }; 1442 - 1443 - function empty( element ) { 1444 - while ( element.firstChild ) { 1445 - element.removeChild( element.firstChild ); 1446 - } 1447 - } 1448 - 1449 - // ----- drag ----- // 1450 - 1451 - Illustration.prototype.setDragRotate = function( item ) { 1452 - if ( !item ) { 1453 - return; 1454 - } else if ( item === true ) { 1455 - item = this; 1456 - } 1457 - this.dragRotate = item; 1458 - 1459 - this.bindDrag( this.element ); 1460 - }; 1461 - 1462 - Illustration.prototype.dragStart = function(/* event, pointer */) { 1463 - this.dragStartRX = this.dragRotate.rotate.x; 1464 - this.dragStartRY = this.dragRotate.rotate.y; 1465 - Dragger.prototype.dragStart.apply( this, arguments ); 1466 - }; 1467 - 1468 - Illustration.prototype.dragMove = function( event, pointer ) { 1469 - var moveX = pointer.pageX - this.dragStartX; 1470 - var moveY = pointer.pageY - this.dragStartY; 1471 - var displaySize = Math.min( this.width, this.height ); 1472 - var moveRY = moveX / displaySize * TAU; 1473 - var moveRX = moveY / displaySize * TAU; 1474 - this.dragRotate.rotate.x = this.dragStartRX - moveRX; 1475 - this.dragRotate.rotate.y = this.dragStartRY - moveRY; 1476 - Dragger.prototype.dragMove.apply( this, arguments ); 1477 - }; 1478 - 1479 - return Illustration; 1480 - 1481 - })); 1482 - 1483 - 1484 - // -------------------------- demo -------------------------- // 1485 - 1486 - var illoElem = document.querySelector('.zdog-canvas'); 1487 - var sceneSize = 96; 1488 - var minWindowSize = Math.min( window.innerWidth - 100 , window.innerHeight - 300 ); 1489 - var zoom = Math.floor( minWindowSize / sceneSize ); 1490 - zoom = Math.min( 5, zoom ) 1491 - var illoSize = sceneSize * zoom; 1492 - illoElem.width = illoElem.height = illoSize; 1493 - 1494 - var isSpinning = true; 1495 - var TAU = Zdog.TAU; 1496 - var initRotate = { x: 20/360 * TAU, y: -50/360 * TAU }; 1497 - 1498 - var illo = new Zdog.Illustration({ 1499 - element: illoElem, 1500 - zoom: zoom, 1501 - rotate: initRotate, 1502 - dragRotate: true, 1503 - onDragStart: function() { 1504 - isSpinning = false; 1505 - }, 1506 - }); 1507 - 1508 - var red = '#E62'; 1509 - var gold = '#EA0'; 1510 - var denim = '#636'; 1511 - 1512 - var depth = 20; 1513 - var lineWidth = 8; 1514 - 1515 - // -- illustration shapes --- // 1516 - 1517 - var bigGroup = new Zdog.Group({ 1518 - addTo: illo, 1519 - }); 1520 - 1521 - var backGroup = new Zdog.Group({ 1522 - addTo: bigGroup, 1523 - updateSort: true, 1524 - }); 1525 - 1526 - 1527 - // top 1528 - var topSide = new Zdog.Rect({ 1529 - addTo: backGroup, 1530 - width: 40, 1531 - height: depth, 1532 - translate: { y: -20 }, 1533 - rotate: { x: TAU/4 }, 1534 - fill: true, 1535 - stroke: lineWidth, 1536 - color: red, 1537 - }); 1538 - topSide.copy({ 1539 - translate: { y: 20 }, 1540 - rotate: { x: -TAU/4 }, 1541 - }); 1542 - 1543 - var endCap = new Zdog.Rect({ 1544 - addTo: backGroup, 1545 - width: depth, 1546 - height: 8, 1547 - translate: { x: -20, y: -16 }, 1548 - rotate: { y: TAU/4 }, 1549 - fill: true, 1550 - color: red, 1551 - stroke: lineWidth, 1552 - }); 1553 - endCap.copy({ 1554 - translate: { x: -20, y: 16 }, 1555 - }); 1556 - endCap.copy({ 1557 - translate: { x: 20, y: -16 }, 1558 - rotate: { y: -TAU/4 }, 1559 - }); 1560 - endCap.copy({ 1561 - translate: { x: 20, y: 16 }, 1562 - rotate: { y: -TAU/4 }, 1563 - }); 1564 - 1565 - var underside = new Zdog.Rect({ 1566 - addTo: backGroup, 1567 - width: 30, 1568 - height: depth, 1569 - translate: { x: -5, y: -12 }, 1570 - rotate: { x: -TAU/4 }, 1571 - stroke: lineWidth, 1572 - fill: true, 1573 - color: red, 1574 - }); 1575 - underside.copy({ 1576 - translate: { x: 5, y: 12 }, 1577 - rotate: { x: TAU/4 }, 1578 - }); 1579 - 1580 - var slopeW = 30; 1581 - var slopeH = 22; 1582 - var slopeAngle = Math.atan( slopeH/slopeW ); 1583 - 1584 - var slope = new Zdog.Rect({ 1585 - addTo: backGroup, 1586 - width: Math.sqrt( slopeH*slopeH + slopeW*slopeW ), 1587 - height: depth, 1588 - translate: { x: -5 }, 1589 - rotate: { x: TAU/4, y: slopeAngle }, 1590 - stroke: lineWidth, 1591 - fill: true, 1592 - color: red, 1593 - }); 1594 - 1595 - slope.copy({ 1596 - translate: { x: 5, y: 0 }, 1597 - rotate: { x: -TAU/4, y: -slopeAngle }, 1598 - }); 1599 - 1600 - // tail 1601 - new Zdog.Ellipse({ 1602 - addTo: backGroup, 1603 - diameter: 32, 1604 - quarters: 1, 1605 - closed: false, 1606 - translate: { x: 22, y: -4 }, 1607 - rotate: { z: TAU/4 }, 1608 - color: red, 1609 - stroke: lineWidth, 1610 - }); 1611 - 1612 - // tongue 1613 - 1614 - var tongueAnchor = new Zdog.Anchor({ 1615 - addTo: backGroup, 1616 - translate: { x: -6, y: -7 }, 1617 - rotate: { y: TAU/4 }, 1618 - 1619 - }); 1620 - 1621 - var tongueH = 12; 1622 - var tongueS = 5; 1623 - var tongueTip = tongueH + tongueS; 1624 - 1625 - new Zdog.Shape({ 1626 - addTo: tongueAnchor, 1627 - path: [ 1628 - { x: -tongueS, y: 0 }, 1629 - { x: tongueS, y: 0 }, 1630 - { x: tongueS, y: tongueH }, 1631 - { arc: [ 1632 - { x: tongueS, y: tongueTip }, 1633 - { x: 0, y: tongueTip } 1634 - ]}, 1635 - { arc: [ 1636 - { x: -tongueS, y: tongueTip }, 1637 - { x: -tongueS, y: tongueH } 1638 - ]}, 1639 - ], 1640 - rotate: { x: TAU/4 - Math.atan(16/22) }, 1641 - fill: true, 1642 - stroke: 4, 1643 - color: denim, 1644 - 1645 - }); 1646 - 1647 - var foreGroup = new Zdog.Group({ 1648 - addTo: bigGroup, 1649 - updateSort: true, 1650 - }); 1651 - 1652 - var zFace = new Zdog.Shape({ 1653 - addTo: foreGroup, 1654 - path: [ 1655 - { x: -20, y: -20 }, 1656 - { x: 20, y: -20 }, 1657 - { x: 20, y: -10 }, 1658 - { x: -10, y: 12 }, 1659 - { x: 20, y: 12 }, 1660 - { x: 20, y: 20 }, 1661 - { x: -20, y: 20 }, 1662 - { x: -20, y: 10 }, 1663 - { x: 10, y: -12 }, 1664 - { x: -20, y: -12 }, 1665 - ], 1666 - translate: { z: depth/2 }, 1667 - fill: true, 1668 - color: gold, 1669 - stroke: lineWidth, 1670 - backface: false, 1671 - }); 1672 - 1673 - zFace.copy({ 1674 - scale: { x: -1 }, 1675 - translate: { z: -depth/2 }, 1676 - rotate: { y: TAU/2 }, 1677 - }); 1678 - 1679 - // nose 1680 - var semiCircle = new Zdog.Ellipse({ 1681 - addTo: backGroup, 1682 - quarters: 2, 1683 - scale: 8, 1684 - translate: { x: -26, y: -20 }, 1685 - rotate: { y: TAU/4, z: TAU/4 }, 1686 - fill: true, 1687 - stroke: 5, 1688 - color: denim, 1689 - closed: true, 1690 - // backface: false, 1691 - }); 1692 - 1693 - // ears 1694 - // group & extra shape are hacks 1695 - var earGroup = new Zdog.Group({ 1696 - addTo: illo, 1697 - }); 1698 - 1699 - var ear = semiCircle.copy({ 1700 - addTo: earGroup, 1701 - quarters: 2, 1702 - scale: 24, 1703 - rotate: { z: -TAU/16, x: TAU/16 }, 1704 - translate: { x: 10, y: -14, z: depth }, 1705 - }); 1706 - 1707 - new Zdog.Shape({ 1708 - visible: false, 1709 - addTo: ear, 1710 - translate: { z: 0.5, x: -0.5 }, 1711 - }); 1712 - 1713 - earGroup.copyGraph({ 1714 - scale: { z: -1 }, 1715 - }); 1716 - 1717 - // -- animate --- // 1718 - 1719 - var t = 0; 1720 - var tSpeed = 1/150; 1721 - 1722 - function animate() { 1723 - // update 1724 - if ( isSpinning ) { 1725 - var turn = Math.floor( t % 3 ); 1726 - var easeT = Zdog.easeInOut( t % 1, 4 ); 1727 - if ( turn == 0 ) { 1728 - illo.rotate.y = easeT * TAU + initRotate.y; 1729 - } else if ( turn == 1 ) { 1730 - illo.rotate.z = easeT * TAU; 1731 - } 1732 - t += tSpeed; 1733 - } 1734 - illo.updateGraph(); 1735 - // render 1736 - illo.renderGraph(); 1737 - requestAnimationFrame( animate ); 1738 - } 1739 - 1740 - animate(); 1741 - 1742 - 1743 - 1744 - </script> 1745 - 1746 - </body> 1747 - </html>
-53
demo/rgb-birdie/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>rgb birdie</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #111; 19 - color: white; 20 - font-family: sans-serif; 21 - text-align: center; 22 - } 23 - 24 - .illo { 25 - display: block; 26 - margin: 0px auto 20px; 27 - cursor: move; 28 - } 29 - </style> 30 - 31 - </head> 32 - <body> 33 - 34 - <div class="container"> 35 - <canvas class="illo"></canvas> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/svg-renderer.js"></script> 41 - <script src="../../js/vector.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/path-command.js"></script> 44 - <script src="../../js/shape.js"></script> 45 - <script src="../../js/ellipse.js"></script> 46 - <script src="../../js/rect.js"></script> 47 - <script src="../../js/group.js"></script> 48 - <script src="../../js/dragger.js"></script> 49 - <script src="../../js/illustration.js"></script> 50 - <script src="rgb-birdie.js"></script> 51 - 52 - </body> 53 - </html>
-153
demo/rgb-birdie/rgb-birdie.js
··· 1 - // ------------------------- demo ------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var sceneSize = 270; 5 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 6 - var zoom = Math.floor( minWindowSize / (sceneSize/2) ) / 2; 7 - var illoSize = sceneSize * zoom; 8 - illoElem.setAttribute( 'width', illoSize ); 9 - illoElem.setAttribute( 'height', illoSize ); 10 - var isSpinning = false; 11 - var TAU = Zdog.TAU; 12 - var initialRotate = new Zdog.Vector({ x: -35, y: -45 }).multiply( TAU/360 ); 13 - 14 - var illo = new Zdog.Illustration({ 15 - element: illoElem, 16 - zoom: zoom, 17 - rotate: initialRotate, 18 - dragRotate: true, 19 - onDragStart: function() { 20 - isSpinning = false; 21 - }, 22 - }); 23 - 24 - // ----- model ----- // 25 - 26 - var bird = new Zdog.Anchor({ 27 - addTo: illo, 28 - translate: { z: -20 }, 29 - }); 30 - 31 - var letterGroup = new Zdog.Group({ 32 - addTo: bird, 33 - }); 34 - 35 - var R = new Zdog.Shape({ 36 - addTo: letterGroup, 37 - path: [ 38 - { x: -55, y: -55 }, 39 - { x: 15, y: -55 }, 40 - { arc: [ 41 - { x: 55, y: -55 }, 42 - { x: 55, y: -15 }, 43 - ]}, 44 - { bezier: [ 45 - { x: 55, y: 0 }, 46 - { x: 47, y: 13 }, 47 - { x: 35, y: 20 }, 48 - ]}, 49 - { x: 29, y: 23 }, 50 - { x: 50, y: 55 }, 51 - { x: -55, y: 55 }, 52 - ], 53 - rotate: { x: TAU/4 }, 54 - color: '#F00', 55 - stroke: 10, 56 - fill: true, 57 - }); 58 - 59 - var G = new Zdog.Shape({ 60 - addTo: letterGroup, 61 - path: [ 62 - { x: 0, y: -55 }, 63 - { bezier: [ 64 - { x: 18, y: -55 }, 65 - { x: 32, y: -46 }, 66 - { x: 40, y: -38 }, 67 - ]}, 68 - { x: 7, y: -5 }, 69 - { x: 55, y: -5 }, 70 - { x: 55, y: 53 }, 71 - { x: 35, y: 47 }, 72 - { bezier: [ 73 - { x: 21, y: 52 }, 74 - { x: 10, y: 55 }, 75 - { x: 0, y: 55 }, 76 - ]}, 77 - { arc: [ 78 - { x: -55, y: 55 }, 79 - { x: -55, y: 0 }, 80 - ]}, 81 - { arc: [ 82 - { x: -55, y: -55 }, 83 - { x: 0, y: -55 }, 84 - ]}, 85 - ], 86 - translate: { x: -30, y: 20, z: 33 }, 87 - rotate: { y: TAU/4 }, 88 - color: '#0F0', 89 - stroke: 10, 90 - fill: true, 91 - }); 92 - 93 - var B = new Zdog.Shape({ 94 - addTo: letterGroup, 95 - path: [ 96 - { x: -55, y: -55 }, 97 - { x: 25, y: -55 }, 98 - { arc: [ 99 - { x: 55, y: -55 }, 100 - { x: 55, y: -25 }, 101 - ]}, 102 - { bezier: [ 103 - { x: 55, y: -13 }, 104 - { x: 49, y: -7 }, 105 - { x: 42, y: -4 }, 106 - ]}, 107 - { x: 35, y: 0 }, 108 - { x: 42, y: 4 }, 109 - { bezier: [ 110 - { x: 49, y: 7 }, 111 - { x: 55, y: 13 }, 112 - { x: 55, y: 25 }, 113 - ]}, 114 - { arc: [ 115 - { x: 55, y: 55 }, 116 - { x: 25, y: 55 }, 117 - ]}, 118 - { x: -55, y: 55 }, 119 - ], 120 - translate: { y: -10, z: 60 }, 121 - color: '#00F', 122 - stroke: 10, 123 - fill: true, 124 - }); 125 - 126 - var eye = new Zdog.Shape({ 127 - addTo: bird, 128 - translate: { x: -60, y: -40, z: 30 }, 129 - stroke: 18, 130 - color: '#111', 131 - }); 132 - 133 - // screen blend letters 134 - letterGroup.render = function( ctx ) { 135 - ctx.globalCompositeOperation = 'screen'; 136 - Zdog.Group.prototype.render.apply( this, arguments ); 137 - }; 138 - // normal blend eye 139 - eye.render = function( ctx ) { 140 - ctx.globalCompositeOperation = 'source-over'; 141 - Zdog.Shape.prototype.render.apply( this, arguments ); 142 - }; 143 - 144 - // ----- animate ----- // 145 - 146 - function animate() { 147 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 148 - illo.updateRenderGraph(); 149 - requestAnimationFrame( animate ); 150 - } 151 - 152 - animate(); 153 -
-92
demo/santorini/buildings.js
··· 1 - /* globals makeBuilding */ 2 - 3 - function oneStoryBuilding( options ) { 4 - 5 - var anchor = new Zdog.Anchor({ 6 - addTo: options.addTo, 7 - translate: options.translate, 8 - }); 9 - 10 - var isNS = options.gable == 'ns'; 11 - 12 - var buildOptions = { 13 - width: isNS ? 8 : 10, 14 - height: 8, 15 - depth: isNS ? 10 : 8, 16 - gable: options.gable, 17 - addTo: anchor, 18 - }; 19 - 20 - // single window 21 - buildOptions[ options.gable + 'Windows'] = [ { x: 0 } ]; 22 - // two windows on long side 23 - var oppositeSide = isNS ? 'ew' : 'ns'; 24 - buildOptions[ oppositeSide + 'Windows'] = [ 25 - { x: -2 }, 26 - { x: 2 }, 27 - ]; 28 - 29 - makeBuilding( buildOptions ); 30 - 31 - } 32 - 33 - function twoStoryBuilding( options ) { 34 - 35 - var anchor = new Zdog.Anchor({ 36 - addTo: options.addTo, 37 - translate: options.translate, 38 - }); 39 - 40 - var isNS = options.gable == 'ns'; 41 - 42 - var buildOptions = { 43 - width: isNS ? 8 : 10, 44 - height: 14, 45 - depth: isNS ? 10 : 8, 46 - gable: options.gable, 47 - addTo: anchor, 48 - }; 49 - 50 - // single column 51 - buildOptions[ options.gable + 'Windows'] = [ 52 - { x: 0, y: -5 }, 53 - { x: 0, y: -11 }, 54 - ]; 55 - // two windows on long side 56 - var oppositeSide = isNS ? 'ew' : 'ns'; 57 - buildOptions[ oppositeSide + 'Windows'] = [ 58 - { x: -2, y: -5 }, 59 - { x: 2, y: -5 }, 60 - { x: -2, y: -11 }, 61 - { x: 2, y: -11 }, 62 - ]; 63 - 64 - makeBuilding( buildOptions ); 65 - 66 - } 67 - 68 - 69 - function oneStorySlanter( options ) { 70 - 71 - var anchor = new Zdog.Anchor({ 72 - addTo: options.addTo, 73 - translate: options.translate, 74 - }); 75 - 76 - makeBuilding({ 77 - width: 14, 78 - height: 8, 79 - depth: 6, 80 - gable: options.gable, 81 - addTo: anchor, 82 - nsWindows: [ 83 - { x: -4 }, 84 - { x: 0 }, 85 - { x: 4 }, 86 - ], 87 - ewWindows: [ 88 - { x: 0 } 89 - ], 90 - }); 91 - 92 - }
-61
demo/santorini/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>santorini</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #ACF; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p> 36 - <button class="reset-button">Reset</button> 37 - </p> 38 - </div> 39 - 40 - <script src="../../js/boilerplate.js"></script> 41 - <script src="../../js/canvas-renderer.js"></script> 42 - <script src="../../js/svg-renderer.js"></script> 43 - <script src="../../js/vector.js"></script> 44 - <script src="../../js/path-command.js"></script> 45 - <script src="../../js/anchor.js"></script> 46 - <script src="../../js/shape.js"></script> 47 - <script src="../../js/rect.js"></script> 48 - <script src="../../js/ellipse.js"></script> 49 - <script src="../../js/group.js"></script> 50 - <script src="../../js/hemisphere.js"></script> 51 - <script src="../../js/dragger.js"></script> 52 - <script src="../../js/illustration.js"></script> 53 - <script src="../fps-counter.js"></script> 54 - <script src="make-window.js"></script> 55 - <script src="make-building.js"></script> 56 - <script src="make-rock.js"></script> 57 - <script src="buildings.js"></script> 58 - <script src="santorini.js"></script> 59 - 60 - </body> 61 - </html>
-221
demo/santorini/make-building.js
··· 1 - /* jshint unused: false */ 2 - /* globals makeWindow */ 3 - 4 - // translate 5 - // width, 6 - // height 7 - // depth 8 - // nsWindows: function() {} 9 - // ewWindows: function() {} 10 - // gable: flat, ew, ns, slantS, slandN 11 - 12 - var TAU = Zdog.TAU; 13 - // colors 14 - var white = 'white'; 15 - var southWall = white; 16 - var westWall = '#CDE'; 17 - var eastWall = '#8AD'; 18 - var roof = '#06B'; 19 - var northWall = '#58C'; 20 - var navy = '#037'; 21 - var midnight = '#024'; 22 - 23 - 24 - function makeBuilding( options ) { 25 - 26 - var wallX = options.width/2; 27 - var wallY = options.height; 28 - var wallZ = options.depth/2; 29 - 30 - // south/noth walls 31 - [ true, false ].forEach( function( isSouth ) { 32 - var wallTZ = isSouth ? -wallZ : wallZ; 33 - var wallGroup = new Zdog.Group({ 34 - addTo: options.addTo, 35 - translate: { z: wallTZ }, 36 - }); 37 - 38 - var wallPath = [ 39 - { x: -wallX, y: -wallY } 40 - ]; 41 - 42 - if ( options.gable == 'ns' ) { 43 - wallPath.push({ x: 0, y: -wallY - wallX }); 44 - } else if ( options.gable == 'slantS' && !isSouth ) { 45 - wallPath.push({ x: -wallX, y: -wallY - wallZ*2 }); 46 - wallPath.push({ x: wallX, y: -wallY - wallZ*2 }); 47 - } 48 - 49 - wallPath = wallPath.concat([ 50 - { x: wallX, y: -wallY }, 51 - { x: wallX, y: 0 }, 52 - { x: -wallX, y: 0 }, 53 - ]); 54 - 55 - // wall 56 - new Zdog.Shape({ 57 - path: wallPath, 58 - addTo: wallGroup, 59 - color: isSouth ? southWall : northWall, 60 - }); 61 - 62 - var windowColor = isSouth ? navy : midnight; 63 - handleWindows( options.nsWindows, wallGroup, windowColor ); 64 - 65 - // cap border 66 - if ( options.gable == 'cap' ) { 67 - new Zdog.Rect({ 68 - width: options.width, 69 - height: 2, 70 - addTo: wallGroup, 71 - translate: { y: -wallY - 1 }, 72 - color: isSouth ? roof : midnight, 73 - }); 74 - } 75 - 76 - }); 77 - 78 - // east/west wall 79 - [ true, false ].forEach( function( isWest ) { 80 - var wallGroup = new Zdog.Group({ 81 - addTo: options.addTo, 82 - translate: { x: isWest ? -wallX : wallX }, 83 - rotate: { y: TAU/4 }, 84 - }); 85 - 86 - var wallPath = [ 87 - { x: -wallZ, y: -wallY } 88 - ]; 89 - 90 - if ( options.gable == 'ew' ) { 91 - wallPath.push({ x: 0, y: -wallY - wallZ }); 92 - } else if ( options.gable == 'slantS' ) { 93 - wallPath.push({ x: wallZ, y: -wallY - wallZ*2 }); 94 - } 95 - 96 - wallPath = wallPath.concat([ 97 - { x: wallZ, y: -wallY }, 98 - { x: wallZ, y: 0 }, 99 - { x: -wallZ, y: 0 }, 100 - ]); 101 - 102 - // wall 103 - new Zdog.Shape({ 104 - path: wallPath, 105 - addTo: wallGroup, 106 - color: isWest ? westWall : eastWall, 107 - }); 108 - 109 - var windowColor = isWest ? navy : midnight; 110 - handleWindows( options.ewWindows, wallGroup, windowColor ); 111 - 112 - // cap border 113 - if ( options.gable == 'cap' ) { 114 - new Zdog.Rect({ 115 - width: options.depth, 116 - height: 2, 117 - addTo: wallGroup, 118 - translate: { y: -wallY - 1 }, 119 - color: isWest ? roof : midnight, 120 - }); 121 - } 122 - 123 - }); 124 - 125 - 126 - var roofMakers = { 127 - ns: function() { 128 - var y0 = -wallY - wallX; 129 - var roofPanel = new Zdog.Shape({ 130 - path: [ 131 - { x: 0, y: y0, z: -wallZ }, 132 - { x: 0, y: y0, z: wallZ }, 133 - { x: wallX, y: -wallY, z: wallZ }, 134 - { x: wallX, y: -wallY, z: -wallZ }, 135 - ], 136 - addTo: options.addTo, 137 - color: roof, 138 - }); 139 - roofPanel.copy({ 140 - scale: { x: -1 }, 141 - }); 142 - }, 143 - 144 - ew: function() { 145 - var y0 = -wallY - wallZ; 146 - var roofPanel = new Zdog.Shape({ 147 - path: [ 148 - { z: 0, y: y0, x: -wallX }, 149 - { z: 0, y: y0, x: wallX }, 150 - { z: wallZ, y: -wallY, x: wallX }, 151 - { z: wallZ, y: -wallY, x: -wallX }, 152 - ], 153 - addTo: options.addTo, 154 - color: roof, 155 - }); 156 - roofPanel.copy({ 157 - scale: { z: -1 }, 158 - }); 159 - }, 160 - 161 - slantS: function() { 162 - var roofY0 = -wallY; 163 - var roofY1 = -wallY - wallZ*2; 164 - new Zdog.Shape({ 165 - path: [ 166 - { x: -wallX, y: roofY0, z: -wallZ }, 167 - { x: wallX, y: roofY0, z: -wallZ }, 168 - { x: wallX, y: roofY1, z: wallZ }, 169 - { x: -wallX, y: roofY1, z: wallZ }, 170 - ], 171 - addTo: options.addTo, 172 - color: roof, 173 - }); 174 - }, 175 - 176 - flat: function() { 177 - new Zdog.Rect({ 178 - width: options.width, 179 - height: options.depth, 180 - addTo: options.addTo, 181 - translate: { y: -wallY }, 182 - rotate: { x: TAU/4 }, 183 - color: roof, 184 - }); 185 - }, 186 - 187 - cap: function() { 188 - new Zdog.Rect({ 189 - width: options.width, 190 - height: options.depth, 191 - addTo: options.addTo, 192 - translate: { y: -wallY - 2 }, 193 - rotate: { x: TAU/4 }, 194 - color: roof, 195 - }); 196 - }, 197 - }; 198 - 199 - var roofMaker = roofMakers[ options.gable ]; 200 - if ( roofMaker ) { 201 - roofMaker(); 202 - } 203 - 204 - } 205 - 206 - 207 - function handleWindows( windows, wallGroup, color ) { 208 - windows = windows || []; 209 - windows.forEach( function( windowOption ) { 210 - var x = windowOption.x || 0; 211 - var y = windowOption.y || -5; 212 - var height = windowOption.height || 4; 213 - makeWindow({ 214 - style: windowOption.style, 215 - addTo: wallGroup, 216 - height: height, 217 - translate: { x: x, y: y }, 218 - color: color, 219 - }); 220 - }); 221 - }
-83
demo/santorini/make-rock.js
··· 1 - /* globals midnight */ 2 - 3 - // width 4 - // depth 5 - // height 6 - // translate 7 - // eastOffset 8 - // westOffset 9 - // northOffset 10 - // southOffset 11 - 12 - function makeRock( options ) { 13 - 14 - var x = options.width/2; 15 - var z = options.depth/2; 16 - var y = -options.height; 17 - var bottomWestNorth = { x: -x, y: 0, z: z }; 18 - var bottomEastNorth = { x: x, y: 0, z: z }; 19 - var bottomEastSouth = { x: x, y: 0, z: -z }; 20 - var bottomWestSouth = { x: -x, y: 0, z: -z }; 21 - 22 - var topWestX = x + ( options.westOffset || 0 ); 23 - var topEastX = x + ( options.eastOffset || 0 ); 24 - var topNorthZ = z + ( options.northOffset || 0 ); 25 - var topSouthZ = z + ( options.southOffset || 0 ); 26 - 27 - var topWestNorth = { x: -topWestX, y: y, z: topNorthZ }; 28 - var topEastNorth = { x: topEastX, y: y, z: topNorthZ }; 29 - var topEastSouth = { x: topEastX, y: y, z: -topSouthZ }; 30 - var topWestSouth = { x: -topWestX, y: y, z: -topSouthZ }; 31 - 32 - var anchor = new Zdog.Anchor({ 33 - addTo: options.addTo, 34 - translate: options.translate, 35 - }); 36 - 37 - function makeRockFace( path ) { 38 - new Zdog.Shape({ 39 - path: path, 40 - addTo: anchor, 41 - color: midnight, 42 - stroke: 2, 43 - }); 44 - } 45 - 46 - // north face 47 - makeRockFace([ 48 - topWestNorth, 49 - topEastNorth, 50 - bottomEastNorth, 51 - bottomWestNorth, 52 - ]); 53 - // south face 54 - makeRockFace([ 55 - topWestSouth, 56 - topEastSouth, 57 - bottomEastSouth, 58 - bottomWestSouth, 59 - ]); 60 - // west face 61 - makeRockFace([ 62 - topWestSouth, 63 - topWestNorth, 64 - bottomWestNorth, 65 - bottomWestSouth, 66 - ]); 67 - 68 - // east face 69 - makeRockFace([ 70 - topEastSouth, 71 - topEastNorth, 72 - bottomEastNorth, 73 - bottomEastSouth, 74 - ]); 75 - // top face 76 - makeRockFace([ 77 - topWestNorth, 78 - topEastNorth, 79 - topEastSouth, 80 - topWestSouth, 81 - ]); 82 - 83 - }
-37
demo/santorini/make-window.js
··· 1 - /*jshint unused: false */ 2 - 3 - function makeWindow( options ) { 4 - if ( options.style == 'circle' ) { 5 - makeCircleWindow( options ); 6 - } else { 7 - makeLongWindow( options ); 8 - } 9 - } 10 - 11 - function makeCircleWindow( options ) { 12 - new Zdog.Ellipse( Zdog.extend( options, { 13 - diameter: 2, 14 - })); 15 - } 16 - 17 - function makeLongWindow( options ) { 18 - var y2 = options.height - 1; 19 - 20 - var windowShape = new Zdog.Shape( Zdog.extend( options, { 21 - path: [ 22 - { x: -1, y: 0 }, 23 - { arc: [ 24 - { x: -1, y: -1 }, 25 - { x: 0, y: -1 }, 26 - ]}, 27 - { arc: [ 28 - { x: 1, y: -1 }, 29 - { x: 1, y: 0 }, 30 - ]}, 31 - { x: 1, y: y2 }, 32 - { x: -1, y: y2 }, 33 - ], 34 - })); 35 - 36 - return windowShape; 37 - }
-560
demo/santorini/santorini.js
··· 1 - /* globals makeBuilding, oneStoryBuilding, twoStoryBuilding, oneStorySlanter, makeRock */ 2 - 3 - // -------------------------- demo -------------------------- // 4 - 5 - var illoElem = document.querySelector('.illo'); 6 - var w = 192; 7 - var h = 164; 8 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 9 - var zoom = Math.min( 7, Math.floor( minWindowSize / w ) ); 10 - var zoom = 5; 11 - illoElem.setAttribute( 'width', w * zoom ); 12 - illoElem.setAttribute( 'height', h * zoom ); 13 - var isSpinning = false; 14 - var TAU = Zdog.TAU; 15 - var initRotate = { y: TAU/8 }; 16 - 17 - var illo = new Zdog.Illustration({ 18 - element: illoElem, 19 - zoom: zoom, 20 - rotate: initRotate, 21 - dragRotate: true, 22 - onDragStart: function() { 23 - isSpinning = false; 24 - }, 25 - }); 26 - 27 - // colors 28 - // var white = 'white'; 29 - // var southWall = white; 30 - // var westWall = '#CDE'; 31 - // var eastWall = '#8AD'; 32 - var roof = '#06B'; 33 - // var northWall = roof; 34 - // var navy = '#037'; 35 - // var midnight = '#024'; 36 - 37 - // default to flat, filled shapes 38 - [ Zdog.Shape, Zdog.Rect, Zdog.Ellipse ].forEach( function( ItemClass ) { 39 - ItemClass.defaults.fill = true; 40 - ItemClass.defaults.stroke = false; 41 - }); 42 - 43 - var island = new Zdog.Anchor({ 44 - addTo: illo, 45 - scale: { x: 1/Math.sin(TAU/8), z: -1/Math.sin(TAU/8) } 46 - }); 47 - 48 - // -- illustration shapes --- // 49 - 50 - // lil house in front, center 51 - oneStoryBuilding({ 52 - addTo: island, 53 - translate: { x: 17, z: -24 }, 54 - gable: 'ns' 55 - }); 56 - 57 - // lil house to the east 58 - oneStoryBuilding({ 59 - addTo: island, 60 - translate: { x: 47, z: -16 }, 61 - gable: 'ns' 62 - }); 63 - 64 - // 2 story gable, east end 65 - twoStoryBuilding({ 66 - addTo: island, 67 - translate: { x: 55, z: -4 }, 68 - gable: 'ns' 69 - }); 70 - 71 - // 2 story gable, center west 72 - twoStoryBuilding({ 73 - addTo: island, 74 - translate: { x: 14, y: -2, z: -13 }, 75 - gable: 'ew', 76 - }); 77 - 78 - 79 - // 2 story gable, west end 80 - twoStoryBuilding({ 81 - addTo: island, 82 - translate: { x: -14, z: -25 }, 83 - gable: 'ew', 84 - }); 85 - 86 - 87 - // 1 story slantS, west 88 - oneStorySlanter({ 89 - addTo: island, 90 - translate: { x: 0, z: -26 }, 91 - gable: 'slantS', 92 - }); 93 - 94 - 95 - 96 - // ----- ----- // 97 - 98 - // 2.5 story slantS, east 99 - var buildAnchor4 = new Zdog.Anchor({ 100 - addTo: island, 101 - translate: { x: 42, z: -6 }, 102 - }); 103 - 104 - makeBuilding({ 105 - width: 14, 106 - height: 20, 107 - depth: 6, 108 - gable: 'slantS', 109 - addTo: buildAnchor4, 110 - nsWindows: [ 111 - { x: -4, y: -17 }, 112 - { x: 0, y: -17 }, 113 - { x: 4, y: -17 }, 114 - ], 115 - ewWindows: [ 116 - { x: 0, y: -17 } 117 - ], 118 - }); 119 - 120 - // ----- cathedral ----- // 121 - 122 - var cathBaseAnchor = new Zdog.Anchor({ 123 - addTo: island, 124 - translate: { x: 28, z: -12 }, 125 - }); 126 - 127 - // cathedral base 128 - makeBuilding({ 129 - width: 10, 130 - height: 12, 131 - depth: 18, 132 - gable: 'cap', 133 - addTo: cathBaseAnchor, 134 - nsWindows: [ 135 - { x: -2, y: -3 }, 136 - { x: 2, y: -3 }, 137 - { x: -2, y: -9 }, 138 - { x: 2, y: -9 }, 139 - ], 140 - ewWindows: [ 141 - { style: 'circle', x: -6, y: -9 }, 142 - { style: 'circle', x: -2, y: -9 }, 143 - { style: 'circle', x: 2, y: -9 }, 144 - { style: 'circle', x: 6, y: -9 }, 145 - { height: 6, x: -6, y: -5 }, 146 - { height: 6, x: -2, y: -5 }, 147 - { height: 6, x: 2, y: -5 }, 148 - { height: 6, x: 6, y: -5 }, 149 - ], 150 - }); 151 - 152 - // cathedral 2nd story 153 - var cath2ndAnchor = new Zdog.Anchor({ 154 - addTo: cathBaseAnchor, 155 - translate: { y: -14 }, 156 - }); 157 - 158 - makeBuilding({ 159 - width: 8, 160 - height: 8, 161 - depth: 8, 162 - gable: 'cap', 163 - addTo: cath2ndAnchor, 164 - nsWindows: [ 165 - { x: 0, y: -5 }, 166 - ], 167 - ewWindows: [ 168 - { x: 0, y: -5 }, 169 - ], 170 - }); 171 - 172 - // cathedral 3rd story 173 - 174 - var cath3rdAnchor = new Zdog.Anchor({ 175 - addTo: cathBaseAnchor, 176 - translate: { y: -24 }, 177 - }); 178 - 179 - makeBuilding({ 180 - width: 6, 181 - height: 6, 182 - depth: 6, 183 - addTo: cath3rdAnchor, 184 - gable: 'flat', 185 - nsWindows: [ 186 - { x: 0, y: -3 }, 187 - ], 188 - ewWindows: [ 189 - { x: 0, y: -3 }, 190 - ], 191 - }); 192 - 193 - // cathedral dome 194 - var dome = new Zdog.Hemisphere({ 195 - addTo: cathBaseAnchor, 196 - diameter: 6, 197 - translate: { y: -30 }, 198 - rotate: { x: TAU/4 }, 199 - color: roof, 200 - stroke: false, 201 - }); 202 - 203 - // ----- ----- // 204 - 205 - // 2 story gable, east, behind cathdral on hill 206 - var anchor6 = new Zdog.Anchor({ 207 - addTo: island, 208 - translate: { x: 27, z: 6, y: -14 }, 209 - }); 210 - 211 - makeBuilding({ 212 - width: 8, 213 - height: 16, 214 - depth: 10, 215 - gable: 'ns', 216 - addTo: anchor6, 217 - nsWindows: [ 218 - { style: 'circle', x: 0, y: -13 }, 219 - ], 220 - ewWindows: [ 221 - { style: 'circle', x: -2, y: -7 }, 222 - { style: 'circle', x: 2, y: -7 }, 223 - { x: -2, y: -13 }, 224 - { x: 2, y: -13 }, 225 - ], 226 - }); 227 - 228 - // ----- west side ----- // 229 - 230 - 231 - // shack, west end 232 - var anchor9 = new Zdog.Anchor({ 233 - addTo: island, 234 - translate: { x: -13, z: -34 }, 235 - }); 236 - 237 - makeBuilding({ 238 - width: 8, 239 - height: 8, 240 - depth: 6, 241 - gable: 'ns', 242 - addTo: anchor9, 243 - nsWindows: [ 244 - { x: 0, y: -5 }, 245 - ], 246 - ewWindows: [ 247 - { style: 'circle' }, 248 - ], 249 - }); 250 - 251 - // 2 story, west center, 1st hill 252 - var anchor10 = new Zdog.Anchor({ 253 - addTo: island, 254 - translate: { x: 3, z: -10, y: -8 }, 255 - }); 256 - 257 - makeBuilding({ 258 - width: 8, 259 - height: 16, 260 - depth: 10, 261 - gable: 'ns', 262 - addTo: anchor10, 263 - nsWindows: [ 264 - { x: 0, y: -13 }, 265 - ], 266 - ewWindows: [ 267 - { x: -2, y: -13 }, 268 - { x: 2, y: -13 }, 269 - { x: -2, y: -5 }, 270 - { x: 2, y: -5 }, 271 - ], 272 - }); 273 - 274 - // west mansion 275 - var mansionAnchor = new Zdog.Anchor({ 276 - addTo: island, 277 - translate: { x: -14, z: -14, y: -8 }, 278 - }); 279 - 280 - makeBuilding({ 281 - width: 14, 282 - height: 18, 283 - depth: 10, 284 - gable: 'cap', 285 - addTo: mansionAnchor, 286 - nsWindows: [ 287 - { x: -4, y: -15, style: 'circle' }, 288 - { x: 0, y: -15, style: 'circle' }, 289 - { x: 4, y: -15, style: 'circle' }, 290 - { x: -4, y: -11, height: 10 }, 291 - { x: 0, y: -11, height: 10 }, 292 - { x: 4, y: -11, height: 10 }, 293 - ], 294 - ewWindows: [ 295 - { x: -2, y: -15 }, 296 - { x: 2, y: -15 }, 297 - { x: -2, y: -9, height: 8 }, 298 - { x: 2, y: -9, height: 8 }, 299 - ], 300 - }); 301 - 302 - // mansion rock 303 - makeRock({ 304 - width: 19, 305 - depth: 14, 306 - height: 8, 307 - addTo: island, 308 - translate: { x: -13, z: -14, y: 1 }, 309 - southOffset: -2, 310 - }); 311 - 312 - // ----- central tower ----- // 313 - 314 - var centralTowerAnchor = new Zdog.Anchor({ 315 - addTo: island, 316 - translate: { y: -14 }, 317 - }); 318 - 319 - makeBuilding({ 320 - width: 6, 321 - depth: 6, 322 - height: 18, 323 - addTo: centralTowerAnchor, 324 - gable: 'cap', 325 - nsWindows: [ 326 - { x: 0, y: -7, style: 'circle' } 327 - ], 328 - ewWindows: [ 329 - { x: 0, y: -13, style: 'circle' } 330 - ], 331 - }); 332 - 333 - // central tower 2nd story 334 - var centralTower2ndAnchor = new Zdog.Anchor({ 335 - addTo: centralTowerAnchor, 336 - translate: { y: -20 }, 337 - }); 338 - 339 - makeBuilding({ 340 - width: 6, 341 - depth: 6, 342 - height: 8, 343 - addTo: centralTower2ndAnchor, 344 - gable: 'flat', 345 - nsWindows: [ 346 - { x: 0, y: -5 } 347 - ], 348 - ewWindows: [ 349 - { x: 0, y: -5 } 350 - ], 351 - }); 352 - 353 - dome.copy({ 354 - diameter: 4, 355 - addTo: centralTower2ndAnchor, 356 - translate: { y: -8 }, 357 - }); 358 - 359 - // ----- temple ----- // 360 - 361 - var templeAnchor = new Zdog.Anchor({ 362 - addTo: island, 363 - translate: { x: -20, y: -14, z: 1 }, 364 - }); 365 - 366 - makeBuilding({ 367 - width: 12, 368 - depth: 12, 369 - height: 8, 370 - gable: 'cap', 371 - addTo: templeAnchor, 372 - nsWindows:[ 373 - { x: -2, height: 6 }, 374 - { x: 2, height: 6 }, 375 - ], 376 - ewWindows:[ 377 - { x: -2, height: 6 }, 378 - { x: 2, height: 6 }, 379 - ], 380 - }); 381 - 382 - var temple2ndFloor = new Zdog.Anchor({ 383 - addTo: templeAnchor, 384 - translate: { y: -10 }, 385 - }); 386 - 387 - makeBuilding({ 388 - width: 8, 389 - depth: 8, 390 - height: 8, 391 - gable: 'cap', 392 - addTo: temple2ndFloor, 393 - nsWindows:[ 394 - { height: 6 }, 395 - ], 396 - ewWindows:[ 397 - { height: 6 }, 398 - ], 399 - }); 400 - 401 - var temple3rdFloor = new Zdog.Anchor({ 402 - addTo: temple2ndFloor, 403 - translate: { y: -10 }, 404 - }); 405 - 406 - makeBuilding({ 407 - width: 6, 408 - depth: 6, 409 - height: 6, 410 - gable: 'flat', 411 - addTo: temple3rdFloor, 412 - nsWindows:[ 413 - { y: -3 }, 414 - ], 415 - ewWindows:[ 416 - { y: -3 }, 417 - ], 418 - }); 419 - 420 - dome.copy({ 421 - diameter: 4, 422 - addTo: temple3rdFloor, 423 - translate: { y: -6 }, 424 - }); 425 - 426 - // ----- west perch ----- // 427 - 428 - var westPerchAnchor = new Zdog.Anchor({ 429 - addTo: island, 430 - translate: { x: -39, z: 11, y: -44 } 431 - }); 432 - 433 - makeBuilding({ 434 - width: 6, 435 - depth: 6, 436 - height: 6, 437 - gable: 'flat', 438 - addTo: westPerchAnchor, 439 - nsWindows:[ 440 - { y: -3, style: 'circle', }, 441 - ], 442 - ewWindows:[ 443 - { y: -3, style: 'circle', }, 444 - ], 445 - }); 446 - 447 - dome.copy({ 448 - diameter: 6, 449 - addTo: westPerchAnchor, 450 - translate: { y: -6 }, 451 - }); 452 - 453 - // perch rock 454 - makeRock({ 455 - width: 19, 456 - depth: 9, 457 - height: 10, 458 - addTo: island, 459 - translate: { x: -36, z: 13, y: -33 }, 460 - westOffset: -1, 461 - eastOffset: -7, 462 - northOffset: -3, 463 - southOffset: 0, 464 - }); 465 - 466 - // beneath perch rock & 2 story 467 - 468 - makeRock({ 469 - width: 24, 470 - depth: 22, 471 - height: 8, 472 - addTo: island, 473 - translate: { x: -35, z: 19, y: -25 }, 474 - westOffset: -1.5, 475 - eastOffset: -3, 476 - northOffset: -2, 477 - // southOffset: 0, 478 - }); 479 - 480 - // perch staircase 481 - 482 - var staircaseAnchor = new Zdog.Shape({ 483 - addTo: island, 484 - visible: false, 485 - translate: { x: -35, y: -14, z: 5 }, 486 - }); 487 - 488 - makeBuilding({ 489 - width: 6, 490 - depth: 4, 491 - height: 22, 492 - gable: 'slantS', 493 - addTo: staircaseAnchor, 494 - nsWindows: [ 495 - { y: -19 }, 496 - { y: -12 }, 497 - { y: -5 }, 498 - ] 499 - }); 500 - 501 - // ----- hill buildings ----- // 502 - 503 - // center behind cathedral 504 - oneStorySlanter({ 505 - addTo: island, 506 - translate: { x: -14, y: -26, z: 18 }, 507 - gable: 'slantS', 508 - }); 509 - 510 - // behind west perch 511 - twoStoryBuilding({ 512 - addTo: island, 513 - translate: { x: -38, y: -34, z: 23 }, 514 - gable: 'ns', 515 - }); 516 - 517 - oneStoryBuilding({ 518 - addTo: island, 519 - translate: { x: 9, y: -32, z: 24 }, 520 - gable: 'ew', 521 - }); 522 - 523 - // ----- back tower ----- // 524 - 525 - var backTowerAnchor = new Zdog.Anchor({ 526 - addTo: island, 527 - translate: { x: -15, y: -18, z: 35 } 528 - }); 529 - 530 - makeBuilding({ 531 - width: 6, 532 - height: 30, 533 - depth: 6, 534 - gable: 'flat', 535 - addTo: backTowerAnchor, 536 - nsWindows: [ { y: -27 } ], 537 - ewWindows: [ { y: -27 } ], 538 - }); 539 - 540 - dome.copy({ 541 - addTo: backTowerAnchor, 542 - translate: { y: -30 }, 543 - diameter: 4, 544 - }); 545 - 546 - // -- animate --- // 547 - 548 - function animate() { 549 - illo.rotate.y += isSpinning ? TAU/150 : 0; 550 - illo.updateRenderGraph(); 551 - requestAnimationFrame( animate ); 552 - } 553 - 554 - animate(); 555 - 556 - // ----- inputs ----- // 557 - 558 - document.querySelector('.reset-button').onclick = function() { 559 - illo.rotate.set( initRotate ); 560 - };
-52
demo/sauropod/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>sauropod</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - font-family: sans-serif; 19 - text-align: center; 20 - } 21 - 22 - .illo { 23 - display: block; 24 - margin: 0px auto 20px; 25 - cursor: move; 26 - } 27 - </style> 28 - 29 - </head> 30 - <body> 31 - 32 - <div class="container"> 33 - <canvas class="illo"></canvas> 34 - <p>Click &amp; drag to rotate</p> 35 - <p> 36 - <button class="reset-button">Reset</button> 37 - <button class="rotate-button">Rotate</button> 38 - </p> 39 - </div> 40 - 41 - <script src="../../js/boilerplate.js"></script> 42 - <script src="../../js/canvas-renderer.js"></script> 43 - <script src="../../js/vector.js"></script> 44 - <script src="../../js/path-command.js"></script> 45 - <script src="../../js/anchor.js"></script> 46 - <script src="../../js/shape.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="sauropod.js"></script> 50 - 51 - </body> 52 - </html>
-221
demo/sauropod/sauropod.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 104; 5 - var h = 104; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 5, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - var isSpinning = true; 11 - var TAU = Zdog.TAU; 12 - // ratio to make things look square when rotated a quarter 13 - var antiTwist = 1 / Math.cos( TAU/8 ); 14 - // colors 15 - var blue = '#19F'; 16 - 17 - var initialRotate = { y: TAU/8 }; 18 - 19 - var illo = new Zdog.Illustration({ 20 - element: illoElem, 21 - zoom: zoom, 22 - scale: { x: antiTwist, z: antiTwist }, 23 - rotate: initialRotate, 24 - dragRotate: true, 25 - onDragStart: function() { 26 - isSpinning = false; 27 - }, 28 - }); 29 - 30 - // -- illustration shapes --- // 31 - 32 - // front right leg 33 - var leg = new Zdog.Shape({ 34 - path: [ 35 - { x: -8, y: 0 }, 36 - { arc: [ 37 - { x: 0, y: 0 }, 38 - { x: 0, y: 8 } 39 - ]}, 40 - { arc: [ 41 - { z: 0, y: 0 }, 42 - { z: -8, y: 0 } 43 - ]}, 44 - { move: { y: -4 } }, 45 - { line: { y: 12 } }, 46 - ], 47 - addTo: illo, 48 - translate: { x: 16, y: 16, z: 8 }, 49 - stroke: 8, 50 - color: blue, 51 - closed: false, 52 - }); 53 - // front left leg 54 - leg.copy({ 55 - translate: { x: 16, y: 16, z: -8 }, 56 - rotate: { y: -TAU/4 }, 57 - }); 58 - // back right leg 59 - leg.copy({ 60 - translate: { x: -16, y: 16, z: 8 }, 61 - rotate: { y: TAU/4 }, 62 - }); 63 - // back left leg 64 - leg.copy({ 65 - translate: { x: -16, y: 16, z: -8 }, 66 - rotate: { y: -TAU/2 }, 67 - }); 68 - 69 - 70 - // leg connectors 71 - var legConnector = new Zdog.Shape({ 72 - path: [ { x: -8 }, { x: 8 } ], 73 - addTo: illo, 74 - translate: { y: 16, z: 8 }, 75 - stroke: 8, 76 - color: blue, 77 - closed: false, 78 - }); 79 - legConnector.copy({ 80 - translate: { y: 16, z: -8 }, 81 - }); 82 - 83 - // body 84 - new Zdog.Shape({ 85 - path: [ 86 - { x: -1, z: 1 }, 87 - { x: 1, z: 1 }, 88 - { x: 1, z: -1 }, 89 - { x: -1, z: -1 }, 90 - ], 91 - // fudge these numbers 92 - scale: { x: 14.25, z: -3.75 }, 93 - addTo: illo, 94 - translate: { y: 10 }, 95 - stroke: 20, 96 - color: blue, 97 - }); 98 - 99 - // neck squiggle 100 - new Zdog.Shape({ 101 - path: [ 102 - { x: 16, y: 4 }, 103 - { arc: [ 104 - { x: 24, y: 4 }, 105 - { x: 24, y: -4 } 106 - ]}, 107 - { arc: [ 108 - { x: 24, y: -12 }, 109 - { x: 16, y: -12 } 110 - ]}, 111 - { x: -16, y: -12 }, 112 - { arc: [ 113 - { x: -24, y: -12 }, 114 - { x: -24, y: -20 } 115 - ]}, 116 - { arc: [ 117 - { x: -24, y: -28 }, 118 - { x: -16, y: -28 } 119 - ]}, 120 - { x: 24, y: -28 }, 121 - ], 122 - addTo: illo, 123 - stroke: 8, 124 - color: blue, 125 - closed: false, 126 - }); 127 - 128 - // neck 129 - new Zdog.Shape({ 130 - path: [ 131 - { x: -16, y: -28 }, 132 - { x: 24, y: -28 }, 133 - ], 134 - addTo: illo, 135 - stroke: 8, 136 - color: blue, 137 - closed: false, 138 - }); 139 - 140 - // head ball 141 - var head = new Zdog.Shape({ 142 - translate: { x: 16, y: -31 }, 143 - addTo: illo, 144 - stroke: 14, 145 - color: blue, 146 - }); 147 - 148 - // eyes 149 - var eye = new Zdog.Shape({ 150 - addTo: head, 151 - translate: { z: -1, x: 0 }, 152 - color: 'white', 153 - stroke: 4, 154 - fill: true, 155 - closed: false, 156 - }); 157 - eye.copy({ 158 - translate: { z: 1, x: 0 }, 159 - }); 160 - 161 - // tail 162 - new Zdog.Shape({ 163 - path: [ 164 - { x: -16, z: 0 }, 165 - { arc: [ 166 - { x: -24, z: 0 }, 167 - { x: -24, z: -8 }, 168 - ]}, 169 - { arc: [ 170 - { x: -24, z: -16 }, 171 - { x: -16, z: -16 }, 172 - ]}, 173 - { x: -12, z: -16 }, 174 - { arc: [ 175 - { x: -6, z: -16 }, 176 - { x: -6, z: -22 }, 177 - ]}, 178 - { arc: [ 179 - { x: -6, z: -28 }, 180 - { x: -12, z: -28 }, 181 - ]}, 182 - { x: -18, z: -28 }, 183 - ], 184 - addTo: illo, 185 - translate: { y: 4 }, 186 - // rotate: { x: -0.25 }, 187 - color: blue, 188 - stroke: 8, 189 - closed: false, 190 - }); 191 - 192 - // -- animate --- // 193 - 194 - var t = 0; 195 - 196 - function animate() { 197 - // update 198 - if ( isSpinning ) { 199 - var easeT = Zdog.easeInOut( t % 1, 3 ); 200 - illo.rotate.y = easeT*-TAU + TAU/8; 201 - illo.rotate.x = ( Math.cos( easeT * TAU ) * 0.5 + -0.5 ) * TAU/12; 202 - t += 1/210; 203 - } 204 - illo.updateRenderGraph(); 205 - requestAnimationFrame( animate ); 206 - } 207 - 208 - animate(); 209 - 210 - // ----- inputs ----- // 211 - 212 - document.querySelector('.reset-button').onclick = function() { 213 - illo.rotate.set( initialRotate ); 214 - isSpinning = false; 215 - }; 216 - 217 - document.querySelector('.rotate-button').onclick = function() { 218 - isSpinning = true; 219 - t = 0; 220 - }; 221 -
-51
demo/shade-and-shades/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>shade &amp; shades</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #FFF; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - <p><button class="reset-button">Reset</button></p> 37 - </div> 38 - 39 - <script src="../../js/boilerplate.js"></script> 40 - <script src="../../js/canvas-renderer.js"></script> 41 - <script src="../../js/vector.js"></script> 42 - <script src="../../js/path-command.js"></script> 43 - <script src="../../js/anchor.js"></script> 44 - <script src="../../js/shape.js"></script> 45 - <script src="../../js/ellipse.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/illustration.js"></script> 48 - <script src="shade-and-shades.js"></script> 49 - 50 - </body> 51 - </html>
-245
demo/shade-and-shades/shade-and-shades.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 96; 5 - var h = 96; 6 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight ); 7 - var zoom = Math.min( 8, Math.floor( minWindowSize / w ) ); 8 - illoElem.setAttribute( 'width', w * zoom ); 9 - illoElem.setAttribute( 'height', h * zoom ); 10 - 11 - var illo = new Zdog.Illustration({ 12 - element: illoElem, 13 - zoom: zoom, 14 - }); 15 - 16 - Zdog.Shape.defaults.closed = false; 17 - Zdog.Shape.defaults.stroke = 3; 18 - Zdog.Ellipse.defaults.stroke = 3; 19 - 20 - var TAU = Zdog.TAU; 21 - var quarterView = 1/Math.sin(TAU/8); 22 - var isRotateXFlat; 23 - var isSpinning = true; 24 - 25 - var illo = new Zdog.Illustration({ 26 - element: illoElem, 27 - zoom: zoom, 28 - onDragStart: function() { 29 - isSpinning = false; 30 - } 31 - }); 32 - 33 - var initialHatRotate = { y: -TAU/8 }; 34 - 35 - var hat = new Zdog.Anchor({ 36 - addTo: illo, 37 - rotate: initialHatRotate, 38 - }); 39 - 40 - illo.setDragRotate( hat ); 41 - 42 - // -- illustration shapes --- // 43 - 44 - // cap top 45 - var capTop = new Zdog.Shape({ 46 - path: [ 47 - { x: -20, y: 4 }, 48 - { x: -20, y: 0 }, 49 - { arc: [ 50 - { x: -20, y: -20 }, 51 - { x: 0, y: -20 }, 52 - ]}, 53 - { arc: [ 54 - { x: 20, y: -20 }, 55 - { x: 20, y: 0 }, 56 - ]}, 57 - { x: 20, y: 4 }, 58 - ], 59 - addTo: illo, 60 - }); 61 - 62 - // cap back 63 - new Zdog.Ellipse({ 64 - addTo: hat, 65 - diameter: 40, 66 - quarters: 2, 67 - translate: { y: 4 }, 68 - rotate: { x: TAU/4, z: -TAU/4 }, 69 - }); 70 - 71 - // brim back arch 72 - new Zdog.Ellipse({ 73 - addTo: hat, 74 - diameter: 32, 75 - quarters: 2, 76 - translate: { y: 4, z: 12 }, 77 - rotate: { z: -TAU/4 }, 78 - }); 79 - 80 - // cap back to brim bottom connect 81 - var brimConnector = new Zdog.Shape({ 82 - path: [ 83 - { x: -20, z: 0 }, 84 - { arc: [ 85 - { x: -20, z: 6 }, 86 - { x: -16, z: 12 }, 87 - ]}, 88 - ], 89 - addTo: hat, 90 - translate: { y: 4 }, 91 - }); 92 - 93 - brimConnector.copy({ 94 - scale: { x: -1 }, 95 - }); 96 - 97 - var brimTip = { x: 0, y: -12, z: 38 }; 98 - 99 - new Zdog.Shape({ 100 - path: [ 101 - { x: 0, y: -12, z: 12 }, 102 - brimTip, 103 - ], 104 - addTo: hat, 105 - }); 106 - 107 - var brimBridge = new Zdog.Shape({ 108 - path: [ 109 - { x: -16, y: 4, z: 12 }, 110 - { x: -16, y: 4, z: 22 }, 111 - { bezier: [ 112 - { x: -16, y: 4, z: 34 }, 113 - { x: -14, y: -12, z: 38 }, 114 - brimTip 115 - ]}, 116 - ], 117 - addTo: hat, 118 - }); 119 - brimBridge.copy({ 120 - scale: { x: - 1}, 121 - }); 122 - 123 - // glasses front top 124 - 125 - new Zdog.Shape({ 126 - path: [ 127 - { x: -1 }, 128 - { x: 1 }, 129 - ], 130 - addTo: hat, 131 - translate: { y: 8, z: 12 }, 132 - scale: { x: 16 }, 133 - }); 134 - 135 - // glass lens 136 - var lensScale = (quarterView - 1) * 0.75 + 1; 137 - var glassLens = new Zdog.Shape({ 138 - path: [ 139 - { x: 0, y: -3 }, 140 - { x: 0, y: 0 }, 141 - { arc: [ 142 - { x: 0, y: 5 }, 143 - { x: 5, y: 5 }, 144 - ]}, 145 - { arc: [ 146 - { x: 10, y: 5 }, 147 - { x: 10, y: 0 }, 148 - ]}, 149 - { x: 10, y: -3 }, 150 - ], 151 - addTo: hat, 152 - translate: { x: -16, y: 11, z: 12 }, 153 - scale: { x: lensScale }, 154 - }); 155 - 156 - glassLens.copy({ 157 - translate: { x: 16, y: 11, z: 12 }, 158 - scale: { x: -lensScale }, 159 - }); 160 - 161 - var glassesArm = new Zdog.Shape({ 162 - path: [ 163 - { x: 12, y: 0 }, 164 - { x: -1, y: 0 }, 165 - { arc: [ 166 - { x: -1 - 8*quarterView, y: 0 }, 167 - { x: -1 - 8*quarterView, y: 8 }, 168 - ]}, 169 - ], 170 - addTo: hat, 171 - translate: { x: -16, y: 8 }, 172 - rotate: { y: TAU/4 }, 173 - // only see one arm at time 174 - backface: false, 175 - }); 176 - glassesArm.copy({ 177 - scale: { x: -1 }, 178 - translate: { x: 16, y: 8 }, 179 - rotate: { y: -TAU/4 }, 180 - }); 181 - 182 - // -- animate --- // 183 - 184 - var t = 0; 185 - var cycleFrame = 240; 186 - 187 - function animate() { 188 - update(); 189 - render(); 190 - requestAnimationFrame( animate ); 191 - } 192 - 193 - animate(); 194 - 195 - // -- update -- // 196 - 197 - 198 - function update() { 199 - 200 - 201 - if ( isSpinning ) { 202 - t += 1/cycleFrame; 203 - t = t % 1; 204 - var isFirstHalf = t < 0.5; 205 - var halfT = isFirstHalf ? t : 1 - t; 206 - halfT /= 0.5; 207 - var easeT = Zdog.easeInOut( halfT, 3 ); 208 - hat.rotate.y = easeT*TAU/4 - TAU/8; 209 - var rxDirection = isFirstHalf ? 1 : 0; 210 - hat.rotate.x = (Math.cos( halfT * TAU ) * -0.5 + 0.5 ) * -TAU/16 * rxDirection; 211 - } 212 - 213 - // normalize camera angle 214 - hat.normalizeRotate(); 215 - 216 - var rx = hat.rotate.x; 217 - isRotateXFlat = rx < TAU/16 || rx > TAU * 15/16; 218 - // flip cap top 219 - var isRotateXTopSide = rx < TAU/4 || rx > TAU * 3/4; 220 - capTop.scale.y = isRotateXTopSide ? 1 : -1; 221 - 222 - illo.updateGraph(); 223 - } 224 - 225 - // -- render -- // 226 - 227 - function render() { 228 - var ctx = illo.ctx; 229 - ctx.globalCompositeOperation = 'source-over'; 230 - illo.renderGraph(); 231 - 232 - // render gradient 233 - ctx.globalCompositeOperation = 'source-in'; 234 - var gradient = ctx.createLinearGradient( 0, 0, 0, illo.height ); 235 - gradient.addColorStop( 0.2, '#F00' ); 236 - gradient.addColorStop( 0.75, '#19F' ); 237 - ctx.fillStyle = gradient; 238 - ctx.fillRect( 0, 0, illo.width, illo.height ); 239 - } 240 - 241 - // ----- inputs ----- // 242 - 243 - document.querySelector('.reset-button').onclick = function() { 244 - hat.rotate.set( initialHatRotate ); 245 - };
-54
demo/solid-shifter/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>solid-shifter</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: #EC0; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/vector.js"></script> 40 - <script src="../../js/anchor.js"></script> 41 - <script src="../../js/path-command.js"></script> 42 - <script src="../../js/shape.js"></script> 43 - <script src="../../js/ellipse.js"></script> 44 - <script src="../../js/rect.js"></script> 45 - <script src="../../js/group.js"></script> 46 - <script src="../../js/dragger.js"></script> 47 - <script src="../../js/cylinder.js"></script> 48 - <script src="../../js/cone.js"></script> 49 - <script src="../../js/illustration.js"></script> 50 - <script src="shifter.js"></script> 51 - <script src="solid-shifter.js"></script> 52 - 53 - </body> 54 - </html>
-243
demo/solid-shifter/shifter.js
··· 1 - var navy = '#369'; 2 - // var red = '#E21'; 3 - var green = '#692'; 4 - var egg = '#FED'; 5 - var ochre = '#E83'; 6 - 7 - var TAU = Zdog.TAU; 8 - 9 - [ Zdog.Shape, Zdog.Rect, Zdog.Ellipse, Zdog.Cylinder, Zdog.Cone ] 10 - .forEach( function( ItemClass ) { 11 - ItemClass.defaults.fill = true; 12 - ItemClass.defaults.stroke = false; 13 - } 14 - ); 15 - 16 - 17 - // triangle 18 - var isoTriangle = new Zdog.Shape({ 19 - path: [ 20 - { x: 1, y: 1 }, 21 - { x: -1, y: 1 }, 22 - { x: 0, y: -1 }, 23 - ], 24 - color: egg, 25 - }); 26 - 27 - function Shifter( options ) { 28 - 29 - var shifterAnchor = this.anchor = new Zdog.Anchor( options ); 30 - 31 - this.pyramid = ( function() { 32 - var pyramid = new Zdog.Group({ 33 - addTo: shifterAnchor, 34 - visible: false, 35 - // translate: { x: -3, y: -3 }, 36 - updateSort: true, 37 - }); 38 - 39 - var base = new Zdog.Rect({ 40 - addTo: pyramid, 41 - width: 2, 42 - height: 2, 43 - translate: { y: 1 }, 44 - rotate: { x: -TAU/4 }, 45 - color: navy, 46 - }); 47 - 48 - 49 - var triangle = new Zdog.Shape({ 50 - addTo: base, 51 - path: [ 52 - { x: 1, y: -1, z: 0 }, 53 - { x: -1, y: -1, z: 0 }, 54 - { x: 0, y: 0, z: -2 }, 55 - ], 56 - color: ochre, 57 - }); 58 - triangle.copy({ 59 - rotate: { z: TAU/4 }, 60 - }); 61 - triangle.copy({ 62 - rotate: { z: TAU/2 }, 63 - }); 64 - triangle.copy({ 65 - rotate: { z: TAU * 3/4 }, 66 - }); 67 - 68 - return pyramid; 69 - })(); 70 - 71 - // cylinder 1 72 - this.cylinder1 = new Zdog.Cylinder({ 73 - addTo: shifterAnchor, 74 - visible: false, 75 - diameter: 2, 76 - length: 2, 77 - // translate: { x: 0, y: -3 }, 78 - rotate: { y: TAU/4 }, 79 - color: navy, 80 - backface: egg, 81 - }); 82 - 83 - // cone 1 84 - // isoTriangle.copy({ 85 - // translate: { x: 3, y: -3, z: -2 }, 86 - // color: green, 87 - // }); 88 - 89 - this.cone = ( function() { 90 - var anchor = new Zdog.Group({ 91 - addTo: shifterAnchor, 92 - visible: false, 93 - // translate: { x: 3, y: -3 }, 94 - updateSort: true, 95 - }); 96 - 97 - new Zdog.Cone({ 98 - addTo: anchor, 99 - diameter: 2, 100 - length: 2, 101 - rotate: { x: TAU/4 }, 102 - translate: { y: 1 }, 103 - color: ochre, 104 - backface: egg, 105 - }); 106 - 107 - return anchor; 108 - })(); 109 - 110 - // triangular prism 111 - 112 - this.prism = ( function() { 113 - var prism = new Zdog.Group({ 114 - addTo: shifterAnchor, 115 - visible: false, 116 - // translate: { x: -3, y: 0 }, 117 - updateSort: true, 118 - }); 119 - 120 - var triangle = isoTriangle.copy({ 121 - addTo: prism, 122 - scale: { y: -1 }, 123 - rotate: { y: TAU/4 }, 124 - translate: { x: -1 }, 125 - color: ochre, 126 - }); 127 - triangle.copy({ 128 - translate: { x: 1 }, 129 - }); 130 - 131 - var angleFace = new Zdog.Shape({ 132 - addTo: prism, 133 - path: [ 134 - { x: -1, y: -1, z: 1 }, 135 - { x: 1, y: -1, z: 1 }, 136 - { x: 1, y: 1, z: 0 }, 137 - { x: -1, y: 1, z: 0 }, 138 - ], 139 - color: navy, 140 - }); 141 - angleFace.copy({ 142 - scale: { z: -1 }, 143 - }); 144 - 145 - // base 146 - new Zdog.Rect({ 147 - addTo: prism, 148 - width: 2, 149 - height: 2, 150 - rotate: { x: TAU/4 }, 151 - translate: { y: -1 }, 152 - color: green, 153 - }); 154 - 155 - return prism; 156 - })(); 157 - 158 - // eccentric cylinder, triangle contour 159 - 160 - this.triCylinder = ( function() { 161 - var cylinder = new Zdog.Group({ 162 - addTo: shifterAnchor, 163 - visible: false, 164 - // translate: { x: 3 }, 165 - }); 166 - 167 - isoTriangle.copy({ 168 - translate: {}, 169 - addTo: cylinder, 170 - color: ochre, 171 - }); 172 - 173 - var tilt = Math.atan(1/2); 174 - 175 - var capAnchor = new Zdog.Anchor({ 176 - addTo: cylinder, 177 - translate: { x: -0.5 }, 178 - rotate: { y: TAU/4 }, 179 - }); 180 - 181 - 182 - // left outside cap 183 - var cap = new Zdog.Ellipse({ 184 - addTo: capAnchor, 185 - diameter: 2, 186 - color: egg, 187 - rotate: { x: tilt }, 188 - scale: { y: 1/Math.cos( tilt ) }, 189 - backface: false, 190 - }); 191 - cap.copy({ // left inside cap 192 - rotate: { y: TAU/2, x: tilt }, 193 - color: ochre, 194 - }); 195 - 196 - capAnchor.copyGraph({ 197 - translate: { x: 0.5 }, 198 - rotate: { y: -TAU/4 }, 199 - }); 200 - 201 - return cylinder; 202 - })(); 203 - 204 - this.cylinder2 = this.cylinder1.copy({ 205 - translate: {}, 206 - visible: false, 207 - rotate: { x: TAU/4 }, 208 - }); 209 - 210 - } 211 - 212 - Shifter.prototype.update = function( t ) { 213 - 214 - var turn = Math.floor( t % 6 ); 215 - 216 - var easeT = Zdog.easeInOut( t % 1, 4 ) * TAU/4; 217 - this.pyramid.rotate.x = easeT; 218 - this.cylinder1.rotate.y = easeT + TAU/4; 219 - this.cone.rotate.x = easeT + TAU/4; 220 - this.prism.rotate.y = easeT + TAU/4; 221 - this.cylinder2.rotate.x = easeT + TAU/4; 222 - this.triCylinder.rotate.y = easeT + TAU/4; 223 - 224 - if ( turn === 0 ) { 225 - this.triCylinder.visible = false; 226 - this.pyramid.visible = true; 227 - } else if ( turn == 1) { 228 - this.pyramid.visible = false; 229 - this.cylinder1.visible = true; 230 - } else if ( turn == 2 ) { 231 - this.cylinder1.visible = false; 232 - this.cone.visible = true; 233 - } else if ( turn == 3 ) { 234 - this.cone.visible = false; 235 - this.prism.visible = true; 236 - } else if ( turn == 4 ) { 237 - this.prism.visible = false; 238 - this.cylinder2.visible = true; 239 - } else if ( turn == 5 ) { 240 - this.cylinder2.visible = false; 241 - this.triCylinder.visible = true; 242 - } 243 - };
-51
demo/solid-shifter/solid-shifter.js
··· 1 - /* globals Shifter */ 2 - 3 - // -------------------------- demo -------------------------- // 4 - 5 - var illoElem = document.querySelector('.illo'); 6 - var w = 10; 7 - var h = 10; 8 - var minWindowSize = Math.min( window.innerWidth, window.innerHeight - 40 ); 9 - var zoom = Math.floor( minWindowSize / w ); 10 - illoElem.setAttribute( 'width', w * zoom ); 11 - illoElem.setAttribute( 'height', h * zoom ); 12 - 13 - var illo = new Zdog.Illustration({ 14 - element: illoElem, 15 - zoom: zoom, 16 - dragRotate: true, 17 - }); 18 - 19 - // -- illustration shapes --- // 20 - 21 - var shifterA = new Shifter({ 22 - addTo: illo, 23 - translate: { x: -3 }, 24 - }); 25 - var shifterB = new Shifter({ 26 - addTo: illo, 27 - }); 28 - var shifterC = new Shifter({ 29 - addTo: illo, 30 - translate: { x: 3 }, 31 - }); 32 - 33 - // -- animate --- // 34 - 35 - var t = 0; 36 - var tSpeed = 1/80; 37 - 38 - function animate() { 39 - // update 40 - shifterA.update( t + 4 ); 41 - shifterB.update( t + 2 ); 42 - shifterC.update( t + 0 ); 43 - 44 - t += tSpeed; 45 - 46 - illo.updateRenderGraph(); 47 - requestAnimationFrame( animate ); 48 - } 49 - 50 - animate(); 51 -
-52
demo/starter-demo/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>starter demo</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - background: #FDB; 25 - display: block; 26 - margin: 0px auto 20px; 27 - cursor: move; 28 - border-radius: 8px; 29 - } 30 - </style> 31 - 32 - </head> 33 - <body> 34 - 35 - <div class="container"> 36 - <canvas class="illo" width="240" height="240"></canvas> 37 - </div> 38 - 39 - <script src="../../js/boilerplate.js"></script> 40 - <script src="../../js/canvas-renderer.js"></script> 41 - <script src="../../js/vector.js"></script> 42 - <script src="../../js/anchor.js"></script> 43 - <script src="../../js/path-command.js"></script> 44 - <script src="../../js/shape.js"></script> 45 - <script src="../../js/ellipse.js"></script> 46 - <script src="../../js/rect.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="starter-demo.js"></script> 50 - 51 - </body> 52 - </html>
-47
demo/starter-demo/starter-demo.js
··· 1 - var isSpinning = true; 2 - var TAU = Zdog.TAU; 3 - 4 - var illo = new Zdog.Illustration({ 5 - element: '.illo', 6 - zoom: 4, 7 - dragRotate: true, 8 - onDragStart: function() { 9 - isSpinning = false; // stop rotating 10 - }, 11 - }); 12 - 13 - // circle 14 - new Zdog.Ellipse({ 15 - addTo: illo, 16 - diameter: 20, 17 - translate: { z: 10 }, 18 - stroke: 5, 19 - color: '#636', 20 - }); 21 - 22 - // triangle 23 - new Zdog.Shape({ 24 - addTo: illo, 25 - path: [ 26 - { x: 0, y: -1 }, 27 - { x: 1, y: 1 }, 28 - { x: -1, y: 1 }, 29 - ], 30 - scale: 8, 31 - translate: { z: -10 }, 32 - rotate: { y: TAU/4 }, 33 - color: '#E62', 34 - stroke: 3, 35 - fill: true, 36 - }); 37 - 38 - // animate 39 - function animate() { 40 - if ( isSpinning ) { 41 - illo.rotate.y += TAU/150; 42 - } 43 - illo.updateRenderGraph(); 44 - requestAnimationFrame( animate ); 45 - } 46 - 47 - animate();
-52
demo/strutter-tutorial/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>strutter tutorial</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - font-family: sans-serif; 19 - text-align: center; 20 - } 21 - 22 - .illo { 23 - display: block; 24 - margin: 0px auto 20px; 25 - cursor: move; 26 - background: #FDB; 27 - border-radius: 8px; 28 - } 29 - </style> 30 - 31 - </head> 32 - <body> 33 - 34 - <div class="container"> 35 - <canvas class="illo" width="240" height="240"></canvas> 36 - </div> 37 - 38 - <script src="../../js/boilerplate.js"></script> 39 - <script src="../../js/canvas-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/anchor.js"></script> 42 - <script src="../../js/path-command.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/rect.js"></script> 46 - <script src="../../js/rounded-rect.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="strutter-tutorial.js"></script> 50 - 51 - </body> 52 - </html>
-162
demo/strutter-tutorial/strutter-tutorial.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var isSpinning = true; 4 - // colors 5 - var gold = '#EA0'; 6 - var garnet = '#C25'; 7 - var eggplant = '#636'; 8 - var TAU = Zdog.TAU; 9 - var initalRotate = { y: -TAU/8 }; 10 - 11 - var illo = new Zdog.Illustration({ 12 - element: '.illo', 13 - zoom: 5, 14 - rotate: initalRotate, 15 - dragRotate: true, 16 - onDragStart: function() { 17 - isSpinning = false; 18 - }, 19 - }); 20 - 21 - // ----- model ----- // 22 - 23 - var hipX = 3; 24 - 25 - var hips = new Zdog.Shape({ 26 - addTo: illo, 27 - path: [ { x: -hipX }, { x: hipX } ], 28 - translate: { y: 2 }, 29 - color: eggplant, 30 - stroke: 4, 31 - }); 32 - 33 - var rightLeg = new Zdog.Shape({ 34 - addTo: hips, 35 - path: [ { y: 0 }, { y: 12 } ], 36 - translate: { x: -hipX }, 37 - rotate: { x: TAU/4 }, 38 - color: eggplant, 39 - stroke: 4, 40 - }); 41 - // foot 42 - var foot = new Zdog.RoundedRect({ 43 - addTo: rightLeg, 44 - width: 2, 45 - height: 4, 46 - cornerRadius: 1, 47 - translate: { y: 14, z: 2 }, 48 - rotate: { x: TAU/4 }, 49 - color: garnet, 50 - fill: true, 51 - stroke: 4, 52 - }); 53 - 54 - var plantAngle = -TAU/8; 55 - var leftLeg = rightLeg.copy({ 56 - translate: { x: hipX }, 57 - rotate: { x: plantAngle }, 58 - color: eggplant, 59 - }); 60 - 61 - foot.copy({ 62 - addTo: leftLeg, 63 - rotate: { x: TAU/4 - plantAngle } 64 - }); 65 - 66 - var spine = new Zdog.Anchor({ 67 - addTo: hips, 68 - rotate: { x: TAU/8 }, 69 - }); 70 - 71 - // chest 72 - var chest = new Zdog.Shape({ 73 - addTo: spine, 74 - path: [ { x: -1.5 }, { x: 1.5 } ], 75 - translate: { y: -6.5 }, 76 - color: garnet, 77 - stroke: 9, 78 - }); 79 - 80 - var head = new Zdog.Shape({ 81 - addTo: chest, 82 - stroke: 12, 83 - translate: { y: -9.5 }, 84 - color: gold, 85 - }); 86 - 87 - var eye = new Zdog.Ellipse({ 88 - addTo: head, 89 - diameter: 2, 90 - quarters: 2, 91 - translate: { x: -2, y: 1, z: 4.5 }, 92 - rotate: { z: -TAU/4 }, 93 - color: eggplant, 94 - stroke: 0.5, 95 - backface: false, 96 - }); 97 - eye.copy({ 98 - translate: { x: 2, y: 1, z: 4.5 }, 99 - }); 100 - // smile 101 - new Zdog.Ellipse({ 102 - addTo: head, 103 - diameter: 3, 104 - quarters: 2, 105 - translate: { y: 2.5, z: 4.5 }, 106 - rotate: { z: TAU/4 }, 107 - closed: true, 108 - color: '#FED', 109 - stroke: 0.5, 110 - fill: true, 111 - backface: false, 112 - }); 113 - 114 - var armSize = 6; 115 - 116 - // right arm 117 - var upperArm = new Zdog.Shape({ 118 - addTo: chest, 119 - path: [ { y: 0 }, { y: armSize } ], 120 - translate: { x: -5, y: -2 }, 121 - rotate: { x: -TAU/4 }, 122 - color: eggplant, 123 - stroke: 4, 124 - }); 125 - 126 - var forearm = new Zdog.Shape({ 127 - addTo: upperArm, 128 - path: [ { y: 0 }, { y: armSize-2 } ], 129 - translate: { y: armSize }, 130 - rotate: { x: TAU/8 }, 131 - color: garnet, 132 - stroke: 4, 133 - }); 134 - 135 - // hand 136 - new Zdog.Shape({ 137 - addTo: forearm, 138 - translate: { z: 1, y: armSize }, 139 - stroke: 6, 140 - color: gold, 141 - }); 142 - 143 - // left arm 144 - upperArm.copyGraph({ 145 - translate: { x: 5, y: -2 }, 146 - rotate: { x: TAU/4 }, 147 - }); 148 - 149 - // -- animate --- // 150 - 151 - var t = 0; 152 - 153 - function animate() { 154 - if ( isSpinning ) { 155 - illo.rotate.y = Zdog.easeInOut( t % 1, 4 ) * TAU + initalRotate.y; 156 - t += 1/150; 157 - } 158 - illo.updateRenderGraph(); 159 - requestAnimationFrame( animate ); 160 - } 161 - 162 - animate();
-70
demo/template/demo.js
··· 1 - // ------------------------- demo ------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var sceneSize = 48; 5 - var minWindowSize = Math.min( window.innerWidth - 20 , window.innerHeight - 20 ); 6 - var zoom = Math.floor( minWindowSize / sceneSize ); 7 - var illoSize = sceneSize * zoom; 8 - illoElem.setAttribute( 'width', illoSize ); 9 - illoElem.setAttribute( 'height', illoSize ); 10 - var isSpinning = true; 11 - var TAU = Zdog.TAU; 12 - 13 - var illo = new Zdog.Illustration({ 14 - element: illoElem, 15 - zoom: zoom, 16 - dragRotate: true, 17 - onDragStart: function() { 18 - isSpinning = false; 19 - }, 20 - }); 21 - 22 - // ----- model ----- // 23 - 24 - new Zdog.Rect({ 25 - width: 20, 26 - height: 20, 27 - addTo: illo, 28 - translate: { z: -10 }, 29 - stroke: 2, 30 - color: '#E21', 31 - }); 32 - 33 - new Zdog.Ellipse({ 34 - diameter: 16, 35 - addTo: illo, 36 - translate: { z: 10 }, 37 - stroke: 4, 38 - color: '#19F', 39 - }); 40 - 41 - new Zdog.Shape({ 42 - path: [ 43 - { x: 0, z: 1 }, 44 - { x: -1, z: -1 }, 45 - { x: 1, z: -1 }, 46 - ], 47 - scale: { x: 5, z: 5 }, 48 - addTo: illo, 49 - stroke: 2, 50 - fill: true, 51 - color: '#EA0', 52 - }); 53 - 54 - new Zdog.Shape({ 55 - translate: { x: 10, y: -5 }, 56 - addTo: illo, 57 - stroke: 7, 58 - color: '#246', 59 - }); 60 - 61 - // ----- animate ----- // 62 - 63 - function animate() { 64 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 65 - illo.updateRenderGraph(); 66 - requestAnimationFrame( animate ); 67 - } 68 - 69 - animate(); 70 -
-52
demo/template/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>template</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - </div> 36 - 37 - <script src="../../js/boilerplate.js"></script> 38 - <script src="../../js/canvas-renderer.js"></script> 39 - <script src="../../js/svg-renderer.js"></script> 40 - <script src="../../js/vector.js"></script> 41 - <script src="../../js/anchor.js"></script> 42 - <script src="../../js/path-command.js"></script> 43 - <script src="../../js/shape.js"></script> 44 - <script src="../../js/ellipse.js"></script> 45 - <script src="../../js/rect.js"></script> 46 - <script src="../../js/group.js"></script> 47 - <script src="../../js/dragger.js"></script> 48 - <script src="../../js/illustration.js"></script> 49 - <script src="demo.js"></script> 50 - 51 - </body> 52 - </html>
-44
demo/translate-rotate/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>translate-rotate</title> 8 - 9 - <style> 10 - body { 11 - background: #DDD; 12 - text-align: center; 13 - } 14 - 15 - .illo { 16 - display: block; 17 - border: 2px solid white; 18 - margin: 0px auto; 19 - } 20 - </style> 21 - 22 - </head> 23 - <body> 24 - 25 - <canvas class="illo"></canvas> 26 - 27 - <p>Click &amp; drag to rotate</p> 28 - <p> 29 - <button class="toggle-z-rotation-button">Toggle angleZ rotation</button> 30 - </p> 31 - 32 - <script src="../../js/boilerplate.js"></script> 33 - <script src="../../js/canvas-renderer.js"></script> 34 - <script src="../../js/vector.js"></script> 35 - <script src="../../js/anchor.js"></script> 36 - <script src="../../js/path-command.js"></script> 37 - <script src="../../js/shape.js"></script> 38 - <script src="../../js/rect.js"></script> 39 - <script src="../../js/dragger.js"></script> 40 - <script src="../../js/illustration.js"></script> 41 - <script src="translate-rotate.js"></script> 42 - 43 - </body> 44 - </html>
-83
demo/translate-rotate/translate-rotate.js
··· 1 - var illoElem = document.querySelector('.illo'); 2 - var illoSize = 72; 3 - var zoom = 6; 4 - illoElem.setAttribute( 'width', illoSize * zoom ); 5 - illoElem.setAttribute( 'height', illoSize * zoom ); 6 - var TAU = Zdog.TAU; 7 - 8 - 9 - var illo = new Zdog.Illustration({ 10 - element: illoElem, 11 - zoom: zoom, 12 - dragRotate: true, 13 - }); 14 - 15 - // -- illustration shapes --- // 16 - 17 - var rect1 = new Zdog.Rect({ 18 - width: 12, 19 - height: 16, 20 - translate: { z: -6 }, 21 - // rotate: { z: 1 }, 22 - stroke: 2, 23 - // fill: true, 24 - color: '#08D', 25 - addTo: illo, 26 - }); 27 - 28 - var moon1 = new Zdog.Shape({ 29 - path: [ 30 - { z: 0 }, 31 - { z: 6 } 32 - ], 33 - translate: { y: -11 }, 34 - stroke: 3, 35 - color: 'white', 36 - addTo: rect1, 37 - }); 38 - 39 - new Zdog.Rect({ 40 - width: 12, 41 - height: 8, 42 - translate: { y: 8 }, 43 - rotate: { x: TAU/4 }, 44 - stroke: 2, 45 - fill: true, 46 - color: '#E21', 47 - addTo: illo, 48 - }); 49 - 50 - new Zdog.Shape({ 51 - path: [ 52 - { y: -6, z: 4 }, 53 - { y: 6, z: 4 }, 54 - { y: 6, z: 0 }, 55 - { y: -6, z: 0 }, 56 - ], 57 - stroke: 1, 58 - fill: true, 59 - color: '#F80', 60 - addTo: illo, 61 - }); 62 - 63 - // -- animate --- // 64 - 65 - var rZSpeed = 0; 66 - 67 - function animate() { 68 - // rotate 69 - moon1.rotate.y += 0.03; 70 - rect1.rotate.z -= 0.02; 71 - illo.rotate.z += rZSpeed; 72 - // update & render 73 - illo.updateRenderGraph(); 74 - requestAnimationFrame( animate ); 75 - } 76 - 77 - animate(); 78 - 79 - // ----- inputs ----- // 80 - 81 - document.querySelector('.toggle-z-rotation-button').onclick = function() { 82 - rZSpeed = rZSpeed ? 0 : TAU/360; 83 - };
-48
demo/tri-prism/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>tri-prism</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - font-family: sans-serif; 19 - text-align: center; 20 - } 21 - 22 - canvas { 23 - display: block; 24 - margin: 0px auto 20px; 25 - cursor: move; 26 - } 27 - </style> 28 - 29 - </head> 30 - <body> 31 - 32 - <div class="container"> 33 - <canvas></canvas> 34 - </div> 35 - 36 - <script src="../../js/boilerplate.js"></script> 37 - <script src="../../js/canvas-renderer.js"></script> 38 - <script src="../../js/vector.js"></script> 39 - <script src="../../js/anchor.js"></script> 40 - <script src="../../js/path-command.js"></script> 41 - <script src="../../js/shape.js"></script> 42 - <script src="../../js/rect.js"></script> 43 - <script src="../../js/dragger.js"></script> 44 - <script src="../../js/illustration.js"></script> 45 - <script src="tri-prism.js"></script> 46 - 47 - </body> 48 - </html>
-197
demo/tri-prism/tri-prism.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var canvas = document.querySelector('canvas'); 4 - var proxyCanvas = document.createElement('canvas'); 5 - var ctx = canvas.getContext('2d'); 6 - var w = 14 * Math.sqrt(2); 7 - var h = 14 * Math.sqrt(2); 8 - var minWindowSize = Math.min( window.innerWidth - 20, window.innerHeight - 20 ); 9 - var zoom = Math.floor( minWindowSize / w ); 10 - 11 - var canvasWidth = canvas.width = w * zoom; 12 - var canvasHeight = canvas.height = h * zoom; 13 - var shrink = 1/3; 14 - proxyCanvas.width = canvasWidth * shrink; 15 - proxyCanvas.height = canvasHeight * shrink; 16 - var TAU = Zdog.TAU; 17 - 18 - var illo = new Zdog.Illustration({ 19 - element: proxyCanvas, 20 - rotate: { x: -35/360 * TAU, y: 45/360 * TAU }, 21 - zoom: zoom, 22 - }); 23 - 24 - 25 - var isSpinning = false; 26 - 27 - var navy = '#456'; 28 - var red = '#D21'; 29 - var ochre = '#F90'; 30 - 31 - document.body.style.backgroundColor = '#EDC'; 32 - 33 - // -- illustration shapes --- // 34 - 35 - function makePrism( options ) { 36 - var prism = new Zdog.Anchor({ 37 - addTo: illo, 38 - rotate: options.rotate, 39 - }); 40 - 41 - var rotor = new Zdog.Anchor({ 42 - addTo: prism, 43 - }); 44 - 45 - var positioner = new Zdog.Anchor({ 46 - addTo: rotor, 47 - translate: { z: 1, y: -1 }, 48 - }); 49 - 50 - var triangle = new Zdog.Shape({ 51 - addTo: positioner, 52 - path: [ 53 - { z: 1, y: 1 }, 54 - { z: -1, y: -1 }, 55 - { z: -1, y: 1 }, 56 - ], 57 - color: red, 58 - fill: true, 59 - stroke: 1/zoom, 60 - }); 61 - triangle.copy({ 62 - translate: { x: -2 }, 63 - color: navy, 64 - }); 65 - 66 - // slope 67 - new Zdog.Shape({ 68 - addTo: positioner, 69 - path: [ 70 - { x: -2, y: 1, z: 1 }, 71 - { x: -2, y: -1, z: -1 }, 72 - { x: 0, y: -1, z: -1 }, 73 - { x: 0, y: 1, z: 1 }, 74 - ], 75 - color: ochre, 76 - fill: true, 77 - stroke: 1/zoom, 78 - }); 79 - 80 - var base = new Zdog.Rect({ 81 - addTo: positioner, 82 - width: 2, 83 - height: 2, 84 - translate: { x: -1, z: -1 }, 85 - rotate: { y: TAU/2 }, 86 - color: navy, 87 - fill: true, 88 - stroke: 1/zoom, 89 - backface: false, 90 - }); 91 - base.copy({ 92 - translate: { x: -1, y: 1 }, 93 - rotate: { x: -TAU/4 }, 94 - color: red, 95 - }); 96 - 97 - return prism; 98 - } 99 - 100 - var prismA = makePrism({}); 101 - 102 - var prismB = makePrism({ 103 - rotate: { x: TAU/4, z: TAU/4 }, 104 - }); 105 - 106 - var prismC = makePrism({ 107 - rotate: { y: -TAU/4, z: -TAU/4 }, 108 - }); 109 - 110 - // -- animate --- // 111 - 112 - var t = 0; 113 - var tSpeed = 1/80; 114 - 115 - // -- update -- // 116 - 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 - ]; 126 - 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 - } 134 - 135 - function update() { 136 - var easeT = Zdog.easeInOut( t % 1, 4 ); 137 - var turn = Math.floor( t % 6 ); 138 - 139 - transform( prismA.children[0], turn, easeT ); 140 - transform( prismB.children[0], turn, easeT ); 141 - transform( prismC.children[0], turn, easeT ); 142 - 143 - t += tSpeed; 144 - 145 - illo.updateGraph(); 146 - } 147 - 148 - // -- render -- // 149 - 150 - var shiftX = Math.round( 3 * Math.sqrt(2) * zoom ); 151 - var shiftY = Math.round( 2 * Math.sqrt(2) * Math.sqrt(3)/2 * zoom ); 152 - 153 - function render() { 154 - illo.renderGraph(); 155 - 156 - ctx.clearRect( 0, 0, canvasWidth, canvasHeight ); 157 - 158 - ctx.save(); 159 - ctx.translate( Math.round( w * shrink * zoom ), Math.round( h * shrink * zoom ) ); 160 - 161 - for ( var col = -2; col < 3; col++ ) { 162 - for ( var row = -2; row < 3; row++ ) { 163 - var x = col * shiftX; 164 - var y = ( row * 2 + col % 2 ) * shiftY; 165 - ctx.drawImage( illo.element, x, y ); 166 - } 167 - } 168 - 169 - ctx.restore(); 170 - } 171 - 172 - function animate() { 173 - update(); 174 - render(); 175 - requestAnimationFrame( animate ); 176 - } 177 - 178 - animate(); 179 - 180 - // ----- inputs ----- // 181 - 182 - // click drag to rotate 183 - var dragStartRX, dragStartRY; 184 - 185 - new Zdog.Dragger({ 186 - startElement: canvas, 187 - onDragStart: function() { 188 - isSpinning = false; 189 - dragStartRX = illo.rotate.x; 190 - dragStartRY = illo.rotate.y; 191 - }, 192 - onDragMove: function( pointer, moveX, moveY ) { 193 - illo.rotate.x = dragStartRX - moveY / canvasWidth * TAU; 194 - illo.rotate.y = dragStartRY - moveX / canvasWidth * TAU; 195 - }, 196 - }); 197 -
-46
demo/truck-flight/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>truck-flight</title> 8 - 9 - <style> 10 - body { 11 - background: #FFF; 12 - text-align: center; 13 - } 14 - 15 - .illo { 16 - display: block; 17 - margin: 0px auto; 18 - } 19 - </style> 20 - 21 - </head> 22 - <body> 23 - 24 - <canvas class="illo"></canvas> 25 - 26 - <p>Click &amp; drag to rotate</p> 27 - 28 - <p> 29 - <button class="quarter-twist-button">View quarter twist</button> 30 - </p> 31 - 32 - <script src="../../js/boilerplate.js"></script> 33 - <script src="../../js/canvas-renderer.js"></script> 34 - <script src="../../js/vector.js"></script> 35 - <script src="../../js/path-command.js"></script> 36 - <script src="../../js/anchor.js"></script> 37 - <script src="../../js/shape.js"></script> 38 - <script src="../../js/ellipse.js"></script> 39 - <script src="../../js/rect.js"></script> 40 - <script src="../../js/group.js"></script> 41 - <script src="../../js/dragger.js"></script> 42 - <script src="../../js/illustration.js"></script> 43 - <script src="truck-flight.js"></script> 44 - 45 - </body> 46 - </html>
-398
demo/truck-flight/truck-flight.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var sceneSize = 88; 5 - var zoom = 5; 6 - var illoSize = sceneSize * zoom; 7 - illoElem.setAttribute( 'width', illoSize ); 8 - illoElem.setAttribute( 'height', illoSize ); 9 - var TAU = Zdog.TAU; 10 - var initRotate = { x: TAU/16, y: TAU/8 }; 11 - 12 - var illo = new Zdog.Illustration({ 13 - element: illoElem, 14 - zoom: zoom, 15 - rotate: initRotate, 16 - dragRotate: true, 17 - }); 18 - 19 - // colors 20 - var light = '#FFF'; 21 - var dark = '#333'; 22 - 23 - var darkStroke = { 24 - addTo: illo, 25 - color: dark, 26 - stroke: 2, 27 - fill: false, 28 - }; 29 - 30 - var lightFill = { 31 - addTo: illo, 32 - color: light, 33 - stroke: false, 34 - fill: true, 35 - }; 36 - 37 - var allDark = { 38 - addTo: illo, 39 - color: dark, 40 - fill: true, 41 - stroke: 2, 42 - }; 43 - 44 - // -- illustration shapes --- // 45 - 46 - var bedSidePath = [ 47 - { x: -32, y: -4 }, 48 - { x: -8, y: -4 }, 49 - { x: -8, y: 8 }, 50 - { x: -32, y: 8 }, 51 - ]; 52 - 53 - var darkStrokeSide = Zdog.extend( {translate: { z: 12 }}, darkStroke ); 54 - var lightFillSide = Zdog.extend( {translate: { z: 12 }}, lightFill ); 55 - var allDarkSide = Zdog.extend( {translate: { z: -12 }}, allDark ); 56 - 57 - // sides, outer 58 - [ lightFillSide, darkStrokeSide, allDarkSide ].forEach( function( sideOptions ) { 59 - 60 - // door 61 - new Zdog.Shape( Zdog.extend( { 62 - path: [ 63 - { x: -8, y: -14 }, 64 - { x: 10, y: -14 }, 65 - { x: 20, y: -4 }, 66 - { x: 20, y: 8 }, 67 - { x: -8, y: 8 }, 68 - ], 69 - }, sideOptions ) ); 70 - 71 - // bed side 72 - new Zdog.Shape( Zdog.extend( { 73 - path: bedSidePath, 74 - }, sideOptions ) ); 75 - 76 - // front side 77 - new Zdog.Shape( Zdog.extend( { 78 - path: [ 79 - { x: 20, y: -4 }, 80 - { x: 32, y: -4 }, 81 - { x: 32, y: 8 }, 82 - { x: 20, y: 8 }, 83 - ], 84 - }, sideOptions ) ); 85 - 86 - }); 87 - 88 - // inside bed 89 - // side, dark 90 - new Zdog.Shape( Zdog.extend( { 91 - path: bedSidePath, 92 - translate: { z: 11 } 93 - }, allDark )); 94 - // side light 95 - new Zdog.Shape( Zdog.extend( { 96 - path: bedSidePath, 97 - translate: { z: -11 } 98 - }, lightFill )); 99 - new Zdog.Shape( Zdog.extend( { 100 - path: bedSidePath, 101 - translate: { z: -11 } 102 - }, darkStroke )); 103 - 104 - // underside 105 - 106 - // back underside 107 - new Zdog.Shape( Zdog.extend( { 108 - path: [ 109 - { x: -32, z: 12 }, 110 - { x: -8, z: 12 }, 111 - { x: -8, z: -12 }, 112 - { x: -32, z: -12 }, 113 - ], 114 - translate: { y: 8 }, 115 - }, allDark ) ); 116 - // door underside 117 - new Zdog.Shape( Zdog.extend( { 118 - path: [ 119 - { x: -8, z: 12 }, 120 - { x: 20, z: 12 }, 121 - { x: 20, z: -12 }, 122 - { x: -8, z: -12 }, 123 - ], 124 - translate: { y: 8 }, 125 - }, allDark ) ); 126 - // front underside 127 - new Zdog.Shape( Zdog.extend( { 128 - path: [ 129 - { x: 20, z: 12 }, 130 - { x: 32, z: 12 }, 131 - { x: 32, z: -12 }, 132 - { x: 20, z: -12 }, 133 - ], 134 - translate: { y: 8 }, 135 - }, allDark ) ); 136 - 137 - // roof 138 - var roof = new Zdog.Shape( Zdog.extend( { 139 - path: [ 140 - { x: -8, z: 12 }, 141 - { x: 10, z: 12 }, 142 - { x: 10, z: -12 }, 143 - { x: -8, z: -12 }, 144 - ], 145 - translate: { y: -14 }, 146 - }, lightFill ) ); 147 - roof.copy( darkStroke ); 148 - 149 - // windshield 150 - new Zdog.Shape( Zdog.extend( { 151 - path: [ 152 - { x: 10, y: -14, z: 12 }, 153 - { x: 10, y: -14, z: -12 }, 154 - { x: 20, y: -4, z: -12 }, 155 - { x: 20, y: -4, z: 12 }, 156 - ], 157 - }, allDark ) ); 158 - 159 - // hood 160 - var hood = new Zdog.Shape( Zdog.extend( { 161 - path: [ 162 - { x: 20, z: 12 }, 163 - { x: 32, z: 12 }, 164 - { x: 32, z: -12 }, 165 - { x: 20, z: -12 }, 166 - ], 167 - translate: { y: -4 }, 168 - }, lightFill ) ); 169 - hood.copy( darkStroke ); 170 - 171 - var frontGroup = new Zdog.Group({ 172 - addTo: illo, 173 - translate: { x: 32, y: 2 }, 174 - rotate: { y: -TAU/4 }, 175 - // translate: { z: 1 } 176 - }); 177 - 178 - // front 179 - new Zdog.Rect({ 180 - addTo: frontGroup, 181 - width: 24, 182 - height: 12, 183 - color: dark, 184 - fill: true, 185 - stroke: 2, 186 - }); 187 - 188 - var frontDetails = new Zdog.Anchor({ 189 - addTo: frontGroup, 190 - translate: { z: 0.5 }, 191 - }); 192 - 193 - // front details 194 - var headlight = new Zdog.Rect({ 195 - width: 2, 196 - height: 2, 197 - addTo: frontDetails, 198 - translate: { x: -9, y: -3 }, 199 - color: light, 200 - stroke: 2, 201 - }); 202 - headlight.copy({ 203 - translate: { x: 9, y: -3 }, 204 - }); 205 - 206 - // top line 207 - var grillLine = new Zdog.Shape({ 208 - path: [ 209 - { x: -4 }, 210 - { x: 4 }, 211 - ], 212 - addTo: frontDetails, 213 - translate: { y: -4 }, 214 - color: light, 215 - closed: false, 216 - stroke: 2, 217 - }); 218 - grillLine.copy({ 219 - translate: { y: 0 }, 220 - }); 221 - grillLine.copy({ 222 - path: [ 223 - { x: -10 }, 224 - { x: 10 }, 225 - ], 226 - translate: { y: 4 }, 227 - }); 228 - 229 - // tail 230 - var tail = new Zdog.Rect( Zdog.extend({ 231 - width: 24, 232 - height: 12, 233 - addTo: illo, 234 - translate: { x: -32, y: 2 }, 235 - rotate: { y: TAU/4 }, 236 - }, lightFill )); 237 - tail.copy( darkStroke ); 238 - // tail inside 239 - tail.copy({ 240 - color: dark, 241 - translate: { x: -31, y: 2 }, 242 - }); 243 - 244 - var tailGroup = new Zdog.Group({ 245 - addTo: tail, 246 - translate: { z: -0 }, 247 - }); 248 - 249 - // back details 250 - var backlight = new Zdog.Rect({ 251 - width: 4, 252 - height: 4, 253 - addTo: tailGroup, 254 - translate: { x: -10, y: -4 }, 255 - color: dark, 256 - stroke: 2, 257 - fill: true, 258 - }); 259 - backlight.copy({ 260 - translate: { x: 10, y: -4 }, 261 - }); 262 - // back bumper 263 - new Zdog.Shape({ 264 - path: [ 265 - { x: -11 }, 266 - { x: 11 }, 267 - { move: { z: 64 } }, // 'nother hack 268 - ], 269 - addTo: tailGroup, 270 - translate: { y: 5, z: 1 }, 271 - color: dark, 272 - stroke: 4, 273 - closed: false, 274 - }); 275 - 276 - // cab back 277 - var cabBackTop = new Zdog.Shape({ 278 - path: [ 279 - { y: -14, z: 12 }, 280 - { y: -4, z: 12 }, 281 - { y: -4, z: -12 }, 282 - { y: -14, z: -12 }, 283 - ], 284 - addTo: illo, 285 - translate: { x: -8 }, 286 - color: light, 287 - stroke: false, 288 - fill: true, 289 - }); 290 - cabBackTop.copy({ 291 - color: dark, 292 - fill: false, 293 - stroke: 2, 294 - }); 295 - 296 - var cabBackBottom = new Zdog.Shape({ 297 - path: [ 298 - { y: -4, z: 12 }, 299 - { y: 8, z: 12 }, 300 - { y: 8, z: -12 }, 301 - { y: -4, z: -12 }, 302 - ], 303 - addTo: illo, 304 - translate: { x: -8 }, 305 - color: light, 306 - stroke: false, 307 - fill: true, 308 - }); 309 - cabBackBottom.copy({ 310 - color: dark, 311 - fill: false, 312 - stroke: 2, 313 - }); 314 - 315 - // WHEELS 316 - 317 - // front light 318 - var lightFillWheel = new Zdog.Shape( Zdog.extend({ 319 - path: [ 320 - { x: 0, y: -6 }, 321 - { arc: [ // top right 322 - { x: 6, y: -6 }, 323 - { x: 6, y: 0 }, 324 - ]}, 325 - { arc: [ // bottom right 326 - { x: 6, y: 6 }, 327 - { x: 0, y: 6 }, 328 - ]}, 329 - { arc: [ // bottom left 330 - { x: -6, y: 6 }, 331 - { x: -6, y: 0 }, 332 - ]}, 333 - { arc: [ // bottom left 334 - { x: -6, y: -6 }, 335 - { x: 0, y: -6 }, 336 - ]}, 337 - // hack, add a big move up to fix z-sort bug 338 - { move: { x: 0, y: -64, z: 64 } }, 339 - ], 340 - closed: false, 341 - translate: { x: 18, y: 8, z: 14 }, 342 - }, lightFill )); 343 - var darkStrokeWheel = lightFillWheel.copy({ 344 - fill: false, 345 - stroke: 4, 346 - color: dark, 347 - }); 348 - var darkWheel = new Zdog.Ellipse({ 349 - diameter: 12, 350 - addTo: illo, 351 - translate: { x: 18, y: 8, z: 10 }, 352 - color: dark, 353 - stroke: 4, 354 - fill: true, 355 - }); 356 - 357 - 358 - // back light 359 - lightFillWheel.copy({ 360 - translate: { x: -18, y: 8, z: 14 } 361 - }); 362 - darkStrokeWheel.copy({ 363 - translate: { x: -18, y: 8, z: 14 } 364 - }); 365 - darkWheel.copy({ 366 - translate: { x: -18, y: 8, z: 10 }, 367 - }); 368 - 369 - // front dark 370 - darkWheel.copy({ 371 - translate: { x: 18, y: 8, z: -14 } 372 - }); 373 - darkWheel.copy({ 374 - translate: { x: 18, y: 8, z: -10 } 375 - }); 376 - 377 - // back dark 378 - darkWheel.copy({ 379 - translate: { x: -18, y: 8, z: -14 } 380 - }); 381 - darkWheel.copy({ 382 - translate: { x: -18, y: 8, z: -10 } 383 - }); 384 - 385 - // -- animate --- // 386 - 387 - function animate() { 388 - illo.updateRenderGraph(); 389 - requestAnimationFrame( animate ); 390 - } 391 - 392 - animate(); 393 - 394 - // ----- inputs ----- // 395 - 396 - document.querySelector('.quarter-twist-button').onclick = function() { 397 - illo.rotate.set( initRotate ); 398 - };
-62
demo/unpkg-explode/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8" /> 5 - <meta name="viewport" content="width=device-width" /> 6 - 7 - <title>unpkg explode</title> 8 - 9 - <style> 10 - html { height: 100%; } 11 - 12 - body { 13 - min-height: 100%; 14 - margin: 0; 15 - display: flex; 16 - align-items: center; 17 - justify-content: center; 18 - background: white; 19 - font-family: sans-serif; 20 - text-align: center; 21 - } 22 - 23 - .illo { 24 - display: block; 25 - margin: 0px auto 20px; 26 - cursor: move; 27 - } 28 - </style> 29 - 30 - </head> 31 - <body> 32 - 33 - <div class="container"> 34 - <canvas class="illo"></canvas> 35 - <p>Click &amp; drag to rotate</p> 36 - <p class="fill-p"> 37 - <label><input type="radio" name="fill" value="color" checked /> Color</label> 38 - <label><input type="radio" name="fill" value="gray" /> Gray</label> 39 - <label><input type="radio" name="fill" value="clear" /> Clear</label> 40 - </p> 41 - <p> 42 - <label><input type="checkbox" class="outline-checkbox" /> Outline</label> 43 - </p> 44 - <p><button onclick="javascript:startAnimation();">Restart animation</button></p> 45 - </div> 46 - 47 - <script src="../../js/boilerplate.js"></script> 48 - <script src="../../js/canvas-renderer.js"></script> 49 - <script src="../../js/vector.js"></script> 50 - <script src="../../js/anchor.js"></script> 51 - <script src="../../js/path-command.js"></script> 52 - <script src="../../js/shape.js"></script> 53 - <script src="../../js/ellipse.js"></script> 54 - <script src="../../js/rect.js"></script> 55 - <script src="../../js/rounded-rect.js"></script> 56 - <script src="../../js/group.js"></script> 57 - <script src="../../js/dragger.js"></script> 58 - <script src="../../js/illustration.js"></script> 59 - <script src="unpkg-explode.js"></script> 60 - 61 - </body> 62 - </html>
-167
demo/unpkg-explode/unpkg-explode.js
··· 1 - // -------------------------- demo -------------------------- // 2 - 3 - var illoElem = document.querySelector('.illo'); 4 - var w = 48; 5 - var h = 48; 6 - var minWindowSize = Math.min( window.innerWidth, (window.innerHeight - 200) ); 7 - var zoom = Math.floor( minWindowSize / w ); 8 - // var zoom = 6; 9 - illoElem.setAttribute( 'width', w * zoom ); 10 - illoElem.setAttribute( 'height', h * zoom ); 11 - var TAU = Zdog.TAU; 12 - 13 - var isSpinning = false; 14 - 15 - var illo = new Zdog.Illustration({ 16 - element: illoElem, 17 - zoom: zoom, 18 - rotate: { x: TAU * (35/360), y: TAU/8 }, 19 - dragRotate: true, 20 - onDragStart: function() { 21 - isSpinning = false; 22 - }, 23 - }); 24 - 25 - var red = '#E21'; 26 - var blue = '#19F'; 27 - var gold = '#EA0'; 28 - var green = '#6C6'; 29 - var magenta = '#E2A'; 30 - 31 - // -- illustration shapes --- // 32 - 33 - var colors = [ red, blue, gold, magenta, green ]; 34 - 35 - var panelAnchors = []; 36 - var panels = []; 37 - var outlines = []; 38 - 39 - [ 40 - { y: 0 }, 41 - { y: TAU/4 }, 42 - { y: TAU/2 }, 43 - { y: TAU * 3/4 }, 44 - { x: TAU/4 }, 45 - ].forEach( function( rotation, i ) { 46 - 47 - var rotor = new Zdog.Anchor({ 48 - addTo: illo, 49 - rotate: rotation, 50 - }); 51 - 52 - var anchor = new Zdog.Anchor({ 53 - addTo: rotor, 54 - translate: { z: -8 }, 55 - }); 56 - 57 - panelAnchors.push( anchor ); 58 - 59 - var panel = new Zdog.RoundedRect({ 60 - width: 16, 61 - height: 16, 62 - cornerRadius: 3, 63 - addTo: anchor, 64 - stroke: false, 65 - fill: true, 66 - color: colors[i], 67 - }); 68 - 69 - panels.push( panel ); 70 - 71 - var outline = panel.copy({ 72 - visible: false, 73 - stroke: 1, 74 - fill: false, 75 - color: 'black', 76 - }); 77 - 78 - outlines.push( outline ); 79 - 80 - }); 81 - 82 - // -- animate --- // 83 - 84 - illo.ctx.globalCompositeOperation = 'multiply'; 85 - 86 - function animate() { 87 - illo.updateRenderGraph(); 88 - requestAnimationFrame( animate ); 89 - illo.rotate.y += isSpinning ? +TAU/150 : 0; 90 - } 91 - 92 - animate(); 93 - 94 - // ----- animation ----- // 95 - 96 - var animateFrame; 97 - 98 - function animation( duration, onFrame ) { 99 - 100 - var start = now(); 101 - 102 - animateFrame = function() { 103 - var ellasped = now() - start; 104 - var t = ellasped / duration; 105 - onFrame( t ); 106 - if ( ellasped < duration ) { 107 - requestAnimationFrame( animateFrame ); 108 - } 109 - }; 110 - 111 - animateFrame(); 112 - } 113 - 114 - function now() { 115 - return ( new Date() ).getTime(); 116 - } 117 - 118 - function startAnimation() { 119 - animation( 2000, function( t ) { 120 - var easeT = Zdog.easeInOut( t, 3 ); 121 - panelAnchors.forEach( function( panelAnchor ) { 122 - panelAnchor.translate.z = Zdog.lerp( -8, -11, easeT ); 123 - }); 124 - illo.rotate.x = Zdog.lerp( TAU/4, TAU * (35/360), easeT ); 125 - illo.rotate.y = Zdog.lerp( -TAU/2, TAU/8, easeT ); 126 - }); 127 - } 128 - 129 - startAnimation(); 130 - 131 - // ----- more inputs ----- // 132 - 133 - var fillP = document.querySelector('.fill-p'); 134 - fillP.onchange = function( event ) { 135 - changePanelColor( event.target.value ); 136 - }; 137 - 138 - // set initial 139 - changePanelColor( fillP.querySelector(':checked').value ); 140 - 141 - function changePanelColor( value ) { 142 - panels.forEach( function( panel, i ) { 143 - if ( value == 'gray' ) { 144 - panel.color = '#888'; 145 - } else if ( value == 'clear' ) { 146 - panel.color = 'transparent'; 147 - } else { 148 - panel.color = colors[i]; 149 - } 150 - }); 151 - } 152 - 153 - var outlineCheckbox = document.querySelector('.outline-checkbox'); 154 - outlineCheckbox.onchange = function( event ) { 155 - outlines.forEach( function( outline ) { 156 - outline.visible = event.target.checked; 157 - }); 158 - }; 159 - 160 - // set initial 161 - changeOutline( outlineCheckbox.checked ); 162 - 163 - function changeOutline( isRendering ) { 164 - outlines.forEach( function( outline ) { 165 - outline.visible = isRendering; 166 - }); 167 - }