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.

🐶 v1.0.2

+131 -97
+126 -92
dist/zdog.dist.js
··· 1 1 /*! 2 - * Zdog v1.0.1 2 + * Zdog v1.0.2 3 3 * Round, flat, designer-friendly pseudo-3D engine 4 4 * Licensed MIT 5 5 * https://zzz.dog ··· 13 13 ( function( root, factory ) { 14 14 // module definition 15 15 if ( typeof module == 'object' && module.exports ) { 16 - /* globals module */ // CommonJS 16 + // CommonJS 17 17 module.exports = factory(); 18 18 } else { 19 19 // browser global ··· 32 32 return a; 33 33 }; 34 34 35 - Zdog.lerp = function( a, b, t ) { 36 - return ( b - a ) * t + a; 35 + Zdog.lerp = function( a, b, alpha ) { 36 + return ( b - a ) * alpha + a; 37 37 }; 38 38 39 39 Zdog.modulo = function( num, div ) { ··· 52 52 }, 53 53 5: function( a ) { 54 54 return a * a * a * a * a; 55 - } 55 + }, 56 56 }; 57 57 58 58 Zdog.easeInOut = function( alpha, power ) { ··· 62 62 alpha = Math.max( 0, Math.min( 1, alpha ) ); 63 63 var isFirstHalf = alpha < 0.5; 64 64 var slope = isFirstHalf ? alpha : 1 - alpha; 65 - slope = slope / 0.5; 65 + slope /= 0.5; 66 66 // make easing steeper with more multiples 67 67 var powerMultiplier = powerMultipliers[ power ] || powerMultipliers[2]; 68 68 var curve = powerMultiplier( slope ); 69 - curve = curve / 2; 69 + curve /= 2; 70 70 return isFirstHalf ? curve : 1 - curve; 71 71 }; 72 72 ··· 80 80 ( function( root, factory ) { 81 81 // module definition 82 82 if ( typeof module == 'object' && module.exports ) { 83 - /* globals module */ // CommonJS 83 + // CommonJS 84 84 module.exports = factory(); 85 85 } else { 86 86 // browser global ··· 151 151 ( function( root, factory ) { 152 152 // module definition 153 153 if ( typeof module == 'object' && module.exports ) { 154 - /* globals module */ // CommonJS 154 + // CommonJS 155 155 module.exports = factory(); 156 156 } else { 157 157 // browser global ··· 231 231 ( function( root, factory ) { 232 232 // module definition 233 233 if ( typeof module == 'object' && module.exports ) { 234 - /* globals module, require */ // CommonJS 234 + // CommonJS 235 235 module.exports = factory( require('./boilerplate') ); 236 236 } else { 237 237 // browser global ··· 346 346 return this; 347 347 }; 348 348 349 - Vector.prototype.lerp = function( pos, t ) { 350 - this.x = utils.lerp( this.x, pos.x || 0, t ); 351 - this.y = utils.lerp( this.y, pos.y || 0, t ); 352 - this.z = utils.lerp( this.z, pos.z || 0, t ); 349 + Vector.prototype.lerp = function( pos, alpha ) { 350 + this.x = utils.lerp( this.x, pos.x || 0, alpha ); 351 + this.y = utils.lerp( this.y, pos.y || 0, alpha ); 352 + this.z = utils.lerp( this.z, pos.z || 0, alpha ); 353 353 return this; 354 354 }; 355 355 ··· 385 385 ( function( root, factory ) { 386 386 // module definition 387 387 if ( typeof module == 'object' && module.exports ) { 388 - /* globals module, require */ // CommonJS 389 - module.exports = factory( require('./boilerplate'), require('./vector') ); 388 + // CommonJS 389 + module.exports = factory( require('./boilerplate'), require('./vector'), 390 + require('./canvas-renderer'), require('./svg-renderer') ); 390 391 } else { 391 392 // browser global 392 393 var Zdog = root.Zdog; 393 - Zdog.Anchor = factory( Zdog, Zdog.Vector ); 394 + Zdog.Anchor = factory( Zdog, Zdog.Vector, Zdog.CanvasRenderer, 395 + Zdog.SvgRenderer ); 394 396 } 395 - }( this, function factory( utils, Vector ) { 397 + }( this, function factory( utils, Vector, CanvasRenderer, SvgRenderer ) { 396 398 397 399 var TAU = utils.TAU; 398 400 var onePoint = { x: 1, y: 1, z: 1 }; ··· 488 490 489 491 Anchor.prototype.updateGraph = function() { 490 492 this.update(); 491 - this.checkFlatGraph(); 493 + this.updateFlatGraph(); 492 494 this.flatGraph.forEach( function( item ) { 493 495 item.updateSortValue(); 494 496 }); ··· 500 502 return a.sortValue - b.sortValue; 501 503 }; 502 504 503 - Anchor.prototype.checkFlatGraph = function() { 504 - if ( !this.flatGraph ) { 505 - this.updateFlatGraph(); 506 - } 507 - }; 505 + // custom getter to check for flatGraph before using it 506 + Object.defineProperty( Anchor.prototype, 'flatGraph', { 507 + get: function() { 508 + if ( !this._flatGraph ) { 509 + this.updateFlatGraph(); 510 + } 511 + return this._flatGraph; 512 + }, 513 + set: function( graph ) { 514 + this._flatGraph = graph; 515 + }, 516 + }); 508 517 509 518 Anchor.prototype.updateFlatGraph = function() { 510 519 this.flatGraph = this.getFlatGraph(); ··· 513 522 // return Array of self & all child graph items 514 523 Anchor.prototype.getFlatGraph = function() { 515 524 var flatGraph = [ this ]; 525 + return this.addChildFlatGraph( flatGraph ); 526 + }; 527 + 528 + Anchor.prototype.addChildFlatGraph = function( flatGraph ) { 516 529 this.children.forEach( function( child ) { 517 530 var childFlatGraph = child.getFlatGraph(); 518 - flatGraph = flatGraph.concat( childFlatGraph ); 531 + Array.prototype.push.apply( flatGraph, childFlatGraph ); 519 532 }); 520 533 return flatGraph; 521 534 }; ··· 528 541 529 542 Anchor.prototype.render = function() {}; 530 543 544 + // TODO refactor out CanvasRenderer so its not a dependency within anchor.js 531 545 Anchor.prototype.renderGraphCanvas = function( ctx ) { 532 546 if ( !ctx ) { 533 547 throw new Error( 'ctx is ' + ctx + '. ' + 534 548 'Canvas context required for render. Check .renderGraphCanvas( ctx ).' ); 535 549 } 536 - this.checkFlatGraph(); 537 550 this.flatGraph.forEach( function( item ) { 538 - item.render( ctx, Zdog.CanvasRenderer ); 551 + item.render( ctx, CanvasRenderer ); 539 552 }); 540 553 }; 541 554 ··· 546 559 } 547 560 this.checkFlatGraph(); 548 561 this.flatGraph.forEach( function( item ) { 549 - item.render( svg, Zdog.SvgRenderer ); 562 + item.render( svg, SvgRenderer ); 550 563 }); 551 564 }; 552 565 ··· 622 635 ( function( root, factory ) { 623 636 // module definition 624 637 if ( typeof module == 'object' && module.exports ) { 625 - /* globals module */ // CommonJS 626 - module.exports = factory(); 638 + // CommonJS 639 + module.exports = factory( root ); 627 640 } else { 628 641 // browser global 629 - root.Zdog.Dragger = factory(); 642 + root.Zdog.Dragger = factory( root ); 630 643 } 631 - }( this, function factory() { 644 + }( this, function factory( window ) { 632 645 633 646 // quick & dirty drag event stuff 634 647 // messes up if multiple pointers/touches ··· 666 679 Dragger.prototype.bindDrag = function( element ) { 667 680 element = this.getQueryElement( element ); 668 681 if ( element ) { 669 - element.addEventListener( downEvent , this ); 682 + element.addEventListener( downEvent, this ); 670 683 } 671 684 }; 672 685 ··· 739 752 ( function( root, factory ) { 740 753 // module definition 741 754 if ( typeof module == 'object' && module.exports ) { 742 - /* globals module, require */ // CommonJS 755 + // CommonJS 743 756 module.exports = factory( require('./boilerplate'), require('./anchor'), 744 757 require('./dragger') ); 745 758 } else { ··· 782 795 } 783 796 784 797 var nodeName = element.nodeName.toLowerCase(); 785 - if ( nodeName == 'canvas' ) { 798 + if ( nodeName == 'canvas' ) { 786 799 this.setCanvas( element ); 787 800 } else if ( nodeName == 'svg' ) { 788 801 this.setSvg( element ); ··· 868 881 var pixelRatio = this.pixelRatio = window.devicePixelRatio || 1; 869 882 this.element.width = this.canvasWidth = width * pixelRatio; 870 883 this.element.height = this.canvasHeight = height * pixelRatio; 871 - if ( pixelRatio > 1 ) { 884 + var needsHighPixelRatioSizing = pixelRatio > 1 && !this.resize; 885 + if ( needsHighPixelRatioSizing ) { 872 886 this.element.style.width = width + 'px'; 873 887 this.element.style.height = height + 'px'; 874 888 } ··· 897 911 this.onPrerender( ctx ); 898 912 }; 899 913 900 - Illustration.prototype.postrenderCanvas = function () { 914 + Illustration.prototype.postrenderCanvas = function() { 901 915 this.ctx.restore(); 902 916 }; 903 917 ··· 951 965 if ( !item ) { 952 966 return; 953 967 } else if ( item === true ) { 968 + /* eslint consistent-this: "off" */ 954 969 item = this; 955 970 } 956 971 this.dragRotate = item; ··· 985 1000 ( function( root, factory ) { 986 1001 // module definition 987 1002 if ( typeof module == 'object' && module.exports ) { 988 - /* globals module, require */ // CommonJS 1003 + // CommonJS 989 1004 module.exports = factory( require('./vector') ); 990 1005 } else { 991 1006 // browser global ··· 1053 1068 return renderer.bezier( ctx, elem, cp0, cp1, end ); 1054 1069 }; 1055 1070 1071 + var arcHandleLength = 9/16; 1072 + 1056 1073 PathCommand.prototype.arc = function( ctx, elem, renderer ) { 1057 1074 var prev = this.previousPoint; 1058 1075 var corner = this.renderPoints[0]; 1059 1076 var end = this.renderPoints[1]; 1060 1077 var cp0 = this.controlPoints[0]; 1061 1078 var cp1 = this.controlPoints[1]; 1062 - cp0.set( prev ).lerp( corner, 9/16 ); 1063 - cp1.set( end ).lerp( corner, 9/16 ); 1079 + cp0.set( prev ).lerp( corner, arcHandleLength ); 1080 + cp1.set( end ).lerp( corner, arcHandleLength ); 1064 1081 return renderer.bezier( ctx, elem, cp0, cp1, end ); 1065 1082 }; 1066 1083 ··· 1074 1091 ( function( root, factory ) { 1075 1092 // module definition 1076 1093 if ( typeof module == 'object' && module.exports ) { 1077 - /* globals module, require */ // CommonJS 1078 - module.exports = factory( require('./boilerplate'), require('./vector'), 1094 + // CommonJS 1095 + module.exports = factory( require('./boilerplate'), require('./vector'), 1079 1096 require('./path-command'), require('./anchor') ); 1080 1097 } else { 1081 1098 // browser global ··· 1282 1299 ( function( root, factory ) { 1283 1300 // module definition 1284 1301 if ( typeof module == 'object' && module.exports ) { 1285 - /* globals module, require */ // CommonJS 1302 + // CommonJS 1286 1303 module.exports = factory( require('./anchor') ); 1287 1304 } else { 1288 1305 // browser global ··· 1300 1317 1301 1318 Group.prototype.updateSortValue = function() { 1302 1319 var sortValueTotal = 0; 1303 - this.checkFlatGraph(); 1304 1320 this.flatGraph.forEach( function( item ) { 1305 1321 item.updateSortValue(); 1306 1322 sortValueTotal += item.sortValue; ··· 1321 1337 return; 1322 1338 } 1323 1339 1324 - this.checkFlatGraph(); 1325 1340 this.flatGraph.forEach( function( item ) { 1326 1341 item.render( ctx, renderer ); 1327 1342 }); 1328 1343 }; 1329 1344 1330 - // do not include children, group handles rendering & sorting internally 1331 - Group.prototype.getFlatGraph = function() { 1332 - return [ this ]; 1333 - }; 1334 - 1335 - // get flat graph only used for group 1336 - // do not include in parent flatGraphs 1345 + // actual group flatGraph only used inside group 1337 1346 Group.prototype.updateFlatGraph = function() { 1338 1347 // do not include self 1339 1348 var flatGraph = []; 1340 - this.children.forEach( function( child ) { 1341 - var childFlatGraph = child.getFlatGraph(); 1342 - flatGraph = flatGraph.concat( childFlatGraph ); 1343 - }); 1344 - this.flatGraph = flatGraph; 1349 + this.flatGraph = this.addChildFlatGraph( flatGraph ); 1350 + }; 1351 + 1352 + // do not include children, group handles rendering & sorting internally 1353 + Group.prototype.getFlatGraph = function() { 1354 + return [ this ]; 1345 1355 }; 1346 1356 1347 1357 return Group; ··· 1354 1364 ( function( root, factory ) { 1355 1365 // module definition 1356 1366 if ( typeof module == 'object' && module.exports ) { 1357 - /* globals module, require */// CommonJS 1367 + // CommonJS 1358 1368 module.exports = factory( require('./shape') ); 1359 1369 } else { 1360 1370 // browser global ··· 1371 1381 Rect.prototype.setPath = function() { 1372 1382 var x = this.width / 2; 1373 1383 var y = this.height / 2; 1384 + /* eslint key-spacing: "off" */ 1374 1385 this.path = [ 1375 1386 { x: -x, y: -y }, 1376 1387 { x: x, y: -y }, ··· 1389 1400 ( function( root, factory ) { 1390 1401 // module definition 1391 1402 if ( typeof module == 'object' && module.exports ) { 1392 - /* globals module, require */ // CommonJS 1403 + // CommonJS 1393 1404 module.exports = factory( require('./shape') ); 1394 1405 } else { 1395 1406 // browser global ··· 1406 1417 }); 1407 1418 1408 1419 RoundedRect.prototype.setPath = function() { 1420 + /* eslint 1421 + id-length: [ "error", { "min": 2, "exceptions": [ "x", "y" ] }], 1422 + key-spacing: "off" */ 1409 1423 var xA = this.width / 2; 1410 1424 var yA = this.height / 2; 1411 1425 var shortSide = Math.min( xA, yA ); ··· 1471 1485 ( function( root, factory ) { 1472 1486 // module definition 1473 1487 if ( typeof module == 'object' && module.exports ) { 1474 - /* globals module, require */ // CommonJS 1488 + // CommonJS 1475 1489 module.exports = factory( require('./shape') ); 1476 1490 } else { 1477 1491 // browser global ··· 1499 1513 { arc: [ // top right 1500 1514 { x: x, y: -y }, 1501 1515 { x: x, y: 0 }, 1502 - ]} 1516 + ]}, 1503 1517 ]; 1504 1518 // bottom right 1505 1519 if ( this.quarters > 1 ) { ··· 1545 1559 ( function( root, factory ) { 1546 1560 // module definition 1547 1561 if ( typeof module == 'object' && module.exports ) { 1548 - /* globals module, require */ // CommonJS 1562 + // CommonJS 1549 1563 module.exports = factory( require('./boilerplate'), require('./shape') ); 1550 1564 } else { 1551 1565 // browser global ··· 1581 1595 ( function( root, factory ) { 1582 1596 // module definition 1583 1597 if ( typeof module == 'object' && module.exports ) { 1584 - /* globals module, require */ // CommonJS 1598 + // CommonJS 1585 1599 module.exports = factory( require('./boilerplate'), require('./ellipse') ); 1586 1600 } else { 1587 1601 // browser global ··· 1621 1635 } else if ( renderer.isSvg ) { 1622 1636 // svg 1623 1637 contourAngle = (contourAngle - TAU/4) / TAU * 360; 1624 - this.domeSvgElement.setAttribute( 'd', 'M ' + (-domeRadius) + ',0 A ' + 1625 - domeRadius + ',' + domeRadius + ' 0 0 1 ' + domeRadius + ',0' ); 1638 + this.domeSvgElement.setAttribute( 'd', 'M ' + -domeRadius + ',0 A ' + 1639 + domeRadius + ',' + domeRadius + ' 0 0 1 ' + domeRadius + ',0' ); 1626 1640 this.domeSvgElement.setAttribute( 'transform', 1627 - 'translate(' + x + ',' + y + ' ) rotate(' + contourAngle + ')' ); 1641 + 'translate(' + x + ',' + y + ' ) rotate(' + contourAngle + ')' ); 1628 1642 } 1629 1643 1630 1644 renderer.stroke( ctx, elem, this.stroke, this.color, this.getLineWidth() ); ··· 1657 1671 ( function( root, factory ) { 1658 1672 // module definition 1659 1673 if ( typeof module == 'object' && module.exports ) { 1660 - /* globals module, require */ // CommonJS 1674 + // CommonJS 1661 1675 module.exports = factory( require('./boilerplate'), 1662 1676 require('./path-command'), require('./shape'), require('./group'), 1663 1677 require('./ellipse') ); ··· 1672 1686 function noop() {} 1673 1687 1674 1688 // ----- CylinderGroup ----- // 1675 - 1689 + 1676 1690 var CylinderGroup = Group.subclass({ 1677 1691 color: '#333', 1678 1692 updateSort: true, ··· 1820 1834 ( function( root, factory ) { 1821 1835 // module definition 1822 1836 if ( typeof module == 'object' && module.exports ) { 1823 - /* globals module, require */ // CommonJS 1837 + // CommonJS 1824 1838 module.exports = factory( require('./boilerplate'), require('./vector'), 1825 1839 require('./path-command'), require('./anchor'), require('./ellipse') ); 1826 1840 } else { ··· 1884 1898 return; 1885 1899 } 1886 1900 // update tangents 1887 - var apexAngle = Math.atan2( this.renderNormal.y, this.renderNormal.x ) + TAU/2; 1901 + var apexAngle = Math.atan2( this.renderNormal.y, this.renderNormal.x ) + 1902 + TAU/2; 1888 1903 var projectLength = apexDistance / eccen; 1889 1904 var projectAngle = Math.acos( radius / projectLength ); 1890 1905 // set tangent points ··· 1944 1959 ( function( root, factory ) { 1945 1960 // module definition 1946 1961 if ( typeof module == 'object' && module.exports ) { 1947 - /* globals module, require */ // CommonJS 1962 + // CommonJS 1948 1963 module.exports = factory( require('./boilerplate'), require('./anchor'), 1949 1964 require('./shape'), require('./rect') ); 1950 1965 } else { ··· 2065 2080 ( function( root, factory ) { 2066 2081 // module definition 2067 2082 if ( typeof module == 'object' && module.exports ) { 2068 - /* globals module, require */ // CommonJS 2083 + // CommonJS 2069 2084 module.exports = factory( 2070 - require('./boilerplate'), 2071 - require('./canvas-renderer'), 2072 - require('./svg-renderer'), 2073 - require('./vector'), 2074 - require('./anchor'), 2075 - require('./dragger'), 2076 - require('./illustration'), 2077 - require('./path-command'), 2078 - require('./shape'), 2079 - require('./group'), 2080 - require('./rect'), 2081 - require('./rounded-rect'), 2082 - require('./ellipse'), 2083 - require('./polygon'), 2084 - require('./hemisphere'), 2085 - require('./cylinder'), 2086 - require('./cone'), 2087 - require('./box') 2085 + require('./boilerplate'), 2086 + require('./canvas-renderer'), 2087 + require('./svg-renderer'), 2088 + require('./vector'), 2089 + require('./anchor'), 2090 + require('./dragger'), 2091 + require('./illustration'), 2092 + require('./path-command'), 2093 + require('./shape'), 2094 + require('./group'), 2095 + require('./rect'), 2096 + require('./rounded-rect'), 2097 + require('./ellipse'), 2098 + require('./polygon'), 2099 + require('./hemisphere'), 2100 + require('./cylinder'), 2101 + require('./cone'), 2102 + require('./box') 2088 2103 ); 2089 2104 } else if ( typeof define == 'function' && define.amd ) { 2090 2105 /* globals define */ // AMD 2091 2106 define( 'zdog', [], root.Zdog ); 2092 2107 } 2093 - })( this, function factory( Zdog ) { 2108 + })( this, function factory( Zdog, CanvasRenderer, SvgRenderer, Vector, Anchor, 2109 + Dragger, Illustration, PathCommand, Shape, Group, Rect, RoundedRect, 2110 + Ellipse, Polygon, Hemisphere, Cylinder, Cone, Box ) { 2094 2111 2095 - return Zdog; 2112 + Zdog.CanvasRenderer = CanvasRenderer; 2113 + Zdog.SvgRenderer = SvgRenderer; 2114 + Zdog.Vector = Vector; 2115 + Zdog.Anchor = Anchor; 2116 + Zdog.Dragger = Dragger; 2117 + Zdog.Illustration = Illustration; 2118 + Zdog.PathCommand = PathCommand; 2119 + Zdog.Shape = Shape; 2120 + Zdog.Group = Group; 2121 + Zdog.Rect = Rect; 2122 + Zdog.RoundedRect = RoundedRect; 2123 + Zdog.Ellipse = Ellipse; 2124 + Zdog.Polygon = Polygon; 2125 + Zdog.Hemisphere = Hemisphere; 2126 + Zdog.Cylinder = Cylinder; 2127 + Zdog.Cone = Cone; 2128 + Zdog.Box = Box; 2096 2129 2130 + return Zdog; 2097 2131 });
+2 -2
dist/zdog.dist.min.js
··· 1 1 /*! 2 - * Zdog v1.0.1 2 + * Zdog v1.0.2 3 3 * Round, flat, designer-friendly pseudo-3D engine 4 4 * Licensed MIT 5 5 * https://zzz.dog 6 6 * Copyright 2019 Metafizzy 7 7 */ 8 - (function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog=e()}})(this,function t(){var e={};e.TAU=Math.PI*2;e.extend=function(t,e){for(var r in e){t[r]=e[r]}return t};e.lerp=function(t,e,r){return(e-t)*r+t};e.modulo=function(t,e){return(t%e+e)%e};var s={2:function(t){return t*t},3:function(t){return t*t*t},4:function(t){return t*t*t*t},5:function(t){return t*t*t*t*t}};e.easeInOut=function(t,e){if(e==1){return t}t=Math.max(0,Math.min(1,t));var r=t<.5;var i=r?t:1-t;i=i/.5;var o=s[e]||s[2];var n=o(i);n=n/2;return r?n:1-n};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog.CanvasRenderer=e()}})(this,function t(){var o={isCanvas:true};o.begin=function(t){t.beginPath()};o.move=function(t,e,r){t.moveTo(r.x,r.y)};o.line=function(t,e,r){t.lineTo(r.x,r.y)};o.bezier=function(t,e,r,i,o){t.bezierCurveTo(r.x,r.y,i.x,i.y,o.x,o.y)};o.closePath=function(t){t.closePath()};o.setPath=function(){};o.renderPath=function(e,r,t,i){this.begin(e,r);t.forEach(function(t){t.render(e,r,o)});if(i){this.closePath(e,r)}};o.stroke=function(t,e,r,i,o){if(!r){return}t.strokeStyle=i;t.lineWidth=o;t.stroke()};o.fill=function(t,e,r,i){if(!r){return}t.fillStyle=i;t.fill()};o.end=function(){};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog.SvgRenderer=e()}})(this,function t(){var n={isSvg:true};var e=n.round=function(t){return Math.round(t*1e3)/1e3};function s(t){return e(t.x)+","+e(t.y)+" "}n.begin=function(){};n.move=function(t,e,r){return"M"+s(r)};n.line=function(t,e,r){return"L"+s(r)};n.bezier=function(t,e,r,i,o){return"C"+s(r)+s(i)+s(o)};n.closePath=function(){return"Z"};n.setPath=function(t,e,r){e.setAttribute("d",r)};n.renderPath=function(e,r,t,i){var o="";t.forEach(function(t){o+=t.render(e,r,n)});if(i){o+=this.closePath(e,r)}this.setPath(e,r,o)};n.stroke=function(t,e,r,i,o){if(!r){return}e.setAttribute("stroke",i);e.setAttribute("stroke-width",o)};n.fill=function(t,e,r,i){var o=r?i:"none";e.setAttribute("fill",o)};n.end=function(t,e){t.appendChild(e)};return n});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"))}else{var r=t.Zdog;r.Vector=e(r)}})(this,function t(r){function e(t){this.set(t)}var h=r.TAU;e.prototype.set=function(t){this.x=t&&t.x||0;this.y=t&&t.y||0;this.z=t&&t.z||0;return this};e.prototype.write=function(t){if(!t){return this}this.x=t.x!=undefined?t.x:this.x;this.y=t.y!=undefined?t.y:this.y;this.z=t.z!=undefined?t.z:this.z;return this};e.prototype.rotate=function(t){if(!t){return}this.rotateZ(t.z);this.rotateY(t.y);this.rotateX(t.x);return this};e.prototype.rotateZ=function(t){i(this,t,"x","y")};e.prototype.rotateX=function(t){i(this,t,"y","z")};e.prototype.rotateY=function(t){i(this,t,"x","z")};function i(t,e,r,i){if(!e||e%h===0){return}var o=Math.cos(e);var n=Math.sin(e);var s=t[r];var a=t[i];t[r]=s*o-a*n;t[i]=a*o+s*n}e.prototype.add=function(t){if(!t){return this}this.x+=t.x||0;this.y+=t.y||0;this.z+=t.z||0;return this};e.prototype.subtract=function(t){if(!t){return this}this.x-=t.x||0;this.y-=t.y||0;this.z-=t.z||0;return this};e.prototype.multiply=function(t){if(t==undefined){return this}if(typeof t=="number"){this.x*=t;this.y*=t;this.z*=t}else{this.x*=t.x!=undefined?t.x:1;this.y*=t.y!=undefined?t.y:1;this.z*=t.z!=undefined?t.z:1}return this};e.prototype.transform=function(t,e,r){this.multiply(r);this.rotate(e);this.add(t);return this};e.prototype.lerp=function(t,e){this.x=r.lerp(this.x,t.x||0,e);this.y=r.lerp(this.y,t.y||0,e);this.z=r.lerp(this.z,t.z||0,e);return this};e.prototype.magnitude=function(){var t=this.x*this.x+this.y*this.y+this.z*this.z;return o(t)};function o(t){if(Math.abs(t-1)<1e-8){return 1}return Math.sqrt(t)}e.prototype.magnitude2d=function(){var t=this.x*this.x+this.y*this.y;return o(t)};e.prototype.copy=function(){return new e(this)};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"))}else{var r=t.Zdog;r.Anchor=e(r,r.Vector)}})(this,function t(o,e){var r=o.TAU;var i={x:1,y:1,z:1};function n(t){this.create(t||{})}n.prototype.create=function(t){o.extend(this,this.constructor.defaults);this.setOptions(t);this.translate=new e(t.translate);this.rotate=new e(t.rotate);this.scale=new e(i).multiply(this.scale);this.origin=new e;this.renderOrigin=new e;this.children=[];if(this.addTo){this.addTo.addChild(this)}};n.defaults={};n.optionKeys=Object.keys(n.defaults).concat(["rotate","translate","scale","addTo"]);n.prototype.setOptions=function(t){var e=this.constructor.optionKeys;for(var r in t){if(e.includes(r)){this[r]=t[r]}}};n.prototype.addChild=function(t){var e=this.children.indexOf(t);if(e!=-1){return}t.remove();t.addTo=this;this.children.push(t)};n.prototype.removeChild=function(t){var e=this.children.indexOf(t);if(e!=-1){this.children.splice(e,1)}};n.prototype.remove=function(){if(this.addTo){this.addTo.removeChild(this)}};n.prototype.update=function(){this.reset();this.children.forEach(function(t){t.update()});this.transform(this.translate,this.rotate,this.scale)};n.prototype.reset=function(){this.renderOrigin.set(this.origin)};n.prototype.transform=function(e,r,i){this.renderOrigin.transform(e,r,i);this.children.forEach(function(t){t.transform(e,r,i)})};n.prototype.updateGraph=function(){this.update();this.checkFlatGraph();this.flatGraph.forEach(function(t){t.updateSortValue()});this.flatGraph.sort(n.shapeSorter)};n.shapeSorter=function(t,e){return t.sortValue-e.sortValue};n.prototype.checkFlatGraph=function(){if(!this.flatGraph){this.updateFlatGraph()}};n.prototype.updateFlatGraph=function(){this.flatGraph=this.getFlatGraph()};n.prototype.getFlatGraph=function(){var r=[this];this.children.forEach(function(t){var e=t.getFlatGraph();r=r.concat(e)});return r};n.prototype.updateSortValue=function(){this.sortValue=this.renderOrigin.z};n.prototype.render=function(){};n.prototype.renderGraphCanvas=function(e){if(!e){throw new Error("ctx is "+e+". "+"Canvas context required for render. Check .renderGraphCanvas( ctx ).")}this.checkFlatGraph();this.flatGraph.forEach(function(t){t.render(e,Zdog.CanvasRenderer)})};n.prototype.renderGraphSvg=function(e){if(!e){throw new Error("svg is "+e+". "+"SVG required for render. Check .renderGraphSvg( svg ).")}this.checkFlatGraph();this.flatGraph.forEach(function(t){t.render(e,Zdog.SvgRenderer)})};n.prototype.copy=function(t){var e={};var r=this.constructor.optionKeys;r.forEach(function(t){e[t]=this[t]},this);o.extend(e,t);var i=this.constructor;return new i(e)};n.prototype.copyGraph=function(t){var e=this.copy(t);this.children.forEach(function(t){t.copyGraph({addTo:e})});return e};n.prototype.normalizeRotate=function(){this.rotate.x=o.modulo(this.rotate.x,r);this.rotate.y=o.modulo(this.rotate.y,r);this.rotate.z=o.modulo(this.rotate.z,r)};function s(r){return function(t){function e(t){this.create(t||{})}e.prototype=Object.create(r.prototype);e.prototype.constructor=e;e.defaults=o.extend({},r.defaults);o.extend(e.defaults,t);e.optionKeys=r.optionKeys.slice(0);Object.keys(e.defaults).forEach(function(t){if(!e.optionKeys.includes(t)){e.optionKeys.push(t)}});e.subclass=s(e);return e}}n.subclass=s(n);return n});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog.Dragger=e()}})(this,function t(){var e="mousedown";var r="mousemove";var i="mouseup";if(window.PointerEvent){e="pointerdown";r="pointermove";i="pointerup"}else if("ontouchstart"in window){e="touchstart";r="touchmove";i="touchend"}function o(){}function n(t){this.create(t||{})}n.prototype.create=function(t){this.onDragStart=t.onDragStart||o;this.onDragMove=t.onDragMove||o;this.onDragEnd=t.onDragEnd||o;this.bindDrag(t.startElement)};n.prototype.bindDrag=function(t){t=this.getQueryElement(t);if(t){t.addEventListener(e,this)}};n.prototype.getQueryElement=function(t){if(typeof t=="string"){t=document.querySelector(t)}return t};n.prototype.handleEvent=function(t){var e=this["on"+t.type];if(e){e.call(this,t)}};n.prototype.onmousedown=n.prototype.onpointerdown=function(t){this.dragStart(t,t)};n.prototype.ontouchstart=function(t){this.dragStart(t,t.changedTouches[0])};n.prototype.dragStart=function(t,e){t.preventDefault();this.dragStartX=e.pageX;this.dragStartY=e.pageY;window.addEventListener(r,this);window.addEventListener(i,this);this.onDragStart(e)};n.prototype.ontouchmove=function(t){this.dragMove(t,t.changedTouches[0])};n.prototype.onmousemove=n.prototype.onpointermove=function(t){this.dragMove(t,t)};n.prototype.dragMove=function(t,e){t.preventDefault();var r=e.pageX-this.dragStartX;var i=e.pageY-this.dragStartY;this.onDragMove(e,r,i)};n.prototype.onmouseup=n.prototype.onpointerup=n.prototype.ontouchend=n.prototype.dragEnd=function(){window.removeEventListener(r,this);window.removeEventListener(i,this);this.onDragEnd()};return n});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./anchor"),require("./dragger"))}else{var r=t.Zdog;r.Illustration=e(r,r.Anchor,r.Dragger)}})(this,function t(e,r,a){function i(){}var h=e.TAU;var o=r.subclass({element:undefined,centered:true,zoom:1,dragRotate:false,resize:false,onPrerender:i,onDragStart:i,onDragMove:i,onDragEnd:i,onResize:i});e.extend(o.prototype,a.prototype);o.prototype.create=function(t){r.prototype.create.call(this,t);a.prototype.create.call(this,t);this.setElement(this.element);this.setDragRotate(this.dragRotate);this.setResize(this.resize)};o.prototype.setElement=function(t){t=this.getQueryElement(t);if(!t){throw new Error("Zdog.Illustration element required. Set to "+t)}var e=t.nodeName.toLowerCase();if(e=="canvas"){this.setCanvas(t)}else if(e=="svg"){this.setSvg(t)}};o.prototype.setSize=function(t,e){t=Math.round(t);e=Math.round(e);if(this.isCanvas){this.setSizeCanvas(t,e)}else if(this.isSvg){this.setSizeSvg(t,e)}};o.prototype.setResize=function(t){this.resize=t;if(!this.resizeListener){this.resizeListener=this.onWindowResize.bind(this)}if(t){window.addEventListener("resize",this.resizeListener);this.onWindowResize()}else{window.removeEventListener("resize",this.resizeListener)}};o.prototype.onWindowResize=function(){this.setMeasuredSize();this.onResize(this.width,this.height)};o.prototype.setMeasuredSize=function(){var t,e;var r=this.resize=="fullscreen";if(r){t=window.innerWidth;e=window.innerHeight}else{var i=this.element.getBoundingClientRect();t=i.width;e=i.height}this.setSize(t,e)};o.prototype.renderGraph=function(t){if(this.isCanvas){this.renderGraphCanvas(t)}else if(this.isSvg){this.renderGraphSvg(t)}};o.prototype.updateRenderGraph=function(t){this.updateGraph();this.renderGraph(t)};o.prototype.setCanvas=function(t){this.element=t;this.isCanvas=true;this.ctx=this.element.getContext("2d");this.setSizeCanvas(t.width,t.height)};o.prototype.setSizeCanvas=function(t,e){this.width=t;this.height=e;var r=this.pixelRatio=window.devicePixelRatio||1;this.element.width=this.canvasWidth=t*r;this.element.height=this.canvasHeight=e*r;if(r>1){this.element.style.width=t+"px";this.element.style.height=e+"px"}};o.prototype.renderGraphCanvas=function(t){t=t||this;this.prerenderCanvas();r.prototype.renderGraphCanvas.call(t,this.ctx);this.postrenderCanvas()};o.prototype.prerenderCanvas=function(){var t=this.ctx;t.lineCap="round";t.lineJoin="round";t.clearRect(0,0,this.canvasWidth,this.canvasHeight);t.save();if(this.centered){var e=this.width/2*this.pixelRatio;var r=this.height/2*this.pixelRatio;t.translate(e,r)}var i=this.pixelRatio*this.zoom;t.scale(i,i);this.onPrerender(t)};o.prototype.postrenderCanvas=function(){this.ctx.restore()};o.prototype.setSvg=function(t){this.element=t;this.isSvg=true;this.pixelRatio=1;var e=t.getAttribute("width");var r=t.getAttribute("height");this.setSizeSvg(e,r)};o.prototype.setSizeSvg=function(t,e){this.width=t;this.height=e;var r=t/this.zoom;var i=e/this.zoom;var o=this.centered?-r/2:0;var n=this.centered?-i/2:0;this.element.setAttribute("viewBox",o+" "+n+" "+r+" "+i);if(this.resize){this.element.removeAttribute("width");this.element.removeAttribute("height")}else{this.element.setAttribute("width",t);this.element.setAttribute("height",e)}};o.prototype.renderGraphSvg=function(t){t=t||this;n(this.element);this.onPrerender(this.element);r.prototype.renderGraphSvg.call(t,this.element)};function n(t){while(t.firstChild){t.removeChild(t.firstChild)}}o.prototype.setDragRotate=function(t){if(!t){return}else if(t===true){t=this}this.dragRotate=t;this.bindDrag(this.element)};o.prototype.dragStart=function(){this.dragStartRX=this.dragRotate.rotate.x;this.dragStartRY=this.dragRotate.rotate.y;a.prototype.dragStart.apply(this,arguments)};o.prototype.dragMove=function(t,e){var r=e.pageX-this.dragStartX;var i=e.pageY-this.dragStartY;var o=Math.min(this.width,this.height);var n=r/o*h;var s=i/o*h;this.dragRotate.rotate.x=this.dragStartRX-s;this.dragRotate.rotate.y=this.dragStartRY-n;a.prototype.dragMove.apply(this,arguments)};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./vector"))}else{var r=t.Zdog;r.PathCommand=e(r.Vector)}})(this,function t(i){function e(t,e,r){this.method=t;this.points=e.map(o);this.renderPoints=e.map(n);this.previousPoint=r;this.endRenderPoint=this.renderPoints[this.renderPoints.length-1];if(t=="arc"){this.controlPoints=[new i,new i]}}function o(t){if(t instanceof i){return t}else{return new i(t)}}function n(t){return new i(t)}e.prototype.reset=function(){var i=this.points;this.renderPoints.forEach(function(t,e){var r=i[e];t.set(r)})};e.prototype.transform=function(e,r,i){this.renderPoints.forEach(function(t){t.transform(e,r,i)})};e.prototype.render=function(t,e,r){return this[this.method](t,e,r)};e.prototype.move=function(t,e,r){return r.move(t,e,this.renderPoints[0])};e.prototype.line=function(t,e,r){return r.line(t,e,this.renderPoints[0])};e.prototype.bezier=function(t,e,r){var i=this.renderPoints[0];var o=this.renderPoints[1];var n=this.renderPoints[2];return r.bezier(t,e,i,o,n)};e.prototype.arc=function(t,e,r){var i=this.previousPoint;var o=this.renderPoints[0];var n=this.renderPoints[1];var s=this.controlPoints[0];var a=this.controlPoints[1];s.set(i).lerp(o,9/16);a.set(n).lerp(o,9/16);return r.bezier(t,e,s,a,n)};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"),require("./path-command"),require("./anchor"))}else{var r=t.Zdog;r.Shape=e(r,r.Vector,r.PathCommand,r.Anchor)}})(this,function t(e,r,p,i){var o=i.subclass({stroke:1,fill:false,color:"#333",closed:true,visible:true,path:[{}],front:{z:1},backface:true});o.prototype.create=function(t){i.prototype.create.call(this,t);this.updatePath();this.front=new r(t.front||this.front);this.renderFront=new r(this.front);this.renderNormal=new r};var d=["move","line","bezier","arc"];o.prototype.updatePath=function(){this.setPath();this.updatePathCommands()};o.prototype.setPath=function(){};o.prototype.updatePathCommands=function(){var u;this.pathCommands=this.path.map(function(t,e){var r=Object.keys(t);var i=r[0];var o=t[i];var n=r.length==1&&d.includes(i);if(!n){i="line";o=t}var s=i=="line"||i=="move";var a=Array.isArray(o);if(s&&!a){o=[o]}i=e===0?"move":i;var h=new p(i,o,u);u=h.endRenderPoint;return h})};o.prototype.reset=function(){this.renderOrigin.set(this.origin);this.renderFront.set(this.front);this.pathCommands.forEach(function(t){t.reset()})};o.prototype.transform=function(e,r,i){this.renderOrigin.transform(e,r,i);this.renderFront.transform(e,r,i);this.renderNormal.set(this.renderOrigin).subtract(this.renderFront);this.pathCommands.forEach(function(t){t.transform(e,r,i)});this.children.forEach(function(t){t.transform(e,r,i)})};o.prototype.updateSortValue=function(){var e=0;this.pathCommands.forEach(function(t){e+=t.endRenderPoint.z});this.sortValue=e/this.pathCommands.length};o.prototype.render=function(t,e){var r=this.pathCommands.length;if(!this.visible||!r){return}this.isFacingBack=this.renderNormal.z>0;if(!this.backface&&this.isFacingBack){return}if(!e){throw new Error("Zdog renderer required. Set to "+e)}var i=r==1;if(e.isCanvas&&i){this.renderCanvasDot(t,e)}else{this.renderPath(t,e)}};var n=e.TAU;o.prototype.renderCanvasDot=function(t){var e=this.getLineWidth();if(!e){return}t.fillStyle=this.getRenderColor();var r=this.pathCommands[0].endRenderPoint;t.beginPath();var i=e/2;t.arc(r.x,r.y,i,0,n);t.fill()};o.prototype.getLineWidth=function(){if(!this.stroke){return 0}if(this.stroke==true){return 1}return this.stroke};o.prototype.getRenderColor=function(){var t=typeof this.backface=="string"&&this.isFacingBack;var e=t?this.backface:this.color;return e};o.prototype.renderPath=function(t,e){var r=this.getRenderElement(t,e);var i=this.pathCommands.length==2&&this.pathCommands[1].method=="line";var o=!i&&this.closed;var n=this.getRenderColor();e.renderPath(t,r,this.pathCommands,o);e.stroke(t,r,this.stroke,n,this.getLineWidth());e.fill(t,r,this.fill,n);e.end(t,r)};var s="http://www.w3.org/2000/svg";o.prototype.getRenderElement=function(t,e){if(!e.isSvg){return}if(!this.svgElement){this.svgElement=document.createElementNS(s,"path");this.svgElement.setAttribute("stroke-linecap","round");this.svgElement.setAttribute("stroke-linejoin","round")}return this.svgElement};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./anchor"))}else{var r=t.Zdog;r.Group=e(r.Anchor)}})(this,function t(r){var e=r.subclass({updateSort:false,visible:true});e.prototype.updateSortValue=function(){var e=0;this.checkFlatGraph();this.flatGraph.forEach(function(t){t.updateSortValue();e+=t.sortValue});this.sortValue=e/this.flatGraph.length;if(this.updateSort){this.flatGraph.sort(r.shapeSorter)}};e.prototype.render=function(e,r){if(!this.visible){return}this.checkFlatGraph();this.flatGraph.forEach(function(t){t.render(e,r)})};e.prototype.getFlatGraph=function(){return[this]};e.prototype.updateFlatGraph=function(){var r=[];this.children.forEach(function(t){var e=t.getFlatGraph();r=r.concat(e)});this.flatGraph=r};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.Rect=e(r.Shape)}})(this,function t(e){var r=e.subclass({width:1,height:1});r.prototype.setPath=function(){var t=this.width/2;var e=this.height/2;this.path=[{x:-t,y:-e},{x:t,y:-e},{x:t,y:e},{x:-t,y:e}]};return r});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.RoundedRect=e(r.Shape)}})(this,function t(r){var e=r.subclass({width:1,height:1,cornerRadius:.25,closed:false});e.prototype.setPath=function(){var t=this.width/2;var e=this.height/2;var r=Math.min(t,e);var i=Math.min(this.cornerRadius,r);var o=t-i;var n=e-i;var s=[{x:o,y:-e},{arc:[{x:t,y:-e},{x:t,y:-n}]}];if(n){s.push({x:t,y:n})}s.push({arc:[{x:t,y:e},{x:o,y:e}]});if(o){s.push({x:-o,y:e})}s.push({arc:[{x:-t,y:e},{x:-t,y:n}]});if(n){s.push({x:-t,y:-n})}s.push({arc:[{x:-t,y:-e},{x:-o,y:-e}]});if(o){s.push({x:o,y:-e})}this.path=s};e.prototype.updateSortValue=function(){r.prototype.updateSortValue.apply(this,arguments);var t=this.pathCommands.length;var e=this.pathCommands[t-1].endRenderPoint;this.sortValue-=e.z/t};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.Ellipse=e(r.Shape)}})(this,function t(r){var e=r.subclass({diameter:1,width:undefined,height:undefined,quarters:4,closed:false});e.prototype.setPath=function(){var t=this.width!=undefined?this.width:this.diameter;var e=this.height!=undefined?this.height:this.diameter;var r=t/2;var i=e/2;this.path=[{x:0,y:-i},{arc:[{x:r,y:-i},{x:r,y:0}]}];if(this.quarters>1){this.path.push({arc:[{x:r,y:i},{x:0,y:i}]})}if(this.quarters>2){this.path.push({arc:[{x:-r,y:i},{x:-r,y:0}]})}if(this.quarters>3){this.path.push({arc:[{x:-r,y:-i},{x:0,y:-i}]})}};e.prototype.updateSortValue=function(){r.prototype.updateSortValue.apply(this,arguments);if(this.quarters!=4){return}var t=this.pathCommands.length;var e=this.pathCommands[t-1].endRenderPoint;this.sortValue-=e.z/t};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./shape"))}else{var r=t.Zdog;r.Polygon=e(r,r.Shape)}})(this,function t(e,r){var i=r.subclass({sides:3,radius:.5});var o=e.TAU;i.prototype.setPath=function(){this.path=[];for(var t=0;t<this.sides;t++){var e=t/this.sides*o-o/4;var r=Math.cos(e)*this.radius;var i=Math.sin(e)*this.radius;this.path.push({x:r,y:i})}};return i});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./ellipse"))}else{var r=t.Zdog;r.Hemisphere=e(r,r.Ellipse)}})(this,function t(e,r){var i=r.subclass({fill:true});var u=e.TAU;i.prototype.render=function(t,e){this.renderDome(t,e);r.prototype.render.apply(this,arguments)};i.prototype.renderDome=function(t,e){if(!this.visible){return}var r=this.getDomeRenderElement(t,e);var i=Math.atan2(this.renderNormal.y,this.renderNormal.x);var o=this.diameter/2*this.renderNormal.magnitude();var n=this.renderOrigin.x;var s=this.renderOrigin.y;if(e.isCanvas){var a=i+u/4;var h=i-u/4;t.beginPath();t.arc(n,s,o,a,h)}else if(e.isSvg){i=(i-u/4)/u*360;this.domeSvgElement.setAttribute("d","M "+-o+",0 A "+o+","+o+" 0 0 1 "+o+",0");this.domeSvgElement.setAttribute("transform","translate("+n+","+s+" ) rotate("+i+")")}e.stroke(t,r,this.stroke,this.color,this.getLineWidth());e.fill(t,r,this.fill,this.color);e.end(t,r)};var o="http://www.w3.org/2000/svg";i.prototype.getDomeRenderElement=function(t,e){if(!e.isSvg){return}if(!this.domeSvgElement){this.domeSvgElement=document.createElementNS(o,"path");this.domeSvgElement.setAttribute("stroke-linecap","round");this.domeSvgElement.setAttribute("stroke-linejoin","round")}return this.domeSvgElement};return i});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./path-command"),require("./shape"),require("./group"),require("./ellipse"))}else{var r=t.Zdog;r.Cylinder=e(r,r.PathCommand,r.Shape,r.Group,r.Ellipse)}})(this,function t(e,r,i,o,n){function s(){}var a=o.subclass({color:"#333",updateSort:true});a.prototype.create=function(){o.prototype.create.apply(this,arguments);this.pathCommands=[new r("move",[{}]),new r("line",[{}])]};a.prototype.render=function(t,e){this.renderCylinderSurface(t,e);o.prototype.render.apply(this,arguments)};a.prototype.renderCylinderSurface=function(t,e){if(!this.visible){return}var r=this.getRenderElement(t,e);var i=this.frontBase;var o=this.rearBase;var n=i.renderNormal.magnitude();var s=i.diameter*n+i.getLineWidth();this.pathCommands[0].renderPoints[0].set(i.renderOrigin);this.pathCommands[1].renderPoints[0].set(o.renderOrigin);if(e.isCanvas){t.lineCap="butt"}e.renderPath(t,r,this.pathCommands);e.stroke(t,r,true,this.color,s);e.end(t,r);if(e.isCanvas){t.lineCap="round"}};var h="http://www.w3.org/2000/svg";a.prototype.getRenderElement=function(t,e){if(!e.isSvg){return}if(!this.svgElement){this.svgElement=document.createElementNS(h,"path")}return this.svgElement};a.prototype.copyGraph=s;var u=n.subclass();u.prototype.copyGraph=s;var p=i.subclass({diameter:1,length:1,frontFace:undefined,fill:true});var d=e.TAU;p.prototype.create=function(){i.prototype.create.apply(this,arguments);this.group=new a({addTo:this,color:this.color,visible:this.visible});var t=this.length/2;var e=this.backface||true;this.frontBase=this.group.frontBase=new n({addTo:this.group,diameter:this.diameter,translate:{z:t},rotate:{y:d/2},color:this.color,stroke:this.stroke,fill:this.fill,backface:this.frontFace||e,visible:this.visible});this.rearBase=this.group.rearBase=this.frontBase.copy({translate:{z:-t},rotate:{y:0},backface:e})};p.prototype.render=function(){};var c=["stroke","fill","color","visible"];c.forEach(function(e){var r="_"+e;Object.defineProperty(p.prototype,e,{get:function(){return this[r]},set:function(t){this[r]=t;if(this.frontBase){this.frontBase[e]=t;this.rearBase[e]=t;this.group[e]=t}}})});return p});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"),require("./path-command"),require("./anchor"),require("./ellipse"))}else{var r=t.Zdog;r.Cone=e(r,r.Vector,r.PathCommand,r.Anchor,r.Ellipse)}})(this,function t(e,r,i,o,n){var s=n.subclass({length:1,fill:true});var v=e.TAU;s.prototype.create=function(){n.prototype.create.apply(this,arguments);this.apex=new o({addTo:this,translate:{z:this.length}});this.renderApex=new r;this.tangentA=new r;this.tangentB=new r;this.surfacePathCommands=[new i("move",[{}]),new i("line",[{}]),new i("line",[{}])]};s.prototype.render=function(t,e){this.renderConeSurface(t,e);n.prototype.render.apply(this,arguments)};s.prototype.renderConeSurface=function(t,e){if(!this.visible){return}this.renderApex.set(this.apex.renderOrigin).subtract(this.renderOrigin);var r=this.renderNormal.magnitude();var i=this.renderApex.magnitude2d();var o=this.renderNormal.magnitude2d();var n=Math.acos(o/r);var s=Math.sin(n);var a=this.diameter/2*r;var h=a*s<i;if(!h){return}var u=Math.atan2(this.renderNormal.y,this.renderNormal.x)+v/2;var p=i/s;var d=Math.acos(a/p);var c=this.tangentA;var l=this.tangentB;c.x=Math.cos(d)*a*s;c.y=Math.sin(d)*a;l.set(this.tangentA);l.y*=-1;c.rotateZ(u);l.rotateZ(u);c.add(this.renderOrigin);l.add(this.renderOrigin);this.setSurfaceRenderPoint(0,c);this.setSurfaceRenderPoint(1,this.apex.renderOrigin);this.setSurfaceRenderPoint(2,l);var f=this.getSurfaceRenderElement(t,e);e.renderPath(t,f,this.surfacePathCommands);e.stroke(t,f,this.stroke,this.color,this.getLineWidth());e.fill(t,f,this.fill,this.color);e.end(t,f)};var a="http://www.w3.org/2000/svg";s.prototype.getSurfaceRenderElement=function(t,e){if(!e.isSvg){return}if(!this.surfaceSvgElement){this.surfaceSvgElement=document.createElementNS(a,"path");this.surfaceSvgElement.setAttribute("stroke-linecap","round");this.surfaceSvgElement.setAttribute("stroke-linejoin","round")}return this.surfaceSvgElement};s.prototype.setSurfaceRenderPoint=function(t,e){var r=this.surfacePathCommands[t].renderPoints[0];r.set(e)};return s});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./anchor"),require("./shape"),require("./rect"))}else{var r=t.Zdog;r.Box=e(r,r.Anchor,r.Shape,r.Rect)}})(this,function t(n,e,r,i){var s=i.subclass();s.prototype.copyGraph=function(){};var o=n.extend({width:1,height:1,depth:1,frontFace:true,rearFace:true,leftFace:true,rightFace:true,topFace:true,bottomFace:true},r.defaults);o.fill=true;delete o.path;var a=e.subclass(o);var h=n.TAU;a.prototype.create=function(t){e.prototype.create.call(this,t);this.updatePath()};a.prototype.updatePath=function(){this.setFace("frontFace",{width:this.width,height:this.height,translate:{z:this.depth/2}});this.setFace("rearFace",{width:this.width,height:this.height,translate:{z:-this.depth/2},rotate:{y:h/2}});this.setFace("leftFace",{width:this.depth,height:this.height,translate:{x:-this.width/2},rotate:{y:-h/4}});this.setFace("rightFace",{width:this.depth,height:this.height,translate:{x:this.width/2},rotate:{y:h/4}});this.setFace("topFace",{width:this.width,height:this.depth,translate:{y:-this.height/2},rotate:{x:-h/4}});this.setFace("bottomFace",{width:this.width,height:this.depth,translate:{y:this.height/2},rotate:{x:-h/4}})};a.prototype.setFace=function(t,e){var r=this[t];var i=t+"Rect";var o=this[i];if(!r){this.removeChild(o);return}n.extend(e,{color:typeof r=="string"?r:this.color,stroke:this.stroke,fill:this.fill,backface:this.backface,front:this.front,visible:this.visible});if(o){o.setOptions(e)}else{o=this[i]=new s(e)}o.updatePath();this.addChild(o)};return a});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./canvas-renderer"),require("./svg-renderer"),require("./vector"),require("./anchor"),require("./dragger"),require("./illustration"),require("./path-command"),require("./shape"),require("./group"),require("./rect"),require("./rounded-rect"),require("./ellipse"),require("./polygon"),require("./hemisphere"),require("./cylinder"),require("./cone"),require("./box"))}else if(typeof define=="function"&&define.amd){define("zdog",[],t.Zdog)}})(this,function t(e){return e}); 8 + (function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog=e()}})(this,function t(){var e={};e.TAU=Math.PI*2;e.extend=function(t,e){for(var r in e){t[r]=e[r]}return t};e.lerp=function(t,e,r){return(e-t)*r+t};e.modulo=function(t,e){return(t%e+e)%e};var s={2:function(t){return t*t},3:function(t){return t*t*t},4:function(t){return t*t*t*t},5:function(t){return t*t*t*t*t}};e.easeInOut=function(t,e){if(e==1){return t}t=Math.max(0,Math.min(1,t));var r=t<.5;var i=r?t:1-t;i/=.5;var o=s[e]||s[2];var n=o(i);n/=2;return r?n:1-n};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog.CanvasRenderer=e()}})(this,function t(){var o={isCanvas:true};o.begin=function(t){t.beginPath()};o.move=function(t,e,r){t.moveTo(r.x,r.y)};o.line=function(t,e,r){t.lineTo(r.x,r.y)};o.bezier=function(t,e,r,i,o){t.bezierCurveTo(r.x,r.y,i.x,i.y,o.x,o.y)};o.closePath=function(t){t.closePath()};o.setPath=function(){};o.renderPath=function(e,r,t,i){this.begin(e,r);t.forEach(function(t){t.render(e,r,o)});if(i){this.closePath(e,r)}};o.stroke=function(t,e,r,i,o){if(!r){return}t.strokeStyle=i;t.lineWidth=o;t.stroke()};o.fill=function(t,e,r,i){if(!r){return}t.fillStyle=i;t.fill()};o.end=function(){};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Zdog.SvgRenderer=e()}})(this,function t(){var n={isSvg:true};var e=n.round=function(t){return Math.round(t*1e3)/1e3};function s(t){return e(t.x)+","+e(t.y)+" "}n.begin=function(){};n.move=function(t,e,r){return"M"+s(r)};n.line=function(t,e,r){return"L"+s(r)};n.bezier=function(t,e,r,i,o){return"C"+s(r)+s(i)+s(o)};n.closePath=function(){return"Z"};n.setPath=function(t,e,r){e.setAttribute("d",r)};n.renderPath=function(e,r,t,i){var o="";t.forEach(function(t){o+=t.render(e,r,n)});if(i){o+=this.closePath(e,r)}this.setPath(e,r,o)};n.stroke=function(t,e,r,i,o){if(!r){return}e.setAttribute("stroke",i);e.setAttribute("stroke-width",o)};n.fill=function(t,e,r,i){var o=r?i:"none";e.setAttribute("fill",o)};n.end=function(t,e){t.appendChild(e)};return n});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"))}else{var r=t.Zdog;r.Vector=e(r)}})(this,function t(r){function e(t){this.set(t)}var h=r.TAU;e.prototype.set=function(t){this.x=t&&t.x||0;this.y=t&&t.y||0;this.z=t&&t.z||0;return this};e.prototype.write=function(t){if(!t){return this}this.x=t.x!=undefined?t.x:this.x;this.y=t.y!=undefined?t.y:this.y;this.z=t.z!=undefined?t.z:this.z;return this};e.prototype.rotate=function(t){if(!t){return}this.rotateZ(t.z);this.rotateY(t.y);this.rotateX(t.x);return this};e.prototype.rotateZ=function(t){i(this,t,"x","y")};e.prototype.rotateX=function(t){i(this,t,"y","z")};e.prototype.rotateY=function(t){i(this,t,"x","z")};function i(t,e,r,i){if(!e||e%h===0){return}var o=Math.cos(e);var n=Math.sin(e);var s=t[r];var a=t[i];t[r]=s*o-a*n;t[i]=a*o+s*n}e.prototype.add=function(t){if(!t){return this}this.x+=t.x||0;this.y+=t.y||0;this.z+=t.z||0;return this};e.prototype.subtract=function(t){if(!t){return this}this.x-=t.x||0;this.y-=t.y||0;this.z-=t.z||0;return this};e.prototype.multiply=function(t){if(t==undefined){return this}if(typeof t=="number"){this.x*=t;this.y*=t;this.z*=t}else{this.x*=t.x!=undefined?t.x:1;this.y*=t.y!=undefined?t.y:1;this.z*=t.z!=undefined?t.z:1}return this};e.prototype.transform=function(t,e,r){this.multiply(r);this.rotate(e);this.add(t);return this};e.prototype.lerp=function(t,e){this.x=r.lerp(this.x,t.x||0,e);this.y=r.lerp(this.y,t.y||0,e);this.z=r.lerp(this.z,t.z||0,e);return this};e.prototype.magnitude=function(){var t=this.x*this.x+this.y*this.y+this.z*this.z;return o(t)};function o(t){if(Math.abs(t-1)<1e-8){return 1}return Math.sqrt(t)}e.prototype.magnitude2d=function(){var t=this.x*this.x+this.y*this.y;return o(t)};e.prototype.copy=function(){return new e(this)};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"),require("./canvas-renderer"),require("./svg-renderer"))}else{var r=t.Zdog;r.Anchor=e(r,r.Vector,r.CanvasRenderer,r.SvgRenderer)}})(this,function t(o,e,r,i){var n=o.TAU;var s={x:1,y:1,z:1};function a(t){this.create(t||{})}a.prototype.create=function(t){o.extend(this,this.constructor.defaults);this.setOptions(t);this.translate=new e(t.translate);this.rotate=new e(t.rotate);this.scale=new e(s).multiply(this.scale);this.origin=new e;this.renderOrigin=new e;this.children=[];if(this.addTo){this.addTo.addChild(this)}};a.defaults={};a.optionKeys=Object.keys(a.defaults).concat(["rotate","translate","scale","addTo"]);a.prototype.setOptions=function(t){var e=this.constructor.optionKeys;for(var r in t){if(e.includes(r)){this[r]=t[r]}}};a.prototype.addChild=function(t){var e=this.children.indexOf(t);if(e!=-1){return}t.remove();t.addTo=this;this.children.push(t)};a.prototype.removeChild=function(t){var e=this.children.indexOf(t);if(e!=-1){this.children.splice(e,1)}};a.prototype.remove=function(){if(this.addTo){this.addTo.removeChild(this)}};a.prototype.update=function(){this.reset();this.children.forEach(function(t){t.update()});this.transform(this.translate,this.rotate,this.scale)};a.prototype.reset=function(){this.renderOrigin.set(this.origin)};a.prototype.transform=function(e,r,i){this.renderOrigin.transform(e,r,i);this.children.forEach(function(t){t.transform(e,r,i)})};a.prototype.updateGraph=function(){this.update();this.updateFlatGraph();this.flatGraph.forEach(function(t){t.updateSortValue()});this.flatGraph.sort(a.shapeSorter)};a.shapeSorter=function(t,e){return t.sortValue-e.sortValue};Object.defineProperty(a.prototype,"flatGraph",{get:function(){if(!this._flatGraph){this.updateFlatGraph()}return this._flatGraph},set:function(t){this._flatGraph=t}});a.prototype.updateFlatGraph=function(){this.flatGraph=this.getFlatGraph()};a.prototype.getFlatGraph=function(){var t=[this];return this.addChildFlatGraph(t)};a.prototype.addChildFlatGraph=function(r){this.children.forEach(function(t){var e=t.getFlatGraph();Array.prototype.push.apply(r,e)});return r};a.prototype.updateSortValue=function(){this.sortValue=this.renderOrigin.z};a.prototype.render=function(){};a.prototype.renderGraphCanvas=function(e){if(!e){throw new Error("ctx is "+e+". "+"Canvas context required for render. Check .renderGraphCanvas( ctx ).")}this.flatGraph.forEach(function(t){t.render(e,r)})};a.prototype.renderGraphSvg=function(e){if(!e){throw new Error("svg is "+e+". "+"SVG required for render. Check .renderGraphSvg( svg ).")}this.checkFlatGraph();this.flatGraph.forEach(function(t){t.render(e,i)})};a.prototype.copy=function(t){var e={};var r=this.constructor.optionKeys;r.forEach(function(t){e[t]=this[t]},this);o.extend(e,t);var i=this.constructor;return new i(e)};a.prototype.copyGraph=function(t){var e=this.copy(t);this.children.forEach(function(t){t.copyGraph({addTo:e})});return e};a.prototype.normalizeRotate=function(){this.rotate.x=o.modulo(this.rotate.x,n);this.rotate.y=o.modulo(this.rotate.y,n);this.rotate.z=o.modulo(this.rotate.z,n)};function h(r){return function(t){function e(t){this.create(t||{})}e.prototype=Object.create(r.prototype);e.prototype.constructor=e;e.defaults=o.extend({},r.defaults);o.extend(e.defaults,t);e.optionKeys=r.optionKeys.slice(0);Object.keys(e.defaults).forEach(function(t){if(!e.optionKeys.includes(t)){e.optionKeys.push(t)}});e.subclass=h(e);return e}}a.subclass=h(a);return a});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(t)}else{t.Zdog.Dragger=e(t)}})(this,function t(r){var e="mousedown";var i="mousemove";var o="mouseup";if(r.PointerEvent){e="pointerdown";i="pointermove";o="pointerup"}else if("ontouchstart"in r){e="touchstart";i="touchmove";o="touchend"}function n(){}function s(t){this.create(t||{})}s.prototype.create=function(t){this.onDragStart=t.onDragStart||n;this.onDragMove=t.onDragMove||n;this.onDragEnd=t.onDragEnd||n;this.bindDrag(t.startElement)};s.prototype.bindDrag=function(t){t=this.getQueryElement(t);if(t){t.addEventListener(e,this)}};s.prototype.getQueryElement=function(t){if(typeof t=="string"){t=document.querySelector(t)}return t};s.prototype.handleEvent=function(t){var e=this["on"+t.type];if(e){e.call(this,t)}};s.prototype.onmousedown=s.prototype.onpointerdown=function(t){this.dragStart(t,t)};s.prototype.ontouchstart=function(t){this.dragStart(t,t.changedTouches[0])};s.prototype.dragStart=function(t,e){t.preventDefault();this.dragStartX=e.pageX;this.dragStartY=e.pageY;r.addEventListener(i,this);r.addEventListener(o,this);this.onDragStart(e)};s.prototype.ontouchmove=function(t){this.dragMove(t,t.changedTouches[0])};s.prototype.onmousemove=s.prototype.onpointermove=function(t){this.dragMove(t,t)};s.prototype.dragMove=function(t,e){t.preventDefault();var r=e.pageX-this.dragStartX;var i=e.pageY-this.dragStartY;this.onDragMove(e,r,i)};s.prototype.onmouseup=s.prototype.onpointerup=s.prototype.ontouchend=s.prototype.dragEnd=function(){r.removeEventListener(i,this);r.removeEventListener(o,this);this.onDragEnd()};return s});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./anchor"),require("./dragger"))}else{var r=t.Zdog;r.Illustration=e(r,r.Anchor,r.Dragger)}})(this,function t(e,r,a){function i(){}var h=e.TAU;var o=r.subclass({element:undefined,centered:true,zoom:1,dragRotate:false,resize:false,onPrerender:i,onDragStart:i,onDragMove:i,onDragEnd:i,onResize:i});e.extend(o.prototype,a.prototype);o.prototype.create=function(t){r.prototype.create.call(this,t);a.prototype.create.call(this,t);this.setElement(this.element);this.setDragRotate(this.dragRotate);this.setResize(this.resize)};o.prototype.setElement=function(t){t=this.getQueryElement(t);if(!t){throw new Error("Zdog.Illustration element required. Set to "+t)}var e=t.nodeName.toLowerCase();if(e=="canvas"){this.setCanvas(t)}else if(e=="svg"){this.setSvg(t)}};o.prototype.setSize=function(t,e){t=Math.round(t);e=Math.round(e);if(this.isCanvas){this.setSizeCanvas(t,e)}else if(this.isSvg){this.setSizeSvg(t,e)}};o.prototype.setResize=function(t){this.resize=t;if(!this.resizeListener){this.resizeListener=this.onWindowResize.bind(this)}if(t){window.addEventListener("resize",this.resizeListener);this.onWindowResize()}else{window.removeEventListener("resize",this.resizeListener)}};o.prototype.onWindowResize=function(){this.setMeasuredSize();this.onResize(this.width,this.height)};o.prototype.setMeasuredSize=function(){var t,e;var r=this.resize=="fullscreen";if(r){t=window.innerWidth;e=window.innerHeight}else{var i=this.element.getBoundingClientRect();t=i.width;e=i.height}this.setSize(t,e)};o.prototype.renderGraph=function(t){if(this.isCanvas){this.renderGraphCanvas(t)}else if(this.isSvg){this.renderGraphSvg(t)}};o.prototype.updateRenderGraph=function(t){this.updateGraph();this.renderGraph(t)};o.prototype.setCanvas=function(t){this.element=t;this.isCanvas=true;this.ctx=this.element.getContext("2d");this.setSizeCanvas(t.width,t.height)};o.prototype.setSizeCanvas=function(t,e){this.width=t;this.height=e;var r=this.pixelRatio=window.devicePixelRatio||1;this.element.width=this.canvasWidth=t*r;this.element.height=this.canvasHeight=e*r;var i=r>1&&!this.resize;if(i){this.element.style.width=t+"px";this.element.style.height=e+"px"}};o.prototype.renderGraphCanvas=function(t){t=t||this;this.prerenderCanvas();r.prototype.renderGraphCanvas.call(t,this.ctx);this.postrenderCanvas()};o.prototype.prerenderCanvas=function(){var t=this.ctx;t.lineCap="round";t.lineJoin="round";t.clearRect(0,0,this.canvasWidth,this.canvasHeight);t.save();if(this.centered){var e=this.width/2*this.pixelRatio;var r=this.height/2*this.pixelRatio;t.translate(e,r)}var i=this.pixelRatio*this.zoom;t.scale(i,i);this.onPrerender(t)};o.prototype.postrenderCanvas=function(){this.ctx.restore()};o.prototype.setSvg=function(t){this.element=t;this.isSvg=true;this.pixelRatio=1;var e=t.getAttribute("width");var r=t.getAttribute("height");this.setSizeSvg(e,r)};o.prototype.setSizeSvg=function(t,e){this.width=t;this.height=e;var r=t/this.zoom;var i=e/this.zoom;var o=this.centered?-r/2:0;var n=this.centered?-i/2:0;this.element.setAttribute("viewBox",o+" "+n+" "+r+" "+i);if(this.resize){this.element.removeAttribute("width");this.element.removeAttribute("height")}else{this.element.setAttribute("width",t);this.element.setAttribute("height",e)}};o.prototype.renderGraphSvg=function(t){t=t||this;n(this.element);this.onPrerender(this.element);r.prototype.renderGraphSvg.call(t,this.element)};function n(t){while(t.firstChild){t.removeChild(t.firstChild)}}o.prototype.setDragRotate=function(t){if(!t){return}else if(t===true){t=this}this.dragRotate=t;this.bindDrag(this.element)};o.prototype.dragStart=function(){this.dragStartRX=this.dragRotate.rotate.x;this.dragStartRY=this.dragRotate.rotate.y;a.prototype.dragStart.apply(this,arguments)};o.prototype.dragMove=function(t,e){var r=e.pageX-this.dragStartX;var i=e.pageY-this.dragStartY;var o=Math.min(this.width,this.height);var n=r/o*h;var s=i/o*h;this.dragRotate.rotate.x=this.dragStartRX-s;this.dragRotate.rotate.y=this.dragStartRY-n;a.prototype.dragMove.apply(this,arguments)};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./vector"))}else{var r=t.Zdog;r.PathCommand=e(r.Vector)}})(this,function t(i){function e(t,e,r){this.method=t;this.points=e.map(o);this.renderPoints=e.map(n);this.previousPoint=r;this.endRenderPoint=this.renderPoints[this.renderPoints.length-1];if(t=="arc"){this.controlPoints=[new i,new i]}}function o(t){if(t instanceof i){return t}else{return new i(t)}}function n(t){return new i(t)}e.prototype.reset=function(){var i=this.points;this.renderPoints.forEach(function(t,e){var r=i[e];t.set(r)})};e.prototype.transform=function(e,r,i){this.renderPoints.forEach(function(t){t.transform(e,r,i)})};e.prototype.render=function(t,e,r){return this[this.method](t,e,r)};e.prototype.move=function(t,e,r){return r.move(t,e,this.renderPoints[0])};e.prototype.line=function(t,e,r){return r.line(t,e,this.renderPoints[0])};e.prototype.bezier=function(t,e,r){var i=this.renderPoints[0];var o=this.renderPoints[1];var n=this.renderPoints[2];return r.bezier(t,e,i,o,n)};var h=9/16;e.prototype.arc=function(t,e,r){var i=this.previousPoint;var o=this.renderPoints[0];var n=this.renderPoints[1];var s=this.controlPoints[0];var a=this.controlPoints[1];s.set(i).lerp(o,h);a.set(n).lerp(o,h);return r.bezier(t,e,s,a,n)};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"),require("./path-command"),require("./anchor"))}else{var r=t.Zdog;r.Shape=e(r,r.Vector,r.PathCommand,r.Anchor)}})(this,function t(e,r,p,i){var o=i.subclass({stroke:1,fill:false,color:"#333",closed:true,visible:true,path:[{}],front:{z:1},backface:true});o.prototype.create=function(t){i.prototype.create.call(this,t);this.updatePath();this.front=new r(t.front||this.front);this.renderFront=new r(this.front);this.renderNormal=new r};var d=["move","line","bezier","arc"];o.prototype.updatePath=function(){this.setPath();this.updatePathCommands()};o.prototype.setPath=function(){};o.prototype.updatePathCommands=function(){var u;this.pathCommands=this.path.map(function(t,e){var r=Object.keys(t);var i=r[0];var o=t[i];var n=r.length==1&&d.includes(i);if(!n){i="line";o=t}var s=i=="line"||i=="move";var a=Array.isArray(o);if(s&&!a){o=[o]}i=e===0?"move":i;var h=new p(i,o,u);u=h.endRenderPoint;return h})};o.prototype.reset=function(){this.renderOrigin.set(this.origin);this.renderFront.set(this.front);this.pathCommands.forEach(function(t){t.reset()})};o.prototype.transform=function(e,r,i){this.renderOrigin.transform(e,r,i);this.renderFront.transform(e,r,i);this.renderNormal.set(this.renderOrigin).subtract(this.renderFront);this.pathCommands.forEach(function(t){t.transform(e,r,i)});this.children.forEach(function(t){t.transform(e,r,i)})};o.prototype.updateSortValue=function(){var e=0;this.pathCommands.forEach(function(t){e+=t.endRenderPoint.z});this.sortValue=e/this.pathCommands.length};o.prototype.render=function(t,e){var r=this.pathCommands.length;if(!this.visible||!r){return}this.isFacingBack=this.renderNormal.z>0;if(!this.backface&&this.isFacingBack){return}if(!e){throw new Error("Zdog renderer required. Set to "+e)}var i=r==1;if(e.isCanvas&&i){this.renderCanvasDot(t,e)}else{this.renderPath(t,e)}};var n=e.TAU;o.prototype.renderCanvasDot=function(t){var e=this.getLineWidth();if(!e){return}t.fillStyle=this.getRenderColor();var r=this.pathCommands[0].endRenderPoint;t.beginPath();var i=e/2;t.arc(r.x,r.y,i,0,n);t.fill()};o.prototype.getLineWidth=function(){if(!this.stroke){return 0}if(this.stroke==true){return 1}return this.stroke};o.prototype.getRenderColor=function(){var t=typeof this.backface=="string"&&this.isFacingBack;var e=t?this.backface:this.color;return e};o.prototype.renderPath=function(t,e){var r=this.getRenderElement(t,e);var i=this.pathCommands.length==2&&this.pathCommands[1].method=="line";var o=!i&&this.closed;var n=this.getRenderColor();e.renderPath(t,r,this.pathCommands,o);e.stroke(t,r,this.stroke,n,this.getLineWidth());e.fill(t,r,this.fill,n);e.end(t,r)};var s="http://www.w3.org/2000/svg";o.prototype.getRenderElement=function(t,e){if(!e.isSvg){return}if(!this.svgElement){this.svgElement=document.createElementNS(s,"path");this.svgElement.setAttribute("stroke-linecap","round");this.svgElement.setAttribute("stroke-linejoin","round")}return this.svgElement};return o});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./anchor"))}else{var r=t.Zdog;r.Group=e(r.Anchor)}})(this,function t(r){var e=r.subclass({updateSort:false,visible:true});e.prototype.updateSortValue=function(){var e=0;this.flatGraph.forEach(function(t){t.updateSortValue();e+=t.sortValue});this.sortValue=e/this.flatGraph.length;if(this.updateSort){this.flatGraph.sort(r.shapeSorter)}};e.prototype.render=function(e,r){if(!this.visible){return}this.flatGraph.forEach(function(t){t.render(e,r)})};e.prototype.updateFlatGraph=function(){var t=[];this.flatGraph=this.addChildFlatGraph(t)};e.prototype.getFlatGraph=function(){return[this]};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.Rect=e(r.Shape)}})(this,function t(e){var r=e.subclass({width:1,height:1});r.prototype.setPath=function(){var t=this.width/2;var e=this.height/2;this.path=[{x:-t,y:-e},{x:t,y:-e},{x:t,y:e},{x:-t,y:e}]};return r});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.RoundedRect=e(r.Shape)}})(this,function t(r){var e=r.subclass({width:1,height:1,cornerRadius:.25,closed:false});e.prototype.setPath=function(){var t=this.width/2;var e=this.height/2;var r=Math.min(t,e);var i=Math.min(this.cornerRadius,r);var o=t-i;var n=e-i;var s=[{x:o,y:-e},{arc:[{x:t,y:-e},{x:t,y:-n}]}];if(n){s.push({x:t,y:n})}s.push({arc:[{x:t,y:e},{x:o,y:e}]});if(o){s.push({x:-o,y:e})}s.push({arc:[{x:-t,y:e},{x:-t,y:n}]});if(n){s.push({x:-t,y:-n})}s.push({arc:[{x:-t,y:-e},{x:-o,y:-e}]});if(o){s.push({x:o,y:-e})}this.path=s};e.prototype.updateSortValue=function(){r.prototype.updateSortValue.apply(this,arguments);var t=this.pathCommands.length;var e=this.pathCommands[t-1].endRenderPoint;this.sortValue-=e.z/t};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./shape"))}else{var r=t.Zdog;r.Ellipse=e(r.Shape)}})(this,function t(r){var e=r.subclass({diameter:1,width:undefined,height:undefined,quarters:4,closed:false});e.prototype.setPath=function(){var t=this.width!=undefined?this.width:this.diameter;var e=this.height!=undefined?this.height:this.diameter;var r=t/2;var i=e/2;this.path=[{x:0,y:-i},{arc:[{x:r,y:-i},{x:r,y:0}]}];if(this.quarters>1){this.path.push({arc:[{x:r,y:i},{x:0,y:i}]})}if(this.quarters>2){this.path.push({arc:[{x:-r,y:i},{x:-r,y:0}]})}if(this.quarters>3){this.path.push({arc:[{x:-r,y:-i},{x:0,y:-i}]})}};e.prototype.updateSortValue=function(){r.prototype.updateSortValue.apply(this,arguments);if(this.quarters!=4){return}var t=this.pathCommands.length;var e=this.pathCommands[t-1].endRenderPoint;this.sortValue-=e.z/t};return e});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./shape"))}else{var r=t.Zdog;r.Polygon=e(r,r.Shape)}})(this,function t(e,r){var i=r.subclass({sides:3,radius:.5});var o=e.TAU;i.prototype.setPath=function(){this.path=[];for(var t=0;t<this.sides;t++){var e=t/this.sides*o-o/4;var r=Math.cos(e)*this.radius;var i=Math.sin(e)*this.radius;this.path.push({x:r,y:i})}};return i});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./ellipse"))}else{var r=t.Zdog;r.Hemisphere=e(r,r.Ellipse)}})(this,function t(e,r){var i=r.subclass({fill:true});var u=e.TAU;i.prototype.render=function(t,e){this.renderDome(t,e);r.prototype.render.apply(this,arguments)};i.prototype.renderDome=function(t,e){if(!this.visible){return}var r=this.getDomeRenderElement(t,e);var i=Math.atan2(this.renderNormal.y,this.renderNormal.x);var o=this.diameter/2*this.renderNormal.magnitude();var n=this.renderOrigin.x;var s=this.renderOrigin.y;if(e.isCanvas){var a=i+u/4;var h=i-u/4;t.beginPath();t.arc(n,s,o,a,h)}else if(e.isSvg){i=(i-u/4)/u*360;this.domeSvgElement.setAttribute("d","M "+-o+",0 A "+o+","+o+" 0 0 1 "+o+",0");this.domeSvgElement.setAttribute("transform","translate("+n+","+s+" ) rotate("+i+")")}e.stroke(t,r,this.stroke,this.color,this.getLineWidth());e.fill(t,r,this.fill,this.color);e.end(t,r)};var o="http://www.w3.org/2000/svg";i.prototype.getDomeRenderElement=function(t,e){if(!e.isSvg){return}if(!this.domeSvgElement){this.domeSvgElement=document.createElementNS(o,"path");this.domeSvgElement.setAttribute("stroke-linecap","round");this.domeSvgElement.setAttribute("stroke-linejoin","round")}return this.domeSvgElement};return i});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./path-command"),require("./shape"),require("./group"),require("./ellipse"))}else{var r=t.Zdog;r.Cylinder=e(r,r.PathCommand,r.Shape,r.Group,r.Ellipse)}})(this,function t(e,r,i,o,n){function s(){}var a=o.subclass({color:"#333",updateSort:true});a.prototype.create=function(){o.prototype.create.apply(this,arguments);this.pathCommands=[new r("move",[{}]),new r("line",[{}])]};a.prototype.render=function(t,e){this.renderCylinderSurface(t,e);o.prototype.render.apply(this,arguments)};a.prototype.renderCylinderSurface=function(t,e){if(!this.visible){return}var r=this.getRenderElement(t,e);var i=this.frontBase;var o=this.rearBase;var n=i.renderNormal.magnitude();var s=i.diameter*n+i.getLineWidth();this.pathCommands[0].renderPoints[0].set(i.renderOrigin);this.pathCommands[1].renderPoints[0].set(o.renderOrigin);if(e.isCanvas){t.lineCap="butt"}e.renderPath(t,r,this.pathCommands);e.stroke(t,r,true,this.color,s);e.end(t,r);if(e.isCanvas){t.lineCap="round"}};var h="http://www.w3.org/2000/svg";a.prototype.getRenderElement=function(t,e){if(!e.isSvg){return}if(!this.svgElement){this.svgElement=document.createElementNS(h,"path")}return this.svgElement};a.prototype.copyGraph=s;var u=n.subclass();u.prototype.copyGraph=s;var p=i.subclass({diameter:1,length:1,frontFace:undefined,fill:true});var d=e.TAU;p.prototype.create=function(){i.prototype.create.apply(this,arguments);this.group=new a({addTo:this,color:this.color,visible:this.visible});var t=this.length/2;var e=this.backface||true;this.frontBase=this.group.frontBase=new n({addTo:this.group,diameter:this.diameter,translate:{z:t},rotate:{y:d/2},color:this.color,stroke:this.stroke,fill:this.fill,backface:this.frontFace||e,visible:this.visible});this.rearBase=this.group.rearBase=this.frontBase.copy({translate:{z:-t},rotate:{y:0},backface:e})};p.prototype.render=function(){};var c=["stroke","fill","color","visible"];c.forEach(function(e){var r="_"+e;Object.defineProperty(p.prototype,e,{get:function(){return this[r]},set:function(t){this[r]=t;if(this.frontBase){this.frontBase[e]=t;this.rearBase[e]=t;this.group[e]=t}}})});return p});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./vector"),require("./path-command"),require("./anchor"),require("./ellipse"))}else{var r=t.Zdog;r.Cone=e(r,r.Vector,r.PathCommand,r.Anchor,r.Ellipse)}})(this,function t(e,r,i,o,n){var s=n.subclass({length:1,fill:true});var v=e.TAU;s.prototype.create=function(){n.prototype.create.apply(this,arguments);this.apex=new o({addTo:this,translate:{z:this.length}});this.renderApex=new r;this.tangentA=new r;this.tangentB=new r;this.surfacePathCommands=[new i("move",[{}]),new i("line",[{}]),new i("line",[{}])]};s.prototype.render=function(t,e){this.renderConeSurface(t,e);n.prototype.render.apply(this,arguments)};s.prototype.renderConeSurface=function(t,e){if(!this.visible){return}this.renderApex.set(this.apex.renderOrigin).subtract(this.renderOrigin);var r=this.renderNormal.magnitude();var i=this.renderApex.magnitude2d();var o=this.renderNormal.magnitude2d();var n=Math.acos(o/r);var s=Math.sin(n);var a=this.diameter/2*r;var h=a*s<i;if(!h){return}var u=Math.atan2(this.renderNormal.y,this.renderNormal.x)+v/2;var p=i/s;var d=Math.acos(a/p);var c=this.tangentA;var l=this.tangentB;c.x=Math.cos(d)*a*s;c.y=Math.sin(d)*a;l.set(this.tangentA);l.y*=-1;c.rotateZ(u);l.rotateZ(u);c.add(this.renderOrigin);l.add(this.renderOrigin);this.setSurfaceRenderPoint(0,c);this.setSurfaceRenderPoint(1,this.apex.renderOrigin);this.setSurfaceRenderPoint(2,l);var f=this.getSurfaceRenderElement(t,e);e.renderPath(t,f,this.surfacePathCommands);e.stroke(t,f,this.stroke,this.color,this.getLineWidth());e.fill(t,f,this.fill,this.color);e.end(t,f)};var a="http://www.w3.org/2000/svg";s.prototype.getSurfaceRenderElement=function(t,e){if(!e.isSvg){return}if(!this.surfaceSvgElement){this.surfaceSvgElement=document.createElementNS(a,"path");this.surfaceSvgElement.setAttribute("stroke-linecap","round");this.surfaceSvgElement.setAttribute("stroke-linejoin","round")}return this.surfaceSvgElement};s.prototype.setSurfaceRenderPoint=function(t,e){var r=this.surfacePathCommands[t].renderPoints[0];r.set(e)};return s});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./anchor"),require("./shape"),require("./rect"))}else{var r=t.Zdog;r.Box=e(r,r.Anchor,r.Shape,r.Rect)}})(this,function t(n,e,r,i){var s=i.subclass();s.prototype.copyGraph=function(){};var o=n.extend({width:1,height:1,depth:1,frontFace:true,rearFace:true,leftFace:true,rightFace:true,topFace:true,bottomFace:true},r.defaults);o.fill=true;delete o.path;var a=e.subclass(o);var h=n.TAU;a.prototype.create=function(t){e.prototype.create.call(this,t);this.updatePath()};a.prototype.updatePath=function(){this.setFace("frontFace",{width:this.width,height:this.height,translate:{z:this.depth/2}});this.setFace("rearFace",{width:this.width,height:this.height,translate:{z:-this.depth/2},rotate:{y:h/2}});this.setFace("leftFace",{width:this.depth,height:this.height,translate:{x:-this.width/2},rotate:{y:-h/4}});this.setFace("rightFace",{width:this.depth,height:this.height,translate:{x:this.width/2},rotate:{y:h/4}});this.setFace("topFace",{width:this.width,height:this.depth,translate:{y:-this.height/2},rotate:{x:-h/4}});this.setFace("bottomFace",{width:this.width,height:this.depth,translate:{y:this.height/2},rotate:{x:-h/4}})};a.prototype.setFace=function(t,e){var r=this[t];var i=t+"Rect";var o=this[i];if(!r){this.removeChild(o);return}n.extend(e,{color:typeof r=="string"?r:this.color,stroke:this.stroke,fill:this.fill,backface:this.backface,front:this.front,visible:this.visible});if(o){o.setOptions(e)}else{o=this[i]=new s(e)}o.updatePath();this.addChild(o)};return a});(function(t,e){if(typeof module=="object"&&module.exports){module.exports=e(require("./boilerplate"),require("./canvas-renderer"),require("./svg-renderer"),require("./vector"),require("./anchor"),require("./dragger"),require("./illustration"),require("./path-command"),require("./shape"),require("./group"),require("./rect"),require("./rounded-rect"),require("./ellipse"),require("./polygon"),require("./hemisphere"),require("./cylinder"),require("./cone"),require("./box"))}else if(typeof define=="function"&&define.amd){define("zdog",[],t.Zdog)}})(this,function t(e,r,i,o,n,s,a,h,u,p,d,c,l,f,v,m,y,g){e.CanvasRenderer=r;e.SvgRenderer=i;e.Vector=o;e.Anchor=n;e.Dragger=s;e.Illustration=a;e.PathCommand=h;e.Shape=u;e.Group=p;e.Rect=d;e.RoundedRect=c;e.Ellipse=l;e.Polygon=f;e.Hemisphere=v;e.Cylinder=m;e.Cone=y;e.Box=g;return e});
+1 -1
js/boilerplate.js
··· 1 1 /*! 2 - * Zdog v1.0.1 2 + * Zdog v1.0.2 3 3 * Round, flat, designer-friendly pseudo-3D engine 4 4 * Licensed MIT 5 5 * https://zzz.dog
+1 -1
package-lock.json
··· 1 1 { 2 2 "name": "zdog", 3 - "version": "1.0.1", 3 + "version": "1.0.2", 4 4 "lockfileVersion": 1, 5 5 "requires": true, 6 6 "dependencies": {
+1 -1
package.json
··· 1 1 { 2 2 "name": "zdog", 3 - "version": "1.0.1", 3 + "version": "1.0.2", 4 4 "description": "Round, flat, designer-friendly pseudo-3D engine", 5 5 "main": "js/index.js", 6 6 "files": [