├── .gitignore ├── dev ├── img │ ├── 1.jpg │ ├── background.jpg │ ├── pixelWave.gif │ └── pixelWaveMobile1.gif ├── js │ ├── main.js │ ├── PixelWave-min.js │ └── PixelWave.js ├── css │ ├── main-min.css │ ├── normalize.min.css │ ├── main.css │ └── normalize.css └── index.html ├── index.html ├── README.md └── dist └── PixelWave-min.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.codekit3 3 | -------------------------------------------------------------------------------- /dev/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vin-ni/PixelWave/HEAD/dev/img/1.jpg -------------------------------------------------------------------------------- /dev/img/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vin-ni/PixelWave/HEAD/dev/img/background.jpg -------------------------------------------------------------------------------- /dev/img/pixelWave.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vin-ni/PixelWave/HEAD/dev/img/pixelWave.gif -------------------------------------------------------------------------------- /dev/img/pixelWaveMobile1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vin-ni/PixelWave/HEAD/dev/img/pixelWaveMobile1.gif -------------------------------------------------------------------------------- /dev/js/main.js: -------------------------------------------------------------------------------- 1 | function start () { 2 | console.log('start'); 3 | } 4 | 5 | function middle () { 6 | console.log('middle'); 7 | } 8 | 9 | function end () { 10 | console.log('end'); 11 | } -------------------------------------------------------------------------------- /dev/css/main-min.css: -------------------------------------------------------------------------------- 1 | body{padding:0;margin:0;overflow:hidden}a{font-weight:bold;text-decoration:none;color:#2a2a2a}a:visited{font-weight:normal}a:hover{text-decoration:underline}img{position:absolute;top:0;left:0;width:100vw;display:block;height:auto}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{*zoom:1}@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}} 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /dev/css/normalize.min.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixel Wave Page Transition 2 | ![Pixel Wave Animation Preview](/dev/img/pixelWave.gif "Pixel Wave Animation Preview") 3 | ![Pixel Wave Animation Mobile](/dev/img/pixelWaveMobile1.gif "Pixel Wave Animation Mobile") 4 | 5 | ## Install 6 | At the bottom of your body: 7 | ```javascript 8 | 9 | 10 | 11 | var pixelwave = new PixelWave({ 12 | // options like: 13 | // canvasTop: 0 14 | }); 15 | ``` 16 | ## Run Animation 17 | ```javascript 18 | pixelwave.start(); 19 | ``` 20 | 21 | ## Options 22 | When starting the wave you can add callback functions to get executed at certain times: 23 | ```javascript 24 | pixelwave.start([runsAtStart], [runsAtMiddle], [runsAtEnd]); 25 | ``` 26 | 27 | You can pass these options while you init the wave: 28 | 29 | | Description | Name | Default | 30 | |----------------------------------------------------------------------------------------------------|--------------------------|------------------------------| 31 | | Set width of Pixel | xSize | 48 | 32 | | Set height of Pixel | ySize | 48 | 33 | | How many steps there are between full fill and the beginning of the wave. Add as many as you like. | steps | [0.1, 0.1, 0.3, 0.5, 0.5, 1] | 34 | | Color of the wave | color | #305EFF | 35 | | Time in s the screen needs to fill. | speedIn | 0.7 | 36 | | Time in s the screen needs to empty. | speedOut | 0.7 | 37 | | Position top of the canvas element | canvasTop | 0 | 38 | | Position left of the canvas element | canvasLeft | 0 | 39 | | Sets the z-Index for the canvas element | zIndex | 99999 | 40 | | This is a function that sets a given size for different devices. (*add values) | autoCalculateSquaresSize | false | 41 | | Add a delay in s before animation out runs. | delayMiddle | 0 | 42 | 43 | ## Full Example with options 44 | 45 | ```javascript 46 | 47 | 48 | 49 | var pixelwave = new PixelWave({ 50 | canvasTop: 50, //for a header 51 | speedIn: 3, 52 | speedOut: 1, 53 | autoCalculateSquaresSize: true, 54 | color: '#000000' 55 | }); 56 | 57 | function start () {console.log('start')} 58 | function middle () {console.log('middle')} 59 | function end () {console.log('end')} 60 | 61 | document.getElementById('startImage').addEventListener('click', function() { 62 | pixelwave.start(start, middle, end); 63 | }) 64 | ``` 65 | ### Dependencies 66 | Greensockets amazing [gsap](https://greensock.com/gsap). 67 | ### Contribution 68 | If anyone wants to contribute, just fork the project or write me at v@vinzenzaubry.com :) 69 | -------------------------------------------------------------------------------- /dev/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | overflow: hidden; 5 | 6 | } 7 | 8 | p { 9 | } 10 | 11 | a { 12 | font-weight: bold; 13 | text-decoration: none; 14 | color: #2a2a2a; 15 | } 16 | 17 | a:visited { 18 | font-weight: normal; 19 | } 20 | 21 | a:hover { 22 | text-decoration: underline; 23 | } 24 | 25 | img { 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | width: 100vw; 30 | display: block; 31 | height: auto; 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | /* ========================================================================== 42 | Media Queries 43 | ========================================================================== */ 44 | 45 | /*========== Non-Mobile First Method ==========*/ 46 | 47 | /*Above */ 48 | @media only screen and (min-width : 1201px) { 49 | 50 | } 51 | 52 | /* Large Devices, Wide Screens */ 53 | @media only screen and (max-width : 1200px) { 54 | 55 | } 56 | 57 | /* Medium Devices, Desktops */ 58 | @media only screen and (max-width : 992px) { 59 | 60 | } 61 | 62 | /* Small Devices, Tablets */ 63 | @media only screen and (max-width : 768px) { 64 | 65 | } 66 | 67 | /* Extra Small Devices, Phones */ 68 | @media only screen and (max-width : 480px) { 69 | 70 | } 71 | 72 | /* Custom, iPhone Retina */ 73 | @media only screen and (max-width : 320px) { 74 | 75 | } 76 | 77 | @media print, 78 | (-o-min-device-pixel-ratio: 5/4), 79 | (-webkit-min-device-pixel-ratio: 1.25), 80 | (min-resolution: 120dpi) { 81 | 82 | } 83 | 84 | /* ========================================================================== 85 | Helper classes 86 | ========================================================================== */ 87 | 88 | .hidden { 89 | display: none !important; 90 | visibility: hidden; 91 | } 92 | 93 | .visuallyhidden { 94 | border: 0; 95 | clip: rect(0 0 0 0); 96 | height: 1px; 97 | margin: -1px; 98 | overflow: hidden; 99 | padding: 0; 100 | position: absolute; 101 | width: 1px; 102 | } 103 | 104 | .visuallyhidden.focusable:active, 105 | .visuallyhidden.focusable:focus { 106 | clip: auto; 107 | height: auto; 108 | margin: 0; 109 | overflow: visible; 110 | position: static; 111 | width: auto; 112 | } 113 | 114 | .invisible { 115 | visibility: hidden; 116 | } 117 | 118 | .clearfix:before, 119 | .clearfix:after { 120 | content: " "; 121 | display: table; 122 | } 123 | 124 | .clearfix:after { 125 | clear: both; 126 | } 127 | 128 | .clearfix { 129 | *zoom: 1; 130 | } 131 | 132 | /* ========================================================================== 133 | Print styles 134 | ========================================================================== */ 135 | 136 | @media print { 137 | *, 138 | *:before, 139 | *:after { 140 | background: transparent !important; 141 | color: #000 !important; 142 | box-shadow: none !important; 143 | text-shadow: none !important; 144 | } 145 | 146 | a, 147 | a:visited { 148 | text-decoration: underline; 149 | } 150 | 151 | a[href]:after { 152 | content: " (" attr(href) ")"; 153 | } 154 | 155 | abbr[title]:after { 156 | content: " (" attr(title) ")"; 157 | } 158 | 159 | a[href^="#"]:after, 160 | a[href^="javascript:"]:after { 161 | content: ""; 162 | } 163 | 164 | pre, 165 | blockquote { 166 | border: 1px solid #999; 167 | page-break-inside: avoid; 168 | } 169 | 170 | thead { 171 | display: table-header-group; 172 | } 173 | 174 | tr, 175 | img { 176 | page-break-inside: avoid; 177 | } 178 | 179 | img { 180 | max-width: 100% !important; 181 | } 182 | 183 | p, 184 | h2, 185 | h3 { 186 | orphans: 3; 187 | widows: 3; 188 | } 189 | 190 | h2, 191 | h3 { 192 | page-break-after: avoid; 193 | } 194 | } -------------------------------------------------------------------------------- /dev/js/PixelWave-min.js: -------------------------------------------------------------------------------- 1 | "use strict";/*! 2 | // 3 | // PixelWave.js 4 | // Pixel Wave Animation for seamless page transitions 5 | // Version 0.1 04/12/17 6 | // Created by Vinzenz Aubry for sansho (04/12/17) 7 | // @license MIT Licensed 8 | // 9 | */ 10 | function PixelWave(t){this.animationSettings={xSize:t.xSize||48,ySize:t.ySize||48,steps:t.steps||[.1,.1,.3,.5,.5,1],color:t.color||"#305EFF",zIndex:t.zIndex||99999,speedIn:t.speedIn||.7,speedOut:t.speedOut||.7,canvasTop:t.canvasTop||0,canvasLeft:t.canvasLeft||0,autoCalculateSquaresSize:t.autoCalculateSquaresSize||!1,delayMiddle:t.delayMiddle||0},this.size={scaleRatio:window.devicePixelRatio||1,w:0,h:0},this.calculatedSettings={currentDistance:0,lastDraw:0,blockRun:!1,ending:!1},this.addCanvas(),this.eventListeners(),this.resizeCanvas()}PixelWave.prototype.addCanvas=function(){var t=document.createElement("canvas");t.id="pixelWave",t.style.zIndex=this.animationSettings.zIndex,t.style.pointerEvents="none",t.style.display="block",t.style.position="fixed",t.style.top=this.animationSettings.canvasTop+"px",t.style.left=this.animationSettings.canvasLeft+"px",document.body.appendChild(t),this.canvas=t,this.ctx=this.canvas.getContext("2d")},PixelWave.prototype.calculateSettings=function(){this.calculatedSettings.coloumns=Math.ceil(this.size.w/this.animationSettings.xSize),this.calculatedSettings.rows=Math.ceil(this.size.h/this.animationSettings.ySize);var t=this.calculatedSettings.rows;this.calculatedSettings.rowArray=Array.apply(null,{length:t}).map(Number.call,Number)},PixelWave.prototype.start=function(t,i,e){if(!this.calculateSettings.blockRun){this.calculateSettings.blockRun=!0,t&&t(),this.resizeCanvas(),this.calculateSquaresSize(),this.calculateSettings(),this.calculatedSettings.currentDistance=0,this.calculatedSettings.lastDraw=0;var s=this.calculatedSettings.coloumns+this.animationSettings.steps.length;s=s.toString();var n=this;this.animation=TweenLite.to(this.calculatedSettings,this.animationSettings.speedIn,{currentDistance:"+="+s,onUpdate:this.updateHandlerRunIn,onUpdateParams:[n,!0],onComplete:this.completeHandlerStart,onCompleteParams:[n,i,e],ease:Power0.easeNone})}},PixelWave.prototype.end=function(t){this.calculatedSettings.currentDistance=0,this.calculatedSettings.lastDraw=0,this.calculatedSettings.ending=!0;var i=this.calculatedSettings.coloumns+this.animationSettings.steps.length;i=i.toString();var e=this;this.animation=TweenLite.to(this.calculatedSettings,this.animationSettings.speedOut,{currentDistance:"+="+i,onUpdate:this.updateHandlerRunIn,onUpdateParams:[e,!1],onComplete:this.completeHandlerEnd,onCompleteParams:[e,t],ease:Power0.easeNone})},PixelWave.prototype.updateHandlerRunIn=function(t,i){var e=Math.round(t.calculatedSettings.currentDistance);e>t.calculatedSettings.lastDraw&&(t.calculatedSettings.lastDraw=e,t.spawnPixels(e,i))},PixelWave.prototype.completeHandlerStart=function(t,i,e){i&&i(),setTimeout(function(){t.end(e)},1e3*t.animationSettings.delayMiddle)},PixelWave.prototype.completeHandlerEnd=function(t,i){i&&i(),t.calculateSettings.blockRun=!1,t.calculatedSettings.ending=!1},PixelWave.prototype.spawnPixels=function(t,i){this.ctx.fillStyle=this.animationSettings.color;for(var e=0;e=1600?(this.animationSettings.xSize=48,this.animationSettings.ySize=48):this.size.w>=1200?(this.animationSettings.xSize=42,this.animationSettings.ySize=42):this.size.w>=960?(this.animationSettings.xSize=36,this.animationSettings.ySize=36):(this.animationSettings.xSize=30,this.animationSettings.ySize=30))},PixelWave.prototype.eventListeners=function(){this.resize=this.resizeFunctions.bind(this),window.addEventListener("resize",this.resize),this.debounceF=this.debounce(function(){console.log("debounce function got called"),this.resizeCanvas(),this.calculateSquaresSize(),this.calculateSettings(),this.animation&&(this._progress=this.animation.progress()),this.animation.kill(),console.log(this.calculatedSettings.ending),this.calculatedSettings.ending?(console.log("started End"),this.end(),this.animation.seek(this._progress*this.animationSettings.speedOut)):(this.calculatedSettings.blockRun=!1,this.start(),this.animation.seek(this._progress*this.animationSettings.speedIn),console.log("started Start")),console.log(this._progress),this.calculatedSettings.ending&&this.fill(),this.animation.play(),console.log("animation got restarted")},250)},PixelWave.prototype.resizeFunctions=function(){this.calculateSettings.blockRun&&(this.animation.pause(),this.debounceF())},PixelWave.prototype.debounce=function(t,i,e){var s;return function(){var n=this,a=arguments,o=function i(){s=null,e||t.apply(n,a)},l=e&&!s;clearTimeout(s),s=setTimeout(o,i),l&&t.apply(n,a)}},PixelWave.prototype.fill=function(){this.calculateSettings.blockRun&&(this.ctx.fillStyle=this.animationSettings.color,this.ctx.fillRect(0,0,this.size.w,this.size.h),console.log(this.size.w))},PixelWave.prototype.resizeCanvas=function(){this.size.w=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,this.size.h=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight,this.canvas.width=this.size.w*this.size.scaleRatio,this.canvas.height=this.size.h*this.size.scaleRatio,this.canvas.style.width=this.size.w+"px",this.canvas.style.height=this.size.h+"px",this.ctx.scale(this.size.scaleRatio,this.size.scaleRatio)},PixelWave.prototype.shuffleArray=function(t){for(var i=t.length,e,s;0!==i;)s=Math.floor(Math.random()*i),i-=1,e=t[i],t[i]=t[s],t[s]=e;return t}; -------------------------------------------------------------------------------- /dist/PixelWave-min.js: -------------------------------------------------------------------------------- 1 | "use strict";/*! 2 | // 3 | // PixelWave.js 4 | // Pixel Wave Animation for seamless page transitions 5 | // Version 0.1 04/12/17 6 | // Created by Vinzenz Aubry for sansho (04/12/17) 7 | // @license MIT Licensed 8 | // 9 | */ 10 | function PixelWave(t){this.animationSettings={xSize:t.xSize||48,ySize:t.ySize||48,steps:t.steps||[.1,.1,.3,.5,.5,1],color:t.color||"#305EFF",zIndex:t.zIndex||99999,speedIn:t.speedIn||.7,speedOut:t.speedOut||.7,canvasTop:t.canvasTop||0,canvasLeft:t.canvasLeft||0,autoCalculateSquaresSize:t.autoCalculateSquaresSize||!1,delayMiddle:t.delayMiddle||0},this.size={scaleRatio:window.devicePixelRatio||1,w:0,h:0},this.calculatedSettings={currentDistance:0,lastDraw:0,blockRun:!1,ending:!1},this.addCanvas(),this.eventListeners(),this.resizeCanvas()}PixelWave.prototype.addCanvas=function(){var t=document.createElement("canvas");t.id="pixelWave",t.style.zIndex=this.animationSettings.zIndex,t.style.pointerEvents="none",t.style.display="block",t.style.position="fixed",t.style.top=this.animationSettings.canvasTop+"px",t.style.left=this.animationSettings.canvasLeft+"px",document.body.appendChild(t),this.canvas=t,this.ctx=this.canvas.getContext("2d")},PixelWave.prototype.calculateSettings=function(){this.calculatedSettings.coloumns=Math.ceil(this.size.w/this.animationSettings.xSize),this.calculatedSettings.rows=Math.ceil(this.size.h/this.animationSettings.ySize);var t=this.calculatedSettings.rows;this.calculatedSettings.rowArray=Array.apply(null,{length:t}).map(Number.call,Number)},PixelWave.prototype.start=function(t,i,e){if(!this.calculateSettings.blockRun){this.calculateSettings.blockRun=!0,t&&t(),this.resizeCanvas(),this.calculateSquaresSize(),this.calculateSettings(),this.calculatedSettings.currentDistance=0,this.calculatedSettings.lastDraw=0;var s=this.calculatedSettings.coloumns+this.animationSettings.steps.length;s=s.toString();var n=this;this.animation=TweenLite.to(this.calculatedSettings,this.animationSettings.speedIn,{currentDistance:"+="+s,onUpdate:this.updateHandlerRunIn,onUpdateParams:[n,!0],onComplete:this.completeHandlerStart,onCompleteParams:[n,i,e],ease:Power0.easeNone})}},PixelWave.prototype.end=function(t){this.calculatedSettings.currentDistance=0,this.calculatedSettings.lastDraw=0,this.calculatedSettings.ending=!0;var i=this.calculatedSettings.coloumns+this.animationSettings.steps.length;i=i.toString();var e=this;this.animation=TweenLite.to(this.calculatedSettings,this.animationSettings.speedOut,{currentDistance:"+="+i,onUpdate:this.updateHandlerRunIn,onUpdateParams:[e,!1],onComplete:this.completeHandlerEnd,onCompleteParams:[e,t],ease:Power0.easeNone})},PixelWave.prototype.updateHandlerRunIn=function(t,i){var e=Math.round(t.calculatedSettings.currentDistance);e>t.calculatedSettings.lastDraw&&(t.calculatedSettings.lastDraw=e,t.spawnPixels(e,i))},PixelWave.prototype.completeHandlerStart=function(t,i,e){i&&i(),setTimeout(function(){t.end(e)},1e3*t.animationSettings.delayMiddle)},PixelWave.prototype.completeHandlerEnd=function(t,i){i&&i(),t.calculateSettings.blockRun=!1,t.calculatedSettings.ending=!1},PixelWave.prototype.spawnPixels=function(t,i){this.ctx.fillStyle=this.animationSettings.color;for(var e=0;e=1600?(this.animationSettings.xSize=48,this.animationSettings.ySize=48):this.size.w>=1200?(this.animationSettings.xSize=42,this.animationSettings.ySize=42):this.size.w>=960?(this.animationSettings.xSize=36,this.animationSettings.ySize=36):(this.animationSettings.xSize=30,this.animationSettings.ySize=30))},PixelWave.prototype.eventListeners=function(){this.resize=this.resizeFunctions.bind(this),window.addEventListener("resize",this.resize),this.debounceF=this.debounce(function(){console.log("debounce function got called"),this.resizeCanvas(),this.calculateSquaresSize(),this.calculateSettings(),this.animation&&(this._progress=this.animation.progress()),this.animation.kill(),console.log(this.calculatedSettings.ending),this.calculatedSettings.ending?(console.log("started End"),this.end(),this.animation.seek(this._progress*this.animationSettings.speedOut)):(this.calculatedSettings.blockRun=!1,this.start(),this.animation.seek(this._progress*this.animationSettings.speedIn),console.log("started Start")),console.log(this._progress),this.calculatedSettings.ending&&this.fill(),this.animation.play(),console.log("animation got restarted")},250)},PixelWave.prototype.resizeFunctions=function(){this.calculateSettings.blockRun&&(this.animation.pause(),this.debounceF())},PixelWave.prototype.debounce=function(t,i,e){var s;return function(){var n=this,a=arguments,o=function i(){s=null,e||t.apply(n,a)},l=e&&!s;clearTimeout(s),s=setTimeout(o,i),l&&t.apply(n,a)}},PixelWave.prototype.fill=function(){this.calculateSettings.blockRun&&(this.ctx.fillStyle=this.animationSettings.color,this.ctx.fillRect(0,0,this.size.w,this.size.h),console.log(this.size.w))},PixelWave.prototype.resizeCanvas=function(){this.size.w=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,this.size.h=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight,this.canvas.width=this.size.w*this.size.scaleRatio,this.canvas.height=this.size.h*this.size.scaleRatio,this.canvas.style.width=this.size.w+"px",this.canvas.style.height=this.size.h+"px",this.ctx.scale(this.size.scaleRatio,this.size.scaleRatio)},PixelWave.prototype.shuffleArray=function(t){for(var i=t.length,e,s;0!==i;)s=Math.floor(Math.random()*i),i-=1,e=t[i],t[i]=t[s],t[s]=e;return t}; -------------------------------------------------------------------------------- /dev/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } 428 | -------------------------------------------------------------------------------- /dev/js/PixelWave.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | /*! 4 | // 5 | // PixelWave.js 6 | // Pixel Wave Animation for seamless page transitions 7 | // Version 0.1 04/12/17 8 | // Created by Vinzenz Aubry for sansho (04/12/17) 9 | // @license MIT Licensed 10 | // 11 | */ 12 | 13 | function PixelWave(settings) { 14 | this.animationSettings = { 15 | xSize: settings.xSize || 48, 16 | ySize: settings.ySize || 48, 17 | steps: settings.steps || [0.1, 0.1, 0.3, 0.5, 0.5, 1], 18 | color: settings.color || "#305EFF", 19 | zIndex: settings.zIndex || 99999, 20 | speedIn: settings.speedIn || 0.7, //0.7 21 | speedOut: settings.speedOut || 0.7, //0.7 22 | canvasTop: settings.canvasTop || 0, 23 | canvasLeft: settings.canvasLeft || 0, 24 | autoCalculateSquaresSize: settings.autoCalculateSquaresSize || false, 25 | delayMiddle: settings.delayMiddle || 0 26 | } 27 | 28 | this.size = { 29 | scaleRatio: window.devicePixelRatio||1, 30 | w: 0, 31 | h: 0 32 | }; 33 | 34 | this.calculatedSettings = { 35 | currentDistance: 0, 36 | lastDraw: 0, 37 | blockRun: false, 38 | ending: false 39 | }; 40 | 41 | this.addCanvas(); 42 | this.eventListeners(); 43 | 44 | this.resizeCanvas(); 45 | // this.calculateSquaresSize(); 46 | // this.calculateSettings(); 47 | } 48 | 49 | PixelWave.prototype.addCanvas = function () { 50 | var canv = document.createElement('canvas'); 51 | canv.id = 'pixelWave'; 52 | canv.style.zIndex = this.animationSettings.zIndex; 53 | canv.style.pointerEvents = "none"; 54 | canv.style.display = 'block'; 55 | canv.style.position = 'fixed'; 56 | canv.style.top = `${this.animationSettings.canvasTop}px`; 57 | canv.style.left = `${this.animationSettings.canvasLeft}px`; 58 | 59 | document.body.appendChild(canv); 60 | this.canvas = canv; 61 | this.ctx = this.canvas.getContext("2d"); 62 | } 63 | 64 | PixelWave.prototype.calculateSettings = function() { 65 | //amount coloumns ↓↓↓↓ 66 | this.calculatedSettings.coloumns = Math.ceil(this.size.w / this.animationSettings.xSize); 67 | //amount lines → 68 | // → 69 | // → 70 | this.calculatedSettings.rows = Math.ceil(this.size.h / this.animationSettings.ySize); 71 | 72 | var n = this.calculatedSettings.rows; 73 | this.calculatedSettings.rowArray = Array.apply(null, {length: n}).map(Number.call, Number); 74 | } 75 | 76 | PixelWave.prototype.start = function(callbackStart, callbackMiddle, callbackEnd) { 77 | if (this.calculateSettings.blockRun) {return} 78 | this.calculateSettings.blockRun = true; 79 | 80 | if (callbackStart) {callbackStart()}; 81 | 82 | //reset values 83 | this.resizeCanvas(); 84 | this.calculateSquaresSize(); 85 | this.calculateSettings(); 86 | this.calculatedSettings.currentDistance = 0; 87 | this.calculatedSettings.lastDraw = 0; 88 | 89 | let coloumnsString = this.calculatedSettings.coloumns + this.animationSettings.steps.length; 90 | coloumnsString = coloumnsString.toString(); 91 | var self = this; 92 | 93 | this.animation = TweenLite.to(this.calculatedSettings, this.animationSettings.speedIn, {currentDistance:`+=${coloumnsString}`, 94 | onUpdate:this.updateHandlerRunIn, onUpdateParams:[self, true], 95 | onComplete:this.completeHandlerStart, onCompleteParams:[self, callbackMiddle, callbackEnd], 96 | ease: Power0.easeNone}); 97 | } 98 | 99 | PixelWave.prototype.end = function(callbackEnd) { 100 | //reset values 101 | this.calculatedSettings.currentDistance = 0; 102 | this.calculatedSettings.lastDraw = 0; 103 | 104 | this.calculatedSettings.ending = true; 105 | 106 | let coloumnsString = this.calculatedSettings.coloumns + this.animationSettings.steps.length; 107 | coloumnsString = coloumnsString.toString(); 108 | var self = this; 109 | 110 | this.animation = TweenLite.to(this.calculatedSettings, this.animationSettings.speedOut, {currentDistance:`+=${coloumnsString}`, 111 | onUpdate:this.updateHandlerRunIn, onUpdateParams:[self, false], 112 | onComplete:this.completeHandlerEnd, onCompleteParams:[self, callbackEnd], 113 | ease: Power0.easeNone}); 114 | } 115 | 116 | PixelWave.prototype.updateHandlerRunIn = function(scope, addRectangles) { 117 | var distance = Math.round(scope.calculatedSettings.currentDistance); 118 | 119 | if (distance > scope.calculatedSettings.lastDraw) { 120 | scope.calculatedSettings.lastDraw = distance; 121 | scope.spawnPixels(distance, addRectangles); 122 | } 123 | } 124 | 125 | PixelWave.prototype.completeHandlerStart = function(scope, callbackMiddle, callbackEnd) { 126 | if (callbackMiddle) {callbackMiddle()}; 127 | 128 | //call animation out 129 | setTimeout(function() {scope.end(callbackEnd);}, scope.animationSettings.delayMiddle*1000); 130 | 131 | } 132 | 133 | PixelWave.prototype.completeHandlerEnd = function(scope, callbackEnd) { 134 | if (callbackEnd) {callbackEnd()}; 135 | scope.calculateSettings.blockRun = false; 136 | scope.calculatedSettings.ending = false; 137 | } 138 | 139 | PixelWave.prototype.spawnPixels = function(xStep, addRectangles) { 140 | this.ctx.fillStyle = this.animationSettings.color; 141 | 142 | for (let i = 0; i < this.animationSettings.steps.length; i++) { 143 | 144 | this.calculatedSettings.rowArray = this.shuffleArray(this.calculatedSettings.rowArray); //shuffle 145 | let maxElements = Math.ceil(this.animationSettings.steps[i] * this.calculatedSettings.rows); 146 | let rowArray = this.calculatedSettings.rowArray.slice(0, maxElements); 147 | 148 | for (let j = 0; j < rowArray.length; j++) { 149 | let randomX = (xStep-i) * this.animationSettings.xSize; 150 | let randomY = rowArray[j] * this.animationSettings.ySize; 151 | if (addRectangles) { 152 | this.ctx.fillRect(randomX,randomY,this.animationSettings.xSize,this.animationSettings.ySize); 153 | } else { 154 | this.ctx.clearRect(randomX,randomY,this.animationSettings.xSize,this.animationSettings.ySize); 155 | } 156 | } 157 | } 158 | 159 | //fill all previous Pixels 160 | let lastStep = (xStep - (this.animationSettings.steps.length - 1))*this.animationSettings.xSize; 161 | if (addRectangles) { 162 | this.ctx.fillRect(0,0, lastStep, this.size.h); 163 | } else { 164 | this.ctx.clearRect(0,0, lastStep, this.size.h); 165 | } 166 | } 167 | 168 | PixelWave.prototype.setPixelWavePosition = function(x, y) { 169 | this.animationSettings.canvasTop = y; 170 | this.animationSettings.canvasLeft = x; 171 | this.canvas.style.top = `${this.animationSettings.canvasTop}px`; 172 | this.canvas.style.left = `${this.animationSettings.canvasLeft}px`; 173 | } 174 | 175 | PixelWave.prototype.calculateSquaresSize = function() { 176 | if (this.animationSettings.autoCalculateSquaresSize) { 177 | if (this.size.w >= 1600) { 178 | this.animationSettings.xSize = 48; 179 | this.animationSettings.ySize = 48; 180 | } else if (this.size.w >= 1200) { 181 | this.animationSettings.xSize = 42; 182 | this.animationSettings.ySize = 42; 183 | } else if (this.size.w >= 960) { 184 | this.animationSettings.xSize = 36; 185 | this.animationSettings.ySize = 36; 186 | } else { 187 | this.animationSettings.xSize = 30; 188 | this.animationSettings.ySize = 30; 189 | } 190 | } 191 | } 192 | 193 | PixelWave.prototype.eventListeners = function () { 194 | this.resize = this.resizeFunctions.bind(this); 195 | window.addEventListener('resize', this.resize); 196 | // window.addEventListener('resize', this.resizeFunctions); 197 | 198 | this.debounceF = this.debounce(function() { 199 | console.log('debounce function got called'); 200 | this.resizeCanvas(); 201 | this.calculateSquaresSize(); 202 | this.calculateSettings(); 203 | 204 | if (this.animation) {this._progress = this.animation.progress();} 205 | this.animation.kill(); 206 | console.log(this.calculatedSettings.ending); 207 | 208 | //rebuild animation with new values 209 | if (this.calculatedSettings.ending) { 210 | console.log('started End'); 211 | this.end(); 212 | this.animation.seek(this._progress*this.animationSettings.speedOut); 213 | } else { 214 | this.calculatedSettings.blockRun = false; //otherwise start won't run 215 | this.start(); 216 | this.animation.seek(this._progress*this.animationSettings.speedIn); 217 | console.log('started Start'); 218 | } 219 | 220 | 221 | console.log(this._progress); 222 | 223 | if (this.calculatedSettings.ending) {this.fill()}; 224 | 225 | this.animation.play(); 226 | console.log("animation got restarted") 227 | }, 250); 228 | } 229 | 230 | PixelWave.prototype.resizeFunctions = function () { 231 | if (!this.calculateSettings.blockRun) {return} 232 | this.animation.pause(); 233 | //debouncer 234 | this.debounceF(); 235 | } 236 | 237 | PixelWave.prototype.debounce = function (func, wait, immediate) { 238 | var timeout; 239 | return function() { 240 | var context = this, args = arguments; 241 | var later = function() { 242 | timeout = null; 243 | if (!immediate) func.apply(context, args); 244 | }; 245 | var callNow = immediate && !timeout; 246 | clearTimeout(timeout); 247 | timeout = setTimeout(later, wait); 248 | if (callNow) func.apply(context, args); 249 | }; 250 | }; 251 | 252 | PixelWave.prototype.fill = function () { 253 | if (this.calculateSettings.blockRun) { 254 | this.ctx.fillStyle = this.animationSettings.color; 255 | this.ctx.fillRect(0,0,this.size.w,this.size.h); 256 | console.log(this.size.w); 257 | } 258 | } 259 | 260 | PixelWave.prototype.resizeCanvas = function () { 261 | this.size.w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 262 | this.size.h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 263 | 264 | this.canvas.width = this.size.w * this.size.scaleRatio; 265 | this.canvas.height = this.size.h * this.size.scaleRatio; 266 | 267 | this.canvas.style.width = this.size.w+'px'; 268 | this.canvas.style.height = this.size.h + 'px'; 269 | 270 | this.ctx.scale(this.size.scaleRatio, this.size.scaleRatio); 271 | } 272 | 273 | // =================== SANTAS LITTLE HELPERS =================== // 274 | 275 | PixelWave.prototype.shuffleArray = function (array) { 276 | var currentIndex = array.length, temporaryValue, randomIndex; 277 | 278 | // While there remain elements to shuffle... 279 | while (0 !== currentIndex) { 280 | 281 | // Pick a remaining element... 282 | randomIndex = Math.floor(Math.random() * currentIndex); 283 | currentIndex -= 1; 284 | 285 | // And swap it with the current element. 286 | temporaryValue = array[currentIndex]; 287 | array[currentIndex] = array[randomIndex]; 288 | array[randomIndex] = temporaryValue; 289 | } 290 | 291 | return array; 292 | } 293 | 294 | --------------------------------------------------------------------------------