├── .eslintrc.json ├── .gitignore ├── README.md ├── assets ├── css │ └── index.css └── js │ └── index.js ├── gulp.config.js ├── gulpfile.js ├── index.html ├── license.txt ├── package-lock.json ├── package.json ├── sass ├── _reset.scss └── index.scss └── scripts └── index.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { "browser": true }, 3 | "extends": "standard", 4 | "globals": { 5 | "Vue": false, 6 | "Sine": false, 7 | "TweenLite": false 8 | }, 9 | "rules": { 10 | "space-before-function-paren": 0, 11 | "object-property-newline": 0, 12 | "arrow-parens": 0, 13 | "new-cap": 0, 14 | "no-eval": 0, 15 | "no-new": 0, 16 | "semi": 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SVG Animations with VueJS and TweenLite 2 | 3 |  4 | 5 | This repo contains the code for a demo from our blog post "Creating Vue.js Transitions & Animation: Live Examples". 6 | 7 | "An animation is a more complex, usually multi-step and sometimes continuous change in appearance. Animations will often call on JavaScript to pick up where CSS' lack of logic drops off. It could be to add a class and trigger the animation or to make complex state transitions that reflect onto the DOM. 8 | 9 | The possibilities and approaches are virtually endless, so I've chosen one of my favourite techniques to showcase how you could animate your data with Vue.js. 10 | 11 | Essentially we're going to use GSAP's TweenLite library to apply easing functions to our state's changes and let Vue's lightning fast reactivity reflect this on the DOM. Vue is just as comfortable working with inline SVG as it is with HTML." 12 | 13 | >[Read full tutorial](https://snipcart.com/blog/vuejs-transitions-animations) 14 | 15 | >[Try it on CodePen](https://codepen.io/udyux/pen/aLVXOg) 16 | 17 | Enjoy folks! 18 | -------------------------------------------------------------------------------- /assets/css/index.css: -------------------------------------------------------------------------------- 1 | @import "https://fonts.googleapis.com/css?family=Lato:300,900|Libre+Franklin:100,200,300,600,900|Prompt:100,200,300,600,900";html{-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Libre Franklin,sans-serif;font-size:100%;height:100%}html.lato{font-family:Lato,sans-serif}html.prompt{font-family:Prompt,sans-serif}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;height:100%;line-height:1;position:relative}*{-webkit-margin-after:0;-webkit-margin-before:0;-webkit-margin-end:0;-webkit-margin-start:0;-webkit-padding-after:0;-webkit-padding-before:0;-webkit-padding-end:0;-webkit-padding-start:0;background:none;border:none;border-radius:0;margin:0;outline:none;padding:0}*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}:active,:hover{outline:0}address,b,button,del,em,h1,h2,h3,h4,h5,h6,i,input,ins,pre,select,strong,td,textarea,th{font-family:inherit;font-size:inherit;font-style:normal;font-weight:400;letter-spacing:inherit;text-transform:inherit}input,textarea{-moz-appearance:none;-webkit-appearance:none;appearance:none;background-clip:padding-box}a,button,del,ins{color:inherit;text-decoration:none}menu,ol,ul{list-style:none}table{border-collapse:separate;border-spacing:0;width:100%}pre,textarea{max-width:100%;overflow:auto}img{display:block;height:auto;width:100%}svg:not(:root){overflow:hidden}form{width:100%}button{cursor:pointer;overflow:visible}textarea{resize:none}input[type=range]{-webkit-appearance:none;background-color:transparent}input[type=range]::-ms-track{background:transparent;border-color:transparent;color:transparent;cursor:pointer}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none}::moz-focus-inner{border:none;padding:0}.chart{-ms-flex-align:center;-ms-flex-direction:column;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-box-pack:center;align-items:center;background:-webkit-gradient(linear,left top,left bottom,from(#c0f195),to(#4c9b95));background:linear-gradient(#c0f195,#4c9b95);color:#36424b;display:-webkit-box;display:-ms-flexbox;display:flex;flex-direction:column;height:100vh;justify-content:center}.chart__content{max-width:775px;padding-right:1.5rem;position:relative;width:95%}.chart__content:after,.chart__content:before{bottom:0;content:"";left:0;position:absolute}.chart__content:before{background:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.3)),color-stop(110%,transparent));background:linear-gradient(90deg,rgba(0,0,0,.3),transparent 110%);height:1px;width:100%}.chart__content:after{background:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.3)),color-stop(110%,transparent));background:linear-gradient(0deg,rgba(0,0,0,.3),transparent 110%);height:100%;width:1px}.chart__content svg{display:block}.chart__caption{-webkit-transform:translate(-50%,100%);left:50%;position:absolute;text-align:center;top:100%;transform:translate(-50%,100%);width:100%}.chart__title{font-size:1.3rem}.chart__subtitle{font-size:1.15rem;margin-top:.5em}.modal{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;background-color:hsla(0,0%,100%,.6);display:-webkit-box;display:-ms-flexbox;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:1}.modal-enter-active,.modal-leave-active{-webkit-transition:opacity .35s;transition:opacity .35s}.modal-enter,.modal-leave-to{opacity:0}.modal-enter-to,.modal-leave{opacity:1}.modal__open{font-size:1.1rem;font-weight:200;position:fixed;right:2.5rem;top:2em}.modal__content{-ms-flex-align:center;-ms-flex-direction:column;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-box-pack:center;-webkit-box-shadow:0 .5rem 1.75rem -.25rem rgba(61,83,88,.4);align-items:center;background-color:#fff;border:1px solid #c5d0d1;border-radius:12px;box-shadow:0 .5rem 1.75rem -.25rem rgba(61,83,88,.4);display:-webkit-box;display:-ms-flexbox;display:flex;flex-direction:column;justify-content:center;max-width:500px;min-height:250px;padding:1.5rem 1rem;position:relative;text-align:center;width:90%}.modal__title{font-size:1.5rem}.modal__link{font-size:1.2rem;font-weight:300;margin-top:1.5rem;position:relative;z-index:0}.modal__link:after{-webkit-transition:background-color 225ms ease-out;background-color:currentColor;bottom:0;content:"";height:1px;left:0;position:absolute;transition:background-color 225ms ease-out;width:100%;z-index:-1}.modal__link:hover:after{background-color:#4c9b95}.modal__close{-webkit-transition:opacity .15s ease-out;font-size:2.5rem;line-height:1;opacity:.5;position:absolute;right:1rem;top:.25rem;transition:opacity .15s ease-out}.modal__close:hover{opacity:1} 2 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIl9yZXNldC5zY3NzIiwiaW5kZXguc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2SEFBTyxBQUVQLEtBQ0UsOEJBQUEsQUFBc0Isc0JBQUEsQUFHdEIsc0NBRkEsQUFFeUMsZUFGMUIsQUFDZixXQUFZLENBS2IsQUFSRCxVQU1XLDJCQUFnQyxDQUFHLEFBTjlDLFlBT2EsNkJBQWtDLENBQUcsQUFHbEQsS0FLRSxrQ0FEQSxBQUNrQyxtQ0FIbEMsQUFFbUMsWUFGdkIsQUFDWixjQUZBLEFBRWMsaUJBRkksQ0FLbkIsQUFHRCxFQVNFLHVCQURBLEFBQ3VCLHdCQURDLEFBR3hCLHFCQURBLEFBQ3FCLHVCQURFLEFBS3ZCLHdCQUhBLEFBR3dCLHlCQUhDLEFBRXpCLHNCQURBLEFBQ3NCLHdCQVB0QixBQU13QixnQkFSeEIsQUFFZ0IsWUFIaEIsQUFDWSxnQkFIWixBQUVnQixTQUZQLEFBSVQsYUFIQSxBQUdhLFNBSEgsQ0FhWCxBQUVELGlCQWpCRSwyQkFBQSxBQUFtQixrQkFBQSxDQW9CcEIsQUFFRCxlQUVFLFNBQVUsQ0FDWCxBQUVELHVGQUtFLG9CQUFvQixBQUNwQixrQkFBa0IsQUFFbEIsa0JBREEsQUFDa0IsZ0JBREMsQUFFbkIsdUJBTEEsQUFLdUIsc0JBTEEsQ0FNeEIsQUFFRCxlQUVFLHFCQUFBLEFBQWdCLHdCQUFoQixBQUFnQixnQkFBQSxBQUNoQiwyQkFBNEIsQ0FDN0IsQUFFRCxpQkFDRSxjQUFjLEFBQ2Qsb0JBQXFCLENBQ3RCLEFBRUQsV0FFRSxlQUFnQixDQUNqQixBQUVELE1BRUUseUJBQXlCLEFBQ3pCLGlCQUZBLEFBRWlCLFVBRk4sQ0FHWixBQUVELGFBR0UsZUFEQSxBQUNlLGFBREQsQ0FFZixBQUVELElBR0UsY0FEQSxBQUNjLFlBRmQsQUFDWSxVQURELENBR1osQUFFRCxlQUNFLGVBQWdCLENBQ2pCLEFBRUQsS0FDRSxVQUFXLENBQ1osQUFFRCxPQUNFLGVBQWUsQUFDZixnQkFBaUIsQ0FDbEIsQUFFRCxTQUNFLFdB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Y3NzIiwic291cmNlc0NvbnRlbnQiOlsiQGltcG9ydCAnaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PUxhdG86MzAwLDkwMHxMaWJyZStGcmFua2xpbjoxMDAsMjAwLDMwMCw2MDAsOTAwfFByb21wdDoxMDAsMjAwLDMwMCw2MDAsOTAwJztcblxuaHRtbCB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIGZvbnQtc2l6ZTogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBmb250LWZhbWlseTogJ0xpYnJlIEZyYW5rbGluJywgc2Fucy1zZXJpZjtcbiAgXG4gICYubGF0byB7IGZvbnQtZmFtaWx5OiAnTGF0bycsIHNhbnMtc2VyaWYgfVxuICAmLnByb21wdCB7IGZvbnQtZmFtaWx5OiAnUHJvbXB0Jywgc2Fucy1zZXJpZiB9XG59XG5cbmJvZHkge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGhlaWdodDogMTAwJTtcbiAgbGluZS1oZWlnaHQ6IDE7XG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xufVxuXG4vKiByZXNldCAqL1xuKiB7XG4gIGJveC1zaXppbmc6IGluaGVyaXQ7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyLXJhZGl1czogMDtcbiAgYm9yZGVyOiBub25lO1xuICBvdXRsaW5lOiBub25lO1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICAtd2Via2l0LW1hcmdpbi1iZWZvcmU6IDA7XG4gIC13ZWJraXQtbWFyZ2luLWFmdGVyOiAwO1xuICAtd2Via2l0LW1hcmdpbi1zdGFydDogMDtcbiAgLXdlYmtpdC1tYXJnaW4tZW5kOiAwO1xuICAtd2Via2l0LXBhZGRpbmctYmVmb3JlOiAwO1xuICAtd2Via2l0LXBhZGRpbmctc3RhcnQ6IDA7XG4gIC13ZWJraXQtcGFkZGluZy1lbmQ6IDA7XG4gIC13ZWJraXQtcGFkZGluZy1hZnRlcjogMDtcbn1cblxuKjo6YmVmb3JlLFxuKjo6YWZ0ZXIge1xuICBib3gtc2l6aW5nOiBpbmhlcml0O1xufVxuXG4qOmFjdGl2ZSxcbio6aG92ZXIge1xuICBvdXRsaW5lOiAwO1xufVxuXG5iLCBpLCBlbSwgc3Ryb25nLFxuaDEsIGgyLCBoMywgaDQsIGg1LCBoNixcbnRoLCB0ZCwgcHJlLCBpbnMsIGRlbCwgYWRkcmVzcyxcbmlucHV0LCBzZWxlY3QsIGJ1dHRvbiwgdGV4dGFyZWEge1xuICB0ZXh0LXRyYW5zZm9ybTogaW5oZXJpdDtcbiAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xuICBsZXR0ZXItc3BhY2luZzogaW5oZXJpdDtcbn1cblxudGV4dGFyZWEsXG5pbnB1dCB7XG4gIGFwcGVhcmFuY2U6IG5vbmU7XG4gIGJhY2tncm91bmQtY2xpcDogcGFkZGluZy1ib3g7XG59XG5cbmEsIGlucywgZGVsLCBidXR0b24ge1xuICBjb2xvcjogaW5oZXJpdDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xufVxuXG51bCwgb2wsXG5tZW51IHtcbiAgbGlzdC1zdHlsZTogbm9uZTtcbn1cblxudGFibGUge1xuICB3aWR0aDogMTAwJTtcbiAgYm9yZGVyLWNvbGxhcHNlOiBzZXBhcmF0ZTtcbiAgYm9yZGVyLXNwYWNpbmc6IDA7XG59XG5cbnByZSxcbnRleHRhcmVhIHtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIG1heC13aWR0aDogMTAwJTtcbn1cblxuaW1nIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogYXV0bztcbiAgZGlzcGxheTogYmxvY2s7XG59XG5cbnN2Zzpub3QoOnJvb3QpIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuZm9ybSB7XG4gIHdpZHRoOiAxMDAlO1xufVxuXG5idXR0b24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiB2aXNpYmxlO1xufVxuXG50ZXh0YXJlYSB7XG4gIHJlc2l6ZTogbm9uZTtcbn1cblxuaW5wdXRbdHlwZT0ncmFuZ2UnXSB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIFxuICAmOjotbXMtdHJhY2sge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgXG4gICAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICBjb2xvcjogdHJhbnNwYXJlbnQ7XG4gIH1cblxuICAmOjotd2Via2l0LXNsaWRlci10aHVtYiB7XG4gICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICB9XG59XG5cbjo6bW96LWZvY3VzLWlubmVyIHtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiBub25lO1xufVxuIiwiQGltcG9ydCAncmVzZXQnO1xuXG4uY2hhcnQge1xuICBoZWlnaHQ6IDEwMHZoO1xuICBkaXNwbGF5OiBmbGV4O1xuICBjb2xvcjogIzM2NDI0YjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChyZ2IoMTkyLCAyNDEsIDE0OSksIHJnYig3NiwgMTU1LCAxNDkpKTtcblxuICAmX19jb250ZW50IHtcbiAgICB3aWR0aDogOTUlO1xuICAgIG1heC13aWR0aDogNzc1cHg7XG4gICAgcGFkZGluZy1yaWdodDogMS41cmVtO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgICY6OmJlZm9yZSxcbiAgICAmOjphZnRlciB7XG4gICAgICBjb250ZW50OiAnJztcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGJvdHRvbTogMDtcbiAgICAgIGxlZnQ6IDA7XG4gICAgfVxuXG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiAxcHg7XG4gICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsIHJnYmEoYmxhY2ssIDAuMyksIHJnYmEoYmxhY2ssIDApIDExMCUpO1xuICAgIH1cblxuICAgICY6OmFmdGVyIHtcbiAgICAgIHdpZHRoOiAxcHg7XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCByZ2JhKGJsYWNrLCAwLjMpLCByZ2JhKGJsYWNrLCAwKSAxMTAlKTtcbiAgICB9XG5cbiAgICBzdmcge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxuICB9XG5cbiAgJl9fY2FwdGlvbiB7XG4gICAgbGVmdDogNTAlO1xuICAgIHRvcDogMTAwJTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIDEwMCUpO1xuICB9XG5cbiAgJl9fdGl0bGUge1xuICAgIGZvbnQtc2l6ZTogMS4zcmVtO1xuICB9XG5cbiAgJl9fc3VidGl0bGUge1xuICAgIGZvbnQtc2l6ZTogMS4xNXJlbTtcbiAgICBtYXJnaW4tdG9wOiAwLjVlbTtcbiAgfVxufVxuXG4ubW9kYWwge1xuICB3aWR0aDogMTAwdnc7XG4gIGhlaWdodDogMTAwdmg7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSh3aGl0ZSwgMC42KTtcbiAgei1pbmRleDogMTtcblxuICAmLWVudGVyLWFjdGl2ZSxcbiAgJi1sZWF2ZS1hY3RpdmUgeyB0cmFuc2l0aW9uOiBvcGFjaXR5IDM1MG1zIH1cblxuICAmLWVudGVyLFxuICAmLWxlYXZlLXRvIHsgb3BhY2l0eTogMCB9XG5cbiAgJi1sZWF2ZSxcbiAgJi1lbnRlci10byB7IG9wYWNpdHk6IDEgfVxuXG4gICZfX29wZW4ge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDJlbTtcbiAgICByaWdodDogMi41cmVtO1xuICAgIGZvbnQtd2VpZ2h0OiAyMDA7XG4gICAgZm9udC1zaXplOiAxLjFyZW07XG4gIH1cblxuICAmX19jb250ZW50IHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgd2lkdGg6IDkwJTtcbiAgICBtYXgtd2lkdGg6IDUwMHB4O1xuICAgIG1pbi1oZWlnaHQ6IDI1MHB4O1xuICAgIHBhZGRpbmc6IDEuNXJlbSAxcmVtO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNjNWQwZDE7XG4gICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgYm94LXNoYWRvdzogMCAwLjVyZW0gMS43NXJlbSAtMC4yNXJlbSByZ2JhKCMzZDUzNTgsIDAuNCk7XG4gIH1cblxuICAmX190aXRsZSB7XG4gICAgZm9udC1zaXplOiAxLjVyZW07XG4gIH1cblxuICAmX19saW5rIHtcbiAgICBtYXJnaW4tdG9wOiAxLjVyZW07XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGZvbnQtc2l6ZTogMS4ycmVtO1xuICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgei1pbmRleDogMDtcblxuICAgICY6OmFmdGVyIHtcbiAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBoZWlnaHQ6IDFweDtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGJvdHRvbTogMDtcbiAgICAgIGxlZnQ6IDA7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBjdXJyZW50Q29sb3I7XG4gICAgICB6LWluZGV4OiAtMTtcbiAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgMjI1bXMgZWFzZS1vdXQ7XG4gICAgfVxuXG4gICAgJjpob3Zlcjo6YWZ0ZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDc2LCAxNTUsIDE0OSk7XG4gICAgfVxuICB9XG5cbiAgJl9fY2xvc2Uge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDAuMjVyZW07XG4gICAgcmlnaHQ6IDFyZW07XG4gICAgZm9udC1zaXplOiAyLjVyZW07XG4gICAgb3BhY2l0eTogMC41O1xuICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMTUwbXMgZWFzZS1vdXQ7XG5cbiAgICAmOmhvdmVyIHtcbiAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxuICB9XG59XG4iXX0= */ 3 | -------------------------------------------------------------------------------- /assets/js/index.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var t=function(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[n]=e,t};new Vue({el:"#app",data:function(){return{modal:!1,points:{a:-1,b:-1,c:-1,d:-1,e:-1}}},computed:{path:function(){var t=this;return Object.keys(this.points).filter(function(t){return~"abcde".indexOf(t)}).map(function(n,e){return[100*e,100-t.points[n]]})}},methods:{setPoint:function(t){var n=this.random(3,5),e=this.random(0,100);this.animatePoint({key:t,duration:n,destination:e})},animatePoint:function(n){var e,i=n.key,o=n.duration,a=n.destination;TweenLite.to(this.points,o,(e={},t(e,i,a),t(e,"ease",Sine.easeInOut),t(e,"onComplete",this.setPoint),t(e,"onCompleteParams",[i]),e))},random:function(t,n){return(Math.random()*(n-t)+t).toFixed(2)}},mounted:function(){Object.keys(this.points).forEach(this.setPoint)}})}(); 2 | //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdHMvaW5kZXguanMiXSwibmFtZXMiOlsiVnVlIiwiYSIsImIiLCJjIiwiZCIsImUiLCJPYmplY3QiLCJrZXlzIiwidGhpcyIsInBvaW50cyIsImZpbHRlciIsImtleSIsImluZGV4T2YiLCJtYXAiLCJpIiwiX3RoaXMiLCJkdXJhdGlvbiIsInJhbmRvbSIsImRlc3RpbmF0aW9uIiwiYW5pbWF0ZVBvaW50IiwiX3JlZiIsInRvIiwiX1R3ZWVuTGl0ZSR0byIsImRlZmluZVByb3BlcnR5IiwiU2luZSIsImVhc2VJbk91dCIsInNldFBvaW50IiwibWluIiwibWF4IiwiTWF0aCIsInRvRml4ZWQiLCJmb3JFYWNoIl0sIm1hcHBpbmdzIjoic0pBQUEsSUFBSUEsUUFDRSxZQURFLHlCQUlLLFVBQ0dDLEdBQUksRUFBR0MsR0FBSSxFQUFHQyxHQUFJLEVBQUdDLEdBQUksRUFBR0MsR0FBSSxvQkFJcEMsNkJBRUNDLE9BQU9DLEtBQUtDLEtBQUtDLFFBQ3JCQyxPQUFPLFNBQUFDLFVBQVEsUUFBUUMsUUFBUUQsS0FDL0JFLElBQUksU0FBQ0YsRUFBS0csVUFBVyxJQUFKQSxFQUFTLElBQU1DLEVBQUtOLE9BQU9FLDBCQUkxQyxTQWpCSEEsT0FDRkssRUFERVIsS0FBQVMsT0FBQSxFQUFBLEdBQUFDLEVBRUNWLEtBQUFTLE9BQUEsRUFBQSxVQUNFRSxjQUFBUixJQUFBQSxFQUFBSyxTQUFBQSxFQUFBRSxZQUFBQSxrQkFjQSxTQUFBRSxTQWRQVCxFQUFBUyxFQUFBVCxJQUFBSyxFQUFBSSxFQUFBSixTQUFBRSxFQUFBRSxFQUFBRixzQkFISUcsR0FBQWIsS0FBQUMsT0FBQU8sR0FBQU0sS0FBQUMsRUFBQUQsRUEwQkNYLEVBQU1PLEdBMUJQSyxFQUFBRCxFQUFBLE9BMkJNRSxLQUFLQyxXQTNCWEYsRUFBQUQsRUFBQSxhQVNJZCxLQUFBa0IsVUFUSkgsRUFBQUQsRUFBQSxvQkFVR1gsSUFWSFcsWUFpQkcsU0FnQkFLLEVBckJhQyxVQUNYQyxLQUFBWixVQUFBVyxFQUFBRCxHQUFBQSxHQUFBRyxRQUFBLGFBYkwsa0JBdUNHdkIsS0FBS0MsS0FBS0MsUUFBUXNCLFFBQVF2QixLQUFLa0IiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyJuZXcgVnVlKHtcbiAgZWw6ICcjYXBwJyxcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgcG9pbnRzOiB7IGE6IC0xLCBiOiAtMSwgYzogLTEsIGQ6IC0xLCBlOiAtMSB9XG4gICAgfVxuICB9LFxuXG4gIGNvbXB1dGVkOiB7XG4gICAgcGF0aCgpIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnBvaW50cylcbiAgICAgICAgLmZpbHRlcihrZXkgPT4gfidhYmNkZScuaW5kZXhPZihrZXkpKVxuICAgICAgICAubWFwKChrZXksIGkpID0+IFtpICogMTAwLCAxMDAgLSB0aGlzLnBvaW50c1trZXldXSlcbiAgICB9XG4gIH0sXG5cbiAgbWV0aG9kczoge1xuICAgIHNldFBvaW50KGtleSkge1xuICAgICAgbGV0IGR1cmF0aW9uID0gdGhpcy5yYW5kb20oMywgNSlcbiAgICAgIGxldCBkZXN0aW5hdGlvbiA9IHRoaXMucmFuZG9tKDAsIDEwMClcbiAgICAgIHRoaXMuYW5pbWF0ZVBvaW50KHsga2V5LCBkdXJhdGlvbiwgZGVzdGluYXRpb24gfSlcbiAgICB9LFxuXG4gICAgYW5pbWF0ZVBvaW50KHsga2V5LCBkdXJhdGlvbiwgZGVzdGluYXRpb24gfSkge1xuICAgICAgVHdlZW5MaXRlLnRvKHRoaXMucG9pbnRzLCBkdXJhdGlvbiwge1xuICAgICAgICBba2V5XTogZGVzdGluYXRpb24sXG4gICAgICAgIGVhc2U6IFNpbmUuZWFzZUluT3V0LFxuICAgICAgICBvbkNvbXBsZXRlOiB0aGlzLnNldFBvaW50LFxuICAgICAgICBvbkNvbXBsZXRlUGFyYW1zOiBba2V5XVxuICAgICAgfSlcbiAgICB9LFxuXG4gICAgcmFuZG9tKG1pbiwgbWF4KSB7XG4gICAgICByZXR1cm4gKChNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbikpICsgbWluKS50b0ZpeGVkKDIpXG4gICAgfVxuICB9LFxuXG4gIG1vdW50ZWQoKSB7XG4gICAgT2JqZWN0LmtleXModGhpcy5wb2ludHMpLmZvckVhY2godGhpcy5zZXRQb2ludClcbiAgfVxufSlcbiJdfQ== 3 | -------------------------------------------------------------------------------- /gulp.config.js: -------------------------------------------------------------------------------- 1 | /* config ———————————————————————————————————————————————————————————————————*/ 2 | const config = { 3 | browsersync: { 4 | localhost: undefined, 5 | port: 8080, 6 | notify: true, 7 | sync: true 8 | }, 9 | 10 | sass: { 11 | src: ['./sass/index.scss'], 12 | dest: './assets/css', 13 | options: { indentedSyntax: false }, 14 | autoprefixer: { 15 | browsers: ['last 2 versions', 'not ie <= 9'] 16 | } 17 | }, 18 | 19 | js: { 20 | src: './scripts/*.js', 21 | dest: './assets/js', 22 | eslint: { fix: true }, 23 | babel: { 24 | presets: ['es2015-rollup'] 25 | } 26 | }, 27 | 28 | watch: { 29 | sass: 'sass/**/*.scss', 30 | js: 'scripts/**/*.js', 31 | markup: '**/*.html' 32 | } 33 | } 34 | 35 | /* helpers ——————————————————————————————————————————————————————————————————*/ 36 | const notifier = require('node-notifier') 37 | const symbols = require('log-symbols') 38 | const chalk = require('chalk') 39 | 40 | module.exports = { 41 | get config() { 42 | config.sass.dest = config.sass.dest.replace(/\/$/, '') 43 | config.js.dest = config.js.dest.replace(/\/$/, '') 44 | return config 45 | }, 46 | 47 | get bsConfig() { 48 | let conf = { 49 | port: config.browsersync.port, 50 | ui: { port: config.browsersync.port + 1 }, 51 | notify: config.browsersync.notify, 52 | proxy: config.browsersync.localhost, 53 | server: (!config.browsersync.localhost) ? './' : false 54 | } 55 | 56 | if (!config.browsersync.sync) conf.ghostMode = false 57 | return conf 58 | }, 59 | 60 | sassReporter(e) { 61 | let title = `${e.relativePath}:${e.line}` 62 | let message = e.messageOriginal.replace(/\s{4}/,'') 63 | let count = chalk.bold(chalk.red(`${symbols.error} 1 problem (1 error, 0 warnings)`)) 64 | console.log(chalk.underline(title), '\n ', message, `\n\n${count}`, '\n') 65 | notifier.notify({ title, message }) 66 | this.emit('end') 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const sass = require('gulp-sass') 3 | const cssnano = require('cssnano') 4 | const uglify = require('gulp-uglify') 5 | const eslint = require('gulp-eslint') 6 | const rename = require('gulp-rename') 7 | const postcss = require('gulp-postcss') 8 | const plumber = require('gulp-plumber') 9 | const babel = require('rollup-plugin-babel') 10 | const rollup = require('gulp-better-rollup') 11 | const autoprefixer = require('autoprefixer') 12 | const sourcemaps = require('gulp-sourcemaps') 13 | const browserSync = require('browser-sync').create() 14 | const cjsResolve = require('rollup-plugin-commonjs') 15 | const nodeResolve = require('rollup-plugin-node-resolve') 16 | 17 | const utils = require('./gulp.config') 18 | const config = utils.config 19 | 20 | // sass 21 | gulp.task('sass', () => { 22 | return gulp.src(config.sass.src) 23 | .pipe(plumber(utils.sassReporter)) 24 | .pipe(sourcemaps.init()) 25 | .pipe(sass(config.sass.options)) 26 | .pipe(postcss([ 27 | autoprefixer(config.sass.autoprefixer), 28 | cssnano() 29 | ])) 30 | .pipe(sourcemaps.write()) 31 | .pipe(rename({ dirname: '' })) 32 | .pipe(gulp.dest(config.sass.dest)) 33 | .pipe(browserSync.stream({ match: '**/*.css' })) 34 | }) 35 | 36 | // js 37 | gulp.task('js', () => { 38 | return gulp.src(config.js.src) 39 | .pipe(sourcemaps.init()) 40 | .pipe(eslint()) 41 | .pipe(eslint.format()) 42 | .pipe(rollup({ 43 | plugins: [ 44 | cjsResolve(), 45 | nodeResolve(), 46 | babel(config.js.babel) 47 | ] 48 | }, 'iife')) 49 | .pipe(uglify()) 50 | .pipe(sourcemaps.write()) 51 | .pipe(rename({ dirname: '' })) 52 | .pipe(gulp.dest(config.js.dest)) 53 | }) 54 | 55 | // builds 56 | gulp.task('build', ['sass', 'js']) 57 | 58 | // dev 59 | gulp.task('watch', ['build'], () => { 60 | gulp.watch(config.watch.sass, ['sass']) 61 | gulp.watch(config.watch.js, ['js']) 62 | }) 63 | 64 | // browser sync 65 | gulp.task('dev', ['watch'], () => { 66 | browserSync.init(utils.bsConfig) 67 | gulp.watch(`${config.js.dest}/*.js`).on('change', browserSync.reload) 68 | gulp.watch(config.watch.markup).on('change', browserSync.reload) 69 | }) 70 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |