WIP WYSIWYG ~3D SVG editor.
0
fork

Configure Feed

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

Convert Zoodle to use ES6 classes

+215 -247
+215 -247
zoodle.js
··· 1 - function Zoodle(scene, overlay, widgets) { 2 - this.scene = scene; 3 - this.overlay = overlay; 4 - this.widgets = widgets; 1 + class Zoodle { 2 + constructor(sceneElem, overlayElem, widgetsElem) { 3 + // TODO: Calculate appropriate zooms and sizes 4 + let zoom = 10; 5 + let rotate = { x: -Math.atan(1 / Math.sqrt(2)), y: TAU / 8 }; 5 6 6 - this.selection = []; 7 - this.tool = "orbit"; 8 - this.tools = { 9 - orbit: new OrbitTool(this), 10 - translate: new TranslateTool(this), 11 - }; 7 + this.scene = new Zdog.Illustration({ 8 + element: sceneElem, 9 + zoom: zoom, 10 + resize: 'fullscreen', 11 + rotate: rotate, 12 + dragRotate: false, 13 + }); 14 + this.overlay = new Zdog.Illustration({ 15 + element: overlayElem, 16 + zoom: zoom, 17 + resize: 'fullscreen', 18 + rotate: rotate, 19 + dragRotate: false, 20 + }); 21 + this.widgets = new Zdog.Illustration({ 22 + element: widgetsElem, 23 + zoom: zoom, 24 + resize: 'fullscreen', 25 + rotate: rotate, 26 + dragRotate: false, 27 + }); 12 28 13 - this.click = (ptr, target, x, y) => { 14 - this.select(target); 15 - }; 29 + this.selection = []; 30 + this.queue = []; 31 + this.tool = "orbit"; 32 + this.tools = { 33 + orbit: new OrbitTool(this), 34 + }; 35 + 36 + this.presets = { 37 + solar: new Solar(this.scene), 38 + } 16 39 17 - this.select = (target) => { 40 + this.presets.solar.load(this.scene); 41 + 42 + this.fetch = new Zfetch({ 43 + scene: this.scene, 44 + click: this.click.bind(this), 45 + dragStart: this.dragStart.bind(this), 46 + dragMove: this.dragMove.bind(this), 47 + dragEnd: this.dragEnd.bind(this), 48 + }); 49 + 50 + this.update(); 51 + } 52 + 53 + update() { 54 + this.scene.updateRenderGraph(); 55 + this.overlay.updateRenderGraph(); 56 + this.widgets.updateRenderGraph(); 57 + //this.scene.element.setAttribute("data-zdog", JSON.stringify(this.scene)); 58 + requestAnimationFrame(this.update.bind(this)); 59 + } 60 + 61 + select(target) { 62 + if (!target) { 63 + this.clearSelection(); 64 + return; 65 + } 66 + 18 67 // If this is a compositeChild, find its parent 19 68 while (target.compositeChild) { 20 69 target = target.addTo; 21 70 } 22 71 23 72 // Don't highlight if target is the scene element 24 - if (!target || target.element === this.scene.element) { 73 + if (!target.addTo) { 25 74 this.clearSelection(); 26 75 return; 27 76 } 28 77 29 78 this.toggleSelection(target); 30 - }; 79 + } 31 80 32 - this.toggleSelection = (target) => { 81 + toggleSelection(target) { 33 82 const index = this.selection.indexOf(target); 34 - 35 83 if (index !== -1) { 36 84 this.selection.splice(index, 1); 37 85 } else { 38 86 this.selection.push(target); 39 87 } 40 - 41 88 this.updateSelection(); 42 - }; 89 + } 43 90 44 - this.clearSelection = () => { 91 + clearSelection() { 45 92 this.selection = []; 46 - 47 93 this.updateSelection(); 48 - }; 94 + } 49 95 50 - this.updateSelection = () => { 96 + updateSelection() { 51 97 this.overlay.children = []; 52 - 53 - for (let i = 0; i < this.selection.length; i++) { 54 - let currentObj = this.selection[i]; 55 - 56 - let highlight = currentObj.copyGraph({ 98 + this.selection.forEach((selected) => { 99 + let highlight = selected.copyGraph({ 57 100 addTo: this.overlay, 58 101 color: "#E62", 59 102 backface: "#E62", 60 103 }); 61 104 62 - for (let j = 0; j < highlight.flatGraph.length; j++) { 63 - highlight.flatGraph[j].color = "#E62"; 64 - highlight.flatGraph[j].backface = "#E62"; 65 - } 105 + // Highlight all children 106 + highlight.flatGraph.forEach((child) => { 107 + child.color = '#E62'; 108 + child.backface = '#E62'; 109 + }); 66 110 67 - Zdog.extend(highlight, this.getWorldTransforms(currentObj)); 111 + // Apply parent transforms to selected object. 112 + Zdog.extend(highlight, this.getWorldTransforms(selected)); 113 + }); 114 + 115 + this.syncLayers(); 116 + } 68 117 69 - } 118 + syncLayers() { 119 + const scene = this.scene; 120 + const targets = [this.overlay, this.widgets]; 70 121 71 - this.syncLayers(); 72 - }; 122 + targets.forEach((target) => { 123 + target.translate = scene.translate; 124 + target.rotate = scene.rotate; 125 + target.scale = scene.scale; 126 + target.zoom = scene.zoom; 127 + target.updateGraph(); 128 + }); 129 + } 73 130 74 - this.getWorldTransforms = (target) => { 131 + getWorldTransforms(target) { 75 132 let translate = new Zdog.Vector(); 76 133 let rotate = new Zdog.Vector(); 77 134 let scale = new Zdog.Vector({x: 1, y: 1, z: 1}); ··· 102 159 rotate.z = Math.atan2(-down.x, right.x); 103 160 } 104 161 return {translate: translate, rotate: rotate, scale: scale}; 105 - }; 162 + } 106 163 107 - this.dragStart = (ptr, target, x, y) => { 164 + // input 165 + click(ptr, target, x, y) { 166 + this.select(target); 167 + } 168 + 169 + dragStart(ptr, target, x, y) { 170 + // TODO: Edit Zfetch so it just returns null instead of the scene. 108 171 if (!target || target.element === this.scene.element) { 109 172 this.tool = "orbit"; 110 173 } 111 174 112 175 this.tools[this.tool].start(ptr, target, x, y); 113 - }; 176 + } 114 177 115 - this.dragMove = (ptr, target, x, y) => { 178 + dragMove(ptr, target, x, y) { 116 179 this.tools[this.tool].move(ptr, target, x, y); 117 - }; 180 + } 118 181 119 - this.dragEnd = (ptr, target, x, y) => { 182 + dragEnd(ptr, target, x, y) { 120 183 this.tools[this.tool].end(ptr, target, x, y); 121 - }; 122 - 123 - this.fetch = new Zfetch({ 124 - scene: this.scene, 125 - click: this.click, 126 - dragStart: this.dragStart, 127 - dragMove: this.dragMove, 128 - dragEnd: this.dragEnd, 129 - }); 130 - 131 - this.syncLayers = () => { 132 - scene = this.scene; 133 - targets = [this.overlay, this.widgets]; 134 - 135 - targets.forEach(target => { 136 - target.zoom = scene.zoom; 137 - target.scale = scene.scale; 138 - target.rotate = scene.rotate; 139 - target.translate = scene.translate; 140 - target.updateRenderGraph(); 141 - }); 142 184 } 143 - 144 - this.syncLayers(); 145 185 } 146 186 147 187 class Tool { ··· 162 202 } 163 203 } 164 204 165 - class TranslateTool extends Tool { 166 - constructor(editor) { 167 - super(editor); 168 - this.startPosition = new Zdog.Vector(); 169 - } 170 - start(ptr, target, x, y) { 171 - this.startPosition = this.editor.selected.translate.copy(); 172 - } 173 - move(ptr, target, x, y) { 174 - let delta = new Zdog.Vector({ 175 - x: x / this.editor.zoom, 176 - y: y / this.editor.zoom, 177 - }); 178 - this.editor.selected.translate = this.startPosition 179 - .copy() 180 - .add(delta) 181 - .rotate(this.editor.scene.rotate); 182 - } 205 + class Preset { 206 + load(illo) {} 183 207 } 184 208 185 - const TAU = Zdog.TAU; 186 - 187 - const charcoal = "#333"; 188 - const raisin = "#534"; 189 - const plum = "#636"; 190 - const rose = "#C25"; 191 - const orange = "#E62"; 192 - const gold = "#EA0"; 193 - const lemon = "#ED0"; 194 - const peach = "#FDB"; 195 - const lace = "#FFF4E8"; 196 - const mint = "#CFD"; 197 - const lime = "#4A2"; 198 - const blueberry = "#359"; 199 - 200 - function init() { 201 - window.illoElem = document.getElementById("canvas"); 202 - window.widgetsElem = document.getElementById("widgets"); 203 - window.overlayElem = document.getElementById("overlay"); 204 - 205 - illoElem.setAttribute("width", illoElem.clientWidth); 206 - illoElem.setAttribute("height", illoElem.clientHeight); 207 - 208 - widgetsElem.setAttribute("width", illoElem.clientWidth); 209 - widgetsElem.setAttribute("height", illoElem.clientHeight); 210 - overlayElem.setAttribute("width", illoElem.clientWidth); 211 - overlayElem.setAttribute("height", illoElem.clientHeight); 212 - 213 - window.illo = new Zdog.Illustration({ 214 - element: illoElem, 215 - zoom: 10, 216 - rotate: { x: -Math.atan(1 / Math.sqrt(2)), y: TAU / 8 }, 217 - dragRotate: false, 218 - }); 219 - 220 - window.widgets = new Zdog.Illustration({ 221 - element: widgetsElem, 222 - zoom: 10, 223 - dragRotate: false, 224 - }); 209 + class Solar extends Preset { 210 + load(illo) { 211 + let sun = new Zdog.Shape({ 212 + addTo: illo, 213 + stroke: 10, 214 + color: gold, 215 + }); 225 216 226 - window.overlay = new Zdog.Illustration({ 227 - element: overlayElem, 228 - zoom: 10, 229 - dragRotate: false, 230 - }); 217 + let arrow = new Zdog.Cone({ 218 + addTo: sun, 219 + diameter: 1.5, 220 + length: 1.5, 221 + stroke: false, 222 + translate: { y: -7.5 }, 223 + rotate: { x: -TAU / 4 }, 224 + color: orange, 225 + }); 231 226 232 - let sun = new Zdog.Shape({ 233 - addTo: window.illo, 234 - stroke: 10, 235 - color: gold, 236 - }); 227 + new Zdog.Cylinder({ 228 + addTo: arrow, 229 + color: orange, 230 + stroke: false, 231 + length: 1, 232 + diameter: 0.75, 233 + translate: { z: -.5 }, 234 + }); 237 235 238 - new Zdog.Cone({ 239 - addTo: sun, 240 - diameter: 1.5, 241 - length: 1.5, 242 - stroke: 0.1, 243 - translate: { y: -7.5 }, 244 - rotate: { x: -TAU / 4 }, 245 - color: orange, 246 - }); 236 + new Zdog.Shape({ 237 + addTo: sun, 238 + stroke: 1, 239 + translate: { x: 6 }, 240 + color: raisin, 241 + }); 247 242 248 - /*window.horn = new Zdog.Horn({ 249 - addTo: illo, 250 - frontDiameter: 10, 251 - rearDiameter: 2, 252 - length: 20, 253 - fill: true, 254 - stroke: 0, 255 - color: '#C25', 256 - translate: { y: -9 }, 257 - });*/ 243 + let orbit = new Zdog.Anchor({ 244 + addTo: sun, 245 + rotate: { x: TAU / 4 }, 246 + }); 258 247 259 - new Zdog.Cylinder({ 260 - addTo: sun, 261 - color: orange, 262 - stroke: false, 263 - length: 1, 264 - diameter: 0.75, 265 - translate: { y: -8 }, 266 - rotate: { x: -TAU / 4 }, 267 - }); 248 + let orbitalProps = { 249 + stroke: 0.5, 250 + color: charcoal, 251 + closed: false, 252 + }; 268 253 269 - new Zdog.Shape({ 270 - addTo: sun, 271 - stroke: 1, 272 - translate: { x: 6 }, 273 - color: raisin, 274 - }); 254 + let quadrant = new Zdog.Shape({ 255 + addTo: orbit, 256 + path: [ 257 + { x: 5.8, y: -1.55 }, 258 + { bezier: [ 259 + { x: 5.1, y: -4.17 }, 260 + { x: 2.71, y: -6 }, 261 + { x: 0, y: -6 }, 262 + ]}, 263 + ], 264 + }); 275 265 276 - let orbit = new Zdog.Anchor({ 277 - addTo: sun, 278 - rotate: { x: TAU / 4 }, 279 - }); 266 + Zdog.extend(quadrant, orbitalProps); 280 267 281 - let orbitalProps = { 282 - stroke: 0.5, 283 - color: charcoal, 284 - closed: false, 285 - }; 268 + quadrant.copy({ 269 + scale: { y: -1 }, 270 + }); 286 271 287 - let quadrant = new Zdog.Shape({ 288 - addTo: orbit, 289 - path: [ 290 - { x: 5.8, y: -1.55 }, 291 - { 292 - bezier: [ 293 - { x: 5.1, y: -4.17 }, 294 - { x: 2.71, y: -6 }, 295 - { x: 0, y: -6 }, 296 - ] 297 - }, 298 - ], 299 - }); 272 + quadrant = new Zdog.Shape({ 273 + addTo: orbit, 274 + path: [ 275 + { x: 0, y: -6 }, 276 + { arc: [ 277 + { x: -6, y: -6 }, 278 + { x: -6, y: 0 }, 279 + ]}, 280 + ] 281 + }); 300 282 301 - Zdog.extend(quadrant, orbitalProps); 283 + Zdog.extend(quadrant, orbitalProps); 302 284 303 - quadrant.copy({ 304 - scale: { y: -1 }, 305 - }); 285 + quadrant.copy({ 286 + scale: { y: -1 }, 287 + }); 306 288 307 - quadrant = new Zdog.Shape({ 308 - addTo: orbit, 309 - path: [ 310 - { x: 0, y: -6 }, 311 - { 312 - arc: [ 313 - { x: -6, y: -6 }, 314 - { x: -6, y: 0 }, 315 - ] 316 - }, 317 - ] 318 - }); 289 + new Zdog.Shape({ 290 + addTo: sun, 291 + stroke: 2, 292 + translate: { x: Math.cos(TAU/8)*8, z: Math.sin(TAU/8)*8 }, 293 + color: rose, 294 + }); 319 295 320 - Zdog.extend(quadrant, orbitalProps); 296 + orbit.copyGraph({ 297 + rotate: { x: TAU / 4, z: TAU / 8 }, 298 + scale: 8/6, 299 + }); 321 300 322 - quadrant.copy({ 323 - scale: { y: -1 }, 324 - }); 301 + new Zdog.Shape({ 302 + addTo: sun, 303 + stroke: 2, 304 + translate: { x: Math.cos(TAU/4)*10, z: Math.sin(TAU/4)*10 }, 305 + color: blueberry, 306 + }); 325 307 326 - new Zdog.Shape({ 327 - addTo: sun, 328 - stroke: 2, 329 - translate: { x: Math.cos(TAU/8)*8, z: Math.sin(TAU/8)*8 }, 330 - color: rose, 331 - }); 332 - 333 - orbit.copyGraph({ 334 - rotate: { x: TAU / 4, z: TAU / 8 }, 335 - scale: 8/6, 336 - }); 337 - 338 - new Zdog.Shape({ 339 - addTo: sun, 340 - stroke: 2, 341 - translate: { x: Math.cos(TAU/4)*10, z: Math.sin(TAU/4)*10 }, 342 - color: blueberry, 343 - }); 344 - 345 - orbit.copyGraph({ 346 - rotate: { x: TAU / 4, z: TAU / 4 }, 347 - scale: 10 / 6, 348 - }); 349 - 350 - window.zoodle = new Zoodle(illo, overlay, widgets); 308 + orbit.copyGraph({ 309 + rotate: { x: TAU / 4, z: TAU / 4 }, 310 + scale: 10 / 6, 311 + }); 312 + } 351 313 } 352 314 353 - // TODO: Only update when we have something to update. 354 - function update() { 355 - window.illo.updateRenderGraph(); 356 - window.widgets.updateRenderGraph(); 357 - window.overlay.updateRenderGraph(); 358 - window.illoElem.setAttribute("data-zdog", JSON.stringify(window.illo)); 359 - requestAnimationFrame(update); 360 - } 315 + const TAU = Zdog.TAU; 361 316 362 - init(); 363 - 364 - update(); 317 + const charcoal = "#333"; 318 + const raisin = "#534"; 319 + const plum = "#636"; 320 + const rose = "#C25"; 321 + const orange = "#E62"; 322 + const gold = "#EA0"; 323 + const lemon = "#ED0"; 324 + const peach = "#FDB"; 325 + const lace = "#FFF4E8"; 326 + const mint = "#CFD"; 327 + const lime = "#4A2"; 328 + const blueberry = "#359"; 365 329 330 + const sceneElem = document.querySelector("#canvas"); 331 + const overlayElem = document.querySelector("#overlay"); 332 + const widgetsElem = document.querySelector("#widgets"); 333 + const zoodle = new Zoodle(sceneElem, overlayElem, widgetsElem);