├── .gitignore ├── README.md ├── css ├── reset.css └── main.css ├── LICENSE ├── js ├── sphere.js └── header.js └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .svn 3 | log/*.log 4 | tmp/** 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sphere 2 | 3 | When bored, I sometimes open a blank JavaScript 4 | file and start writing without any clear objective 5 | of where I want to take it. This is the result of one 6 | such coding session. 7 | 8 | After some fiddling and minification I was able to 9 | squeeze the JavaScript source into 372 bytes. 10 | 11 | Curious about how this looks in action? [Check out the live demo.](http://hakim.se/experiments/html5/sphere). 12 | 13 | # License 14 | 15 | MIT licensed 16 | 17 | Copyright (C) 2017 Hakim El Hattab, http://hakim.se -------------------------------------------------------------------------------- /css/reset.css: -------------------------------------------------------------------------------- 1 | html{color:#000;background:#222222;} 2 | a{cursor:pointer;} 3 | html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;} 4 | table{border-collapse:collapse;border-spacing:0;} 5 | fieldset,img{border:0;} 6 | address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;} 7 | li{list-style:none;} 8 | caption,th{text-align:left;} 9 | /* h1,h2,h3,h4,h5,h6{font-size:100%;} */ 10 | q:before,q:after{content:'';} 11 | abbr,acronym {border:0;font-variant:normal;} 12 | sup {vertical-align:text-top;} 13 | sub {vertical-align:text-bottom;} 14 | input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;outline-style:none;outline-width:0pt;} 15 | legend{color:#000;} 16 | a:focus,object,h1,h2,h3,h4,h5,h6{-moz-outline-style: none; border:0px;} 17 | /*input[type="Submit"]{cursor:pointer;}*/ 18 | strong {font-weight: bold;} 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2017 Hakim El Hattab, http://hakim.se 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /js/sphere.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Draws a particle sphere/spiral on canvas. 3 | * 4 | * @author Hakim El Hattab | http://hakim.se 5 | */ 6 | (function(){ 7 | var d = document, 8 | canvas = d.body.appendChild( d.createElement( 'canvas' ) ), 9 | context = canvas.getContext( '2d' ), 10 | time = 0, 11 | w = 1, 12 | h = 1, 13 | cos = Math.cos, 14 | sin = Math.sin, 15 | PI = Math.PI; 16 | 17 | function resize() { 18 | canvas.width = w = innerWidth; 19 | canvas.height = h = innerHeight; 20 | } 21 | 22 | // Monitor browser resize 23 | addEventListener( 'resize', resize, false ); 24 | 25 | // Initial size 26 | resize(); 27 | 28 | // The main animation loop 29 | setInterval( function() { 30 | context.clearRect( 0, 0, w, h ); 31 | context.fillStyle = 'rgba(0,255,255,.5)'; 32 | context.globalCompositeOperation = 'lighter'; 33 | 34 | time += .1; 35 | 36 | // The number of particles to generate 37 | i = 10000; 38 | 39 | while( i-- ) { 40 | // The magic 41 | r = ( ( w + h ) * 0.4 ) * ( cos( ( time + i ) * ( .05 + ( ( sin(time*0.00002) / PI ) * .2 ) ) ) / PI ); 42 | 43 | context.fillRect( sin(i) * r + (w/2), 44 | cos(i) * r + (h/2), 45 | 1, 46 | 1 ); 47 | } 48 | }, 16 ); 49 | })() -------------------------------------------------------------------------------- /js/header.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Controls the showing and hiding of the expandable 3 | * header. 4 | * 5 | * @author Hakim El Hattab / http://hakim.se 6 | */ 7 | window.onload = function() { 8 | 9 | var header = document.getElementsByTagName('header')[0]; 10 | var headerToggleTimeOut = -1; 11 | var headerMouseDown = false; 12 | 13 | document.addEventListener( 'mousedown', function() { 14 | headerMouseDown = true; 15 | }, false ); 16 | 17 | document.addEventListener( 'mouseup', function() { 18 | headerMouseDown = false; 19 | }, false ); 20 | 21 | header.addEventListener('mouseover', function() { 22 | if (!headerMouseDown) { 23 | // Make sure no previous call to toggle the header are 24 | // queued up 25 | clearTimeout( headerToggleTimeOut ); 26 | 27 | // Avoid accidentally opening the header by setting 28 | // a short time out 29 | headerToggleTimeOut = setTimeout( function() { 30 | header.setAttribute( 'class', 'open' ) 31 | }, 100 ); 32 | } 33 | }, false); 34 | 35 | header.addEventListener('mouseout', function() { 36 | // Make sure no previous call to toggle the header are 37 | // queued up 38 | clearTimeout( headerToggleTimeOut ); 39 | 40 | // Avoid accidentally closing the header by setting 41 | // a short time out 42 | headerToggleTimeOut = setTimeout( function() { 43 | header.setAttribute( 'class', '' ) 44 | }, 100 ); 45 | }, false); 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
31 | When bored, I sometimes open a blank JavaScript
32 | file and start writing without any clear objective
33 | of where I want to take it. This is the result of one
34 | such coding session.
35 |
37 | Created by Hakim El Hattab | @hakimel 38 |
39 |
44 | After some fiddling and minification I was able to
45 | squeeze the JavaScript source into 372 bytes.
46 | You can find the source on GitHub.
47 |