├── .gitignore ├── 1-chapter-1-1-nature-of-code-in-js-svg ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 10-svg-elements-change-on-mouseover ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 11-bouncing-ball-svg ├── README.txt ├── babel │ └── index.babel ├── index.html ├── js │ └── index.js └── license.txt ├── 12-svg-ball-ocsillating ├── README.txt ├── babel │ └── index.babel ├── index.html └── js │ └── index.js ├── 13-small-svg-pool-splash ├── README.txt ├── babel │ └── index.babel ├── css │ └── style.css ├── index.html ├── js │ └── index.js ├── license.txt └── scss │ └── style.scss ├── 2-chapter-1-3-nature-of-code-in-js-svg ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 3-chapter-1-5-nature-of-code-in-js-svg ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 4-hack-physics-and-js-nocanvas-svg-1 ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 5-hack-physics-and-js-nocanvas-svg-2 ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 6-hack-physics-and-js-nocanvas-svg-3 ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 7-hack-physics-and-js-nocanvas-svg-4 ├── README.txt ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 8-better-way-utilizing-object-pool-nocanvas-svg ├── css │ └── normalize.css ├── index.html └── js │ └── index.js ├── 9-changing-linear-gradient-particle-fountain ├── css │ └── normalize.css ├── index.html └── js │ └── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ### OSX ### 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | 21 | # Directories potentially created on remote AFP share 22 | .AppleDB 23 | .AppleDesktop 24 | Network Trash Folder 25 | Temporary Items 26 | .apdisk -------------------------------------------------------------------------------- /1-chapter-1-1-nature-of-code-in-js-svg/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /1-chapter-1-1-nature-of-code-in-js-svg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chapter 1.1 of The Nature of Code, in JS 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /1-chapter-1-1-nature-of-code-in-js-svg/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Processing to JS from https://github.com/shiffman/The-Nature-of-Code-Examples/blob/master/chp01_vectors/NOC_1_1_bouncingball_novectors/NOC_1_1_bouncingball_novectors.pde 2 | // live demo at http://codepen.io/sdras/pen/d953d844fb3bed2c053fb83874844f64 3 | 4 | var ball = document.createElement("ball"); 5 | 6 | document.body.appendChild(ball); 7 | document.body.style.background = '#222'; 8 | 9 | ball.setAttribute("class", "ball"); 10 | 11 | var x = 100, 12 | y = 100, 13 | xspeed = 2, 14 | yspeed = 2.5, 15 | width = window.innerWidth, 16 | height = window.innerHeight, 17 | globalId; 18 | 19 | function repeatOften() { 20 | x = x + xspeed; 21 | y = y + yspeed; 22 | 23 | if ((x > width) || (x < 0)) { 24 | xspeed = xspeed * -1; 25 | } 26 | if ((y > height) || (y < 0)) { 27 | yspeed = yspeed * -1; 28 | } 29 | ball.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 30 | 31 | globalID = requestAnimationFrame(repeatOften); 32 | } 33 | globalID = requestAnimationFrame(repeatOften); -------------------------------------------------------------------------------- /10-svg-elements-change-on-mouseover/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /10-svg-elements-change-on-mouseover/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SVG elements change on mousemove 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /10-svg-elements-change-on-mouseover/js/index.js: -------------------------------------------------------------------------------- 1 | //not from a book or post, but wanted to play with some mouseover and mouseleave events 2 | //of note: we've increased the stroke weight and made it transparent here to increase the hit boundary 3 | //pen can be found at: http://codepen.io/sdras/pen/qZgrxm 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | width = Math.round(window.innerWidth), 9 | height = Math.round(window.innerHeight), 10 | x = window.innerWidth / 2, 11 | y = window.innerHeight / 2, 12 | radius = 10; 13 | 14 | document.body.appendChild(svg); 15 | document.body.style.background = '#222'; 16 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 17 | svg.setAttribute("width", width); 18 | svg.setAttribute("height", height); 19 | svg.style.cursor = "pointer"; 20 | 21 | function drawCirc() { 22 | var st = 40; 23 | var allW = Math.round(width / st); 24 | var allH = Math.round(height / st); 25 | var startY = -st / 2; 26 | var allT = allW * allH; 27 | 28 | for (var i = 0; i < allT; i++) { 29 | var circ = document.createElementNS(svgNS, "circle"); 30 | svg.appendChild(circ); 31 | circ.setAttribute("r", radius); 32 | circ.setAttribute("fill", "rgb(225, " + i + ", 0)"); 33 | circ.setAttribute("stroke-width", "40"); 34 | circ.setAttribute("stroke-opacity", "0"); 35 | circ.setAttribute("stroke", "orangered"); 36 | circ.setAttribute("cx", (i % allW) * st); 37 | 38 | if (i % allW === 0) { 39 | startY += st; 40 | } 41 | circ.setAttribute("cy", (startY)); 42 | 43 | //style it 44 | circ.style.transformOrigin = "50% 50%"; 45 | circ.style.opacity = 0.5; 46 | circ.style.transition = "0.4s all ease-out"; 47 | 48 | circ.addEventListener("mouseover", function(e) { 49 | this.style.transform = "scale(2)"; 50 | this.style.opacity = 1; 51 | }); 52 | 53 | circ.addEventListener("mouseleave", function(e) { 54 | var nowCirc = this; 55 | this.style.transition = "0.6s all ease-in"; 56 | setTimeout(function() { 57 | nowCirc.style.transform = "scale(1)"; 58 | nowCirc.style.opacity = 0.5; 59 | }, 600); 60 | }); 61 | 62 | this.circ = circ; 63 | } 64 | }; 65 | 66 | drawCirc(); -------------------------------------------------------------------------------- /11-bouncing-ball-svg/README.txt: -------------------------------------------------------------------------------- 1 | A Pen created at CodePen.io. You can find this one at http://codepen.io/sdras/pen/rjQrJY. 2 | 3 | -------------------------------------------------------------------------------- /11-bouncing-ball-svg/babel/index.babel: -------------------------------------------------------------------------------- 1 | // codepen demo at http://s.codepen.io/sdras/full/rjQrJY/ 2 | 3 | let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 4 | svgNS = svg.namespaceURI, 5 | vbx = document.createElementNS(svgNS, "viewBox"), 6 | radius = 15, 7 | x1 = 0, // initial horizontal position 8 | y1 = 0, // initial vertical position 9 | g = 0.11, // acceleration due to gravity 10 | vx = 2, // initial horizontal speed 11 | vy = 0, // initial vertical speed 12 | maxHeight = 300; 13 | 14 | //set the SVG and the body 15 | document.body.style.background = '#222'; 16 | append(document.body, svg); 17 | setAttributes(svg, { 18 | "viewBox": `0 0 ${window.innerWidth} ${window.innerHeight}`, 19 | }); 20 | 21 | //make the circle 22 | let circ = document.createElementNS(svgNS, "circle"); 23 | append(svg, circ); 24 | setAttributes(circ, { 25 | "cx": x1, 26 | "cy": y1, 27 | "r": radius, 28 | }); 29 | 30 | //use rAF to animate but put a boundary on it so it doesn't run forever 31 | let start; 32 | 33 | function step(timestamp) { 34 | if (!start) start = timestamp; 35 | var progress = timestamp - start; 36 | if (progress < 13000) { 37 | bounceBall(); 38 | window.requestAnimationFrame(step); 39 | } 40 | } 41 | window.requestAnimationFrame(step); 42 | 43 | //move it 44 | function bounceBall() { 45 | vy += g; // gravity increases the vertical speed 46 | x1 += vx; // horizontal speed inccrements horizontal position 47 | y1 += vy; // vertical speed increases vertical position 48 | 49 | if (y1 > maxHeight - radius) { // if ball hits the ground 50 | y1 = maxHeight - radius; // reposition it at the ground 51 | vy *= -0.8; // then reverse and reduce its speed 52 | } 53 | circ.style.transform = `translate3d(${x1}px, ${y1}px, 0`; 54 | circ.style.fill = `hsl(${y1/3 - 40}, 50%, 50%`; 55 | }; 56 | 57 | //***** helper functions *****// 58 | 59 | //function to set multiple attributes at once 60 | function setAttributes(el, attrs) { 61 | for (let key in attrs) { 62 | el.setAttribute(key, attrs[key]); 63 | } 64 | } 65 | 66 | //function to append children because typing 67 | function append(el, addition) { 68 | el.appendChild(addition); 69 | } -------------------------------------------------------------------------------- /11-bouncing-ball-svg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Bouncing ball SVG demo no library 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /11-bouncing-ball-svg/js/index.js: -------------------------------------------------------------------------------- 1 | // check babel file for original js 2 | 3 | "use strict"; 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | radius = 15, 9 | x1 = 0, 10 | // initial horizontal position 11 | y1 = 0, 12 | // initial vertical position 13 | g = 0.11, 14 | // acceleration due to gravity 15 | vx = 2, 16 | // initial horizontal speed 17 | vy = 0, 18 | // initial vertical speed 19 | maxHeight = 300; 20 | 21 | //set the SVG and the body 22 | document.body.style.background = '#222'; 23 | append(document.body, svg); 24 | setAttributes(svg, { 25 | "viewBox": "0 0 " + window.innerWidth + " " + window.innerHeight 26 | }); 27 | 28 | //make the circle 29 | var circ = document.createElementNS(svgNS, "circle"); 30 | append(svg, circ); 31 | setAttributes(circ, { 32 | "cx": x1, 33 | "cy": y1, 34 | "r": radius 35 | }); 36 | 37 | //use rAF to animate but put a boundary on it so it doesn't run forever 38 | var start = undefined; 39 | 40 | function step(timestamp) { 41 | if (!start) start = timestamp; 42 | var progress = timestamp - start; 43 | if (progress < 13000) { 44 | bounceBall(); 45 | window.requestAnimationFrame(step); 46 | } 47 | } 48 | window.requestAnimationFrame(step); 49 | 50 | //move it 51 | function bounceBall() { 52 | vy += g; // gravity increases the vertical speed 53 | x1 += vx; // horizontal speed inccrements horizontal position 54 | y1 += vy; // vertical speed increases vertical position 55 | 56 | if (y1 > maxHeight - radius) { 57 | // if ball hits the ground 58 | y1 = maxHeight - radius; // reposition it at the ground 59 | vy *= -0.8; // then reverse and reduce its speed 60 | } 61 | circ.style.transform = "translate3d(" + x1 + "px, " + y1 + "px, 0"; 62 | circ.style.fill = "hsl(" + (y1 / 3 - 40) + ", 50%, 50%"; 63 | }; 64 | 65 | //***** helper functions *****// 66 | 67 | //function to set multiple attributes at once 68 | function setAttributes(el, attrs) { 69 | for (var key in attrs) { 70 | el.setAttribute(key, attrs[key]); 71 | } 72 | } 73 | 74 | //function to append children because typing 75 | function append(el, addition) { 76 | el.appendChild(addition); 77 | } -------------------------------------------------------------------------------- /11-bouncing-ball-svg/license.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | -------------------------------------------------------------------------------- /12-svg-ball-ocsillating/README.txt: -------------------------------------------------------------------------------- 1 | A Pen created at CodePen.io. You can find this one at http://codepen.io/sdras/pen/87ae96beeb14ae775bdd26e0d0e616a6. 2 | 3 | -------------------------------------------------------------------------------- /12-svg-ball-ocsillating/babel/index.babel: -------------------------------------------------------------------------------- 1 | // codepen demo at http://codepen.io/sdras/full/rjQrJY 2 | 3 | let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 4 | svgNS = svg.namespaceURI, 5 | vbx = document.createElementNS(svgNS, "viewBox"), 6 | width = window.innerWidth, 7 | height = window.innerHeight, 8 | xA = new Array(), 9 | yA = new Array(), 10 | xmin = -10, 11 | xmax = 10, 12 | ymin = -20, 13 | ymax = 20, 14 | xorig = 300, 15 | yorig = 100, 16 | n = 0, 17 | ball, 18 | xscal, 19 | yscal; 20 | 21 | //set the SVG and the body 22 | document.body.style.background = '#222'; 23 | append(document.body, svg); 24 | setAttributes(svg, { 25 | "viewBox": `0 0 ${width} ${height}`, 26 | }); 27 | 28 | //***** Create the Ball *****// 29 | function Ball (radius, color) { 30 | this.circ = document.createElementNS(svgNS, "circle"); 31 | this.radius = radius; 32 | this.color = color; 33 | this.x = 0; 34 | this.y = 0; 35 | } 36 | 37 | Ball.prototype.draw = function() { 38 | append(svg, this.circ); 39 | setAttributes(this.circ, { 40 | "r": this.radius, 41 | "cx": this.x, 42 | "cy": this.y, 43 | "fill": this.color 44 | }); 45 | }; 46 | 47 | //***** Set up the Motion *****// 48 | window.onload = init; 49 | 50 | function init() { 51 | plotter(); 52 | placeBall(); 53 | window.requestAnimationFrame(step); 54 | } 55 | 56 | function plotter(){ 57 | xscal = (xmax-xmin)/(width/4); 58 | yscal = (ymax-ymin)/(height/4); 59 | for (var i = 0; i <= 1200; i++){ 60 | xA[i] = (i - 550) * 0.02; 61 | yA[i] = f(xA[i]); 62 | } 63 | } 64 | 65 | function f(x) { 66 | var y; 67 | y = (x+3.6)*(x+2.5)*(x+1)*(x-0.5)*(x-2)*(x-3.5)*Math.exp(-x*x/4); 68 | return y; 69 | } 70 | 71 | function placeBall() { 72 | ball = new Ball(10, "#7fdbd8"); 73 | ball.x = xA[0]/xscal + xorig; 74 | ball.y = -yA[0]/yscal + yorig; 75 | ball.draw(); 76 | } 77 | 78 | //use rAF to animate but put a boundary on it so it doesn't run forever 79 | function step(timestamp) { 80 | if (n !== xA.length){ 81 | moveBall(); 82 | window.requestAnimationFrame(step); 83 | } 84 | } 85 | 86 | function moveBall() { 87 | let xMove = xA[n*3]/xscal + xorig; 88 | let yMove = -yA[n*3]/yscal + yorig; 89 | ball.circ.style.transform = `translate3d(${xMove}px, ${yMove}px, 0`; 90 | n++; 91 | } 92 | 93 | //***** helper functions *****// 94 | 95 | //function to set multiple attributes at once 96 | function setAttributes(el, attrs) { 97 | for (let key in attrs) { 98 | el.setAttribute(key, attrs[key]); 99 | } 100 | } 101 | 102 | //function to append children because typing 103 | function append(el, addition) { 104 | el.appendChild(addition); 105 | } 106 | -------------------------------------------------------------------------------- /12-svg-ball-ocsillating/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG ball ocsillating, no library 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /12-svg-ball-ocsillating/js/index.js: -------------------------------------------------------------------------------- 1 | //see babel file 2 | 3 | "use strict"; 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | width = window.innerWidth, 9 | height = window.innerHeight, 10 | xA = new Array(), 11 | yA = new Array(), 12 | xmin = -10, 13 | xmax = 10, 14 | ymin = -20, 15 | ymax = 20, 16 | xorig = 300, 17 | yorig = 100, 18 | n = 0, 19 | ball = undefined, 20 | xscal = undefined, 21 | yscal = undefined; 22 | 23 | //set the SVG and the body 24 | document.body.style.background = '#222'; 25 | append(document.body, svg); 26 | setAttributes(svg, { 27 | "viewBox": "0 0 " + width + " " + height 28 | }); 29 | 30 | //***** Create the Ball *****// 31 | function Ball(radius, color) { 32 | this.circ = document.createElementNS(svgNS, "circle"); 33 | this.radius = radius; 34 | this.color = color; 35 | this.x = 0; 36 | this.y = 0; 37 | } 38 | 39 | Ball.prototype.draw = function () { 40 | append(svg, this.circ); 41 | setAttributes(this.circ, { 42 | "r": this.radius, 43 | "cx": this.x, 44 | "cy": this.y, 45 | "fill": this.color 46 | }); 47 | }; 48 | 49 | //***** Set up the Motion *****// 50 | window.onload = init; 51 | 52 | function init() { 53 | plotter(); 54 | placeBall(); 55 | window.requestAnimationFrame(step); 56 | } 57 | 58 | function plotter() { 59 | xscal = (xmax - xmin) / (width / 4); 60 | yscal = (ymax - ymin) / (height / 4); 61 | for (var i = 0; i <= 1200; i++) { 62 | xA[i] = (i - 550) * 0.02; 63 | yA[i] = f(xA[i]); 64 | } 65 | } 66 | 67 | function f(x) { 68 | var y; 69 | y = (x + 3.6) * (x + 2.5) * (x + 1) * (x - 0.5) * (x - 2) * (x - 3.5) * Math.exp(-x * x / 4); 70 | return y; 71 | } 72 | 73 | function placeBall() { 74 | ball = new Ball(10, "#7fdbd8"); 75 | ball.x = xA[0] / xscal + xorig; 76 | ball.y = -yA[0] / yscal + yorig; 77 | ball.draw(); 78 | } 79 | 80 | //use rAF to animate but put a boundary on it so it doesn't run forever 81 | function step(timestamp) { 82 | if (n !== xA.length) { 83 | moveBall(); 84 | window.requestAnimationFrame(step); 85 | } 86 | } 87 | 88 | function moveBall() { 89 | var xMove = xA[n * 3] / xscal + xorig; 90 | var yMove = -yA[n * 3] / yscal + yorig; 91 | ball.circ.style.transform = "translate3d(" + xMove + "px, " + yMove + "px, 0"; 92 | n++; 93 | } 94 | 95 | //***** helper functions *****// 96 | 97 | //function to set multiple attributes at once 98 | function setAttributes(el, attrs) { 99 | for (var key in attrs) { 100 | el.setAttribute(key, attrs[key]); 101 | } 102 | } 103 | 104 | //function to append children because typing 105 | function append(el, addition) { 106 | el.appendChild(addition); 107 | } -------------------------------------------------------------------------------- /13-small-svg-pool-splash/README.txt: -------------------------------------------------------------------------------- 1 | A Pen created at CodePen.io. You can find this one at http://codepen.io/sdras/pen/ygGzaZ. 2 | 3 | -------------------------------------------------------------------------------- /13-small-svg-pool-splash/babel/index.babel: -------------------------------------------------------------------------------- 1 | // codepen demo at http://codepen.io/sdras/full/ygGzaZ/ 2 | 3 | let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 4 | svgNS = svg.namespaceURI, 5 | vbx = document.createElementNS(svgNS, "viewBox"), 6 | g = document.createElementNS(svgNS, "g"), 7 | color = '#73d2ff', 8 | width = 800, 9 | height = 300, 10 | xA = new Array(), 11 | yA = new Array(), 12 | xmin = -10, 13 | xmax = 10, 14 | ymin = -20, 15 | ymax = 20, 16 | xorig = 300, 17 | yorig = 100, 18 | n = 0, 19 | bk, 20 | ball, 21 | ball2, 22 | xscal, 23 | yscal; 24 | 25 | //set the SVG and the body 26 | document.body.style.background = '#222'; 27 | const poolC = document.getElementById("poolcontain"); 28 | append(poolC, g); 29 | setAttributes(g, { 30 | "class": "elastic", 31 | "filter": "url('#goo')", 32 | "style": "transform:translate3d(600px, 344px, 0) rotate(180deg) scale(0.5)" 33 | }); 34 | 35 | //***** Create the Bk *****// 36 | function Background(color) { 37 | this.panel = document.createElementNS(svgNS, "path"); 38 | this.color = color; 39 | this.y = 0; 40 | this.y2 = 0; 41 | this.inc = 150; 42 | this.start = 175; 43 | } 44 | 45 | Background.prototype.draw = function() { 46 | append(g, this.panel); 47 | setAttributes(this.panel, { 48 | "d": `M ${this.start} 100 Q ${this.start+50} ${this.y2} ${this.start+75} 100 Q ${width/2} ${this.y} ${width-(this.inc+75)} 100 Q ${width-this.inc} ${this.y2} ${width-this.inc} 100 L ${width} 0 L 0 0 Z`, 49 | "fill": this.color, 50 | }); 51 | }; 52 | 53 | //***** Create the Ball *****// 54 | function Ball (radius, color) { 55 | this.circ = document.createElementNS(svgNS, "circle"); 56 | this.radius = radius; 57 | this.color = color; 58 | this.y = 0; 59 | } 60 | 61 | Ball.prototype.draw = function() { 62 | append(g, this.circ); 63 | setAttributes(this.circ, { 64 | "r": this.radius, 65 | "cx": width/2, 66 | "cy": this.y, 67 | "fill": this.color, 68 | }); 69 | }; 70 | 71 | //***** Set up the Motion *****// 72 | window.onload = init; 73 | 74 | function init() { 75 | plotter(); 76 | placeBall(); 77 | placeBk(); 78 | window.requestAnimationFrame(step); 79 | } 80 | 81 | function plotter(){ 82 | xscal = (xmax-xmin)/(width/4); 83 | yscal = (ymax-ymin)/(height/4); 84 | for (let i = 0; i <= 1500; i++){ 85 | //set the boundary for how much plays here 86 | xA[i] = (i - 0) * 0.02; 87 | yA[i] = f(xA[i]); 88 | } 89 | } 90 | 91 | function f(x) { 92 | let y; 93 | y = (x+3.6)*(x+2.5)*(x+1)*(x-0.5)*(x-2)*(x-3.5)*Math.exp(-x*x/4); 94 | return y; 95 | } 96 | 97 | function placeBk() { 98 | let orig = yA[0]/yscal + yorig; 99 | bk = new Background(color); 100 | bk.x = xA[0]/xscal + xorig; 101 | bk.y2 = orig; 102 | bk.y = orig; 103 | bk.draw(); 104 | } 105 | 106 | function placeBall() { 107 | //ball 1 108 | ball = new Ball(12, '#59c1f2'); 109 | ball.x = xA[0]/xscal + xorig; 110 | ball.draw(); 111 | //ball 2 112 | ball2 = new Ball(5, '#bee5f7'); 113 | ball2.x = xA[0]/xscal + xorig; 114 | ball2.draw(); 115 | } 116 | 117 | //use rAF to animate but put a boundary on it so it doesn't run forever 118 | function step(timestamp) { 119 | //console.log(bk.x); 120 | if (bk.x < 440){ 121 | moveBk(); 122 | moveBall(); 123 | window.requestAnimationFrame(step); 124 | } 125 | } 126 | 127 | function moveBk() { 128 | bk.x = xA[n]/xscal + xorig; 129 | bk.y2 = yA[n]/(yscal*4) + yorig; 130 | bk.y = -yA[n]/(yscal/1) + yorig; 131 | bk.draw(); 132 | n++; 133 | } 134 | 135 | function moveBall() { 136 | let yMove = yA[n]/(yscal/1) + (yorig - 30); 137 | let yMove2 = (yA[n]/yscal)*2 + (yorig - 50); 138 | ball.circ.style.transform = `translate3d(0, ${yMove}px, 0`; 139 | ball2.circ.style.transform = `translate3d(0, ${yMove2}px, 0`; 140 | n++; 141 | } 142 | 143 | //***** helper functions *****// 144 | 145 | //function to set multiple attributes at once 146 | function setAttributes(el, attrs) { 147 | for (let key in attrs) { 148 | el.setAttribute(key, attrs[key]); 149 | } 150 | } 151 | 152 | //function to append children because typing 153 | function append(el, addition) { 154 | el.appendChild(addition); 155 | } 156 | -------------------------------------------------------------------------------- /13-small-svg-pool-splash/css/style.css: -------------------------------------------------------------------------------- 1 | #poolcontain { 2 | position: relative; 3 | } 4 | 5 | .poolarea { 6 | position: absolute; 7 | left: 50%; 8 | -webkit-transform: translate3d(-400px, -90px, 0); 9 | transform: translate3d(-400px, -90px, 0); 10 | } 11 | -------------------------------------------------------------------------------- /13-small-svg-pool-splash/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Small SVG pool splash, no library 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /13-small-svg-pool-splash/js/index.js: -------------------------------------------------------------------------------- 1 | //see babel file 2 | 3 | "use strict"; 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | g = document.createElementNS(svgNS, "g"), 9 | color = '#73d2ff', 10 | width = 800, 11 | height = 300, 12 | xA = new Array(), 13 | yA = new Array(), 14 | xmin = -10, 15 | xmax = 10, 16 | ymin = -20, 17 | ymax = 20, 18 | xorig = 300, 19 | yorig = 100, 20 | n = 0, 21 | bk = undefined, 22 | ball = undefined, 23 | ball2 = undefined, 24 | xscal = undefined, 25 | yscal = undefined; 26 | 27 | //set the SVG and the body 28 | document.body.style.background = '#222'; 29 | var poolC = document.getElementById("poolcontain"); 30 | append(poolC, g); 31 | setAttributes(g, { 32 | "class": "elastic", 33 | "filter": "url('#goo')", 34 | "style": "transform:translate3d(600px, 344px, 0) rotate(180deg) scale(0.5)" 35 | }); 36 | 37 | //***** Create the Bk *****// 38 | function Background(color) { 39 | this.panel = document.createElementNS(svgNS, "path"); 40 | this.color = color; 41 | this.y = 0; 42 | this.y2 = 0; 43 | this.inc = 150; 44 | this.start = 175; 45 | } 46 | 47 | Background.prototype.draw = function () { 48 | append(g, this.panel); 49 | setAttributes(this.panel, { 50 | "d": "M " + this.start + " 100 Q " + (this.start + 50) + " " + this.y2 + " " + (this.start + 75) + " 100 Q " + width / 2 + " " + this.y + " " + (width - (this.inc + 75)) + " 100 Q " + (width - this.inc) + " " + this.y2 + " " + (width - this.inc) + " 100 L " + width + " 0 L 0 0 Z", 51 | "fill": this.color 52 | }); 53 | }; 54 | 55 | //***** Create the Ball *****// 56 | function Ball(radius, color) { 57 | this.circ = document.createElementNS(svgNS, "circle"); 58 | this.radius = radius; 59 | this.color = color; 60 | this.y = 0; 61 | } 62 | 63 | Ball.prototype.draw = function () { 64 | append(g, this.circ); 65 | setAttributes(this.circ, { 66 | "r": this.radius, 67 | "cx": width / 2, 68 | "cy": this.y, 69 | "fill": this.color 70 | }); 71 | }; 72 | 73 | //***** Set up the Motion *****// 74 | window.onload = init; 75 | 76 | function init() { 77 | plotter(); 78 | placeBall(); 79 | placeBk(); 80 | window.requestAnimationFrame(step); 81 | } 82 | 83 | function plotter() { 84 | xscal = (xmax - xmin) / (width / 4); 85 | yscal = (ymax - ymin) / (height / 4); 86 | for (var i = 0; i <= 1500; i++) { 87 | //set the boundary for how much plays here 88 | xA[i] = (i - 0) * 0.02; 89 | yA[i] = f(xA[i]); 90 | } 91 | } 92 | 93 | function f(x) { 94 | var y = undefined; 95 | y = (x + 3.6) * (x + 2.5) * (x + 1) * (x - 0.5) * (x - 2) * (x - 3.5) * Math.exp(-x * x / 4); 96 | return y; 97 | } 98 | 99 | function placeBk() { 100 | var orig = yA[0] / yscal + yorig; 101 | bk = new Background(color); 102 | bk.x = xA[0] / xscal + xorig; 103 | bk.y2 = orig; 104 | bk.y = orig; 105 | bk.draw(); 106 | } 107 | 108 | function placeBall() { 109 | //ball 1 110 | ball = new Ball(12, '#59c1f2'); 111 | ball.x = xA[0] / xscal + xorig; 112 | ball.draw(); 113 | //ball 2 114 | ball2 = new Ball(5, '#bee5f7'); 115 | ball2.x = xA[0] / xscal + xorig; 116 | ball2.draw(); 117 | } 118 | 119 | //use rAF to animate but put a boundary on it so it doesn't run forever 120 | function step(timestamp) { 121 | //console.log(bk.x); 122 | if (bk.x < 440) { 123 | moveBk(); 124 | moveBall(); 125 | window.requestAnimationFrame(step); 126 | } 127 | } 128 | 129 | function moveBk() { 130 | bk.x = xA[n] / xscal + xorig; 131 | bk.y2 = yA[n] / (yscal * 4) + yorig; 132 | bk.y = -yA[n] / (yscal / 1) + yorig; 133 | bk.draw(); 134 | n++; 135 | } 136 | 137 | function moveBall() { 138 | var yMove = yA[n] / (yscal / 1) + (yorig - 30); 139 | var yMove2 = yA[n] / yscal * 2 + (yorig - 50); 140 | ball.circ.style.transform = "translate3d(0, " + yMove + "px, 0"; 141 | ball2.circ.style.transform = "translate3d(0, " + yMove2 + "px, 0"; 142 | n++; 143 | } 144 | 145 | //***** helper functions *****// 146 | 147 | //function to set multiple attributes at once 148 | function setAttributes(el, attrs) { 149 | for (var key in attrs) { 150 | el.setAttribute(key, attrs[key]); 151 | } 152 | } 153 | 154 | //function to append children because typing 155 | function append(el, addition) { 156 | el.appendChild(addition); 157 | } -------------------------------------------------------------------------------- /13-small-svg-pool-splash/license.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | -------------------------------------------------------------------------------- /13-small-svg-pool-splash/scss/style.scss: -------------------------------------------------------------------------------- 1 | #poolcontain { 2 | position: relative; 3 | } 4 | 5 | .poolarea { 6 | position: absolute; 7 | left: 50%; 8 | transform: translate3d(-400px, -90px, 0); 9 | } -------------------------------------------------------------------------------- /2-chapter-1-3-nature-of-code-in-js-svg/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /2-chapter-1-3-nature-of-code-in-js-svg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chapter 1.3 of The Nature of Code, in JS 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /2-chapter-1-3-nature-of-code-in-js-svg/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Processing to JS from https://github.com/shiffman/The-Nature-of-Code-Examples/blob/master/chp01_vectors/NOC_1_3_vector_subtraction/NOC_1_3_vector_subtraction.pde 2 | // live demo at http://codepen.io/sdras/pen/5ef8dc81f804d7bd5004e11f7f1902ef 3 | 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | poL = document.createElementNS(svgNS, "polyline"); 9 | 10 | svg.appendChild(poL); 11 | document.body.appendChild(svg); 12 | document.body.style.background = '#222'; 13 | svg.setAttribute("class", "ball"); 14 | svg.setAttribute("viewBox", "0 0 800 600"); 15 | svg.setAttribute("width", "800"); 16 | svg.setAttribute("height", "600"); 17 | 18 | document.onmousemove = handleMouseMove; 19 | 20 | function handleMouseMove(event) { 21 | var dot, eventDoc, doc, body, pageX, pageY; 22 | 23 | event = event || window.event; // IE-ism 24 | 25 | if (event.pageX == null && event.clientX != null) { 26 | eventDoc = (event.target && event.target.ownerDocument) || document; 27 | doc = eventDoc.documentElement; 28 | body = eventDoc.body; 29 | 30 | event.pageX = event.clientX + 31 | (doc && doc.scrollLeft || body && body.scrollLeft || 0) - 32 | (doc && doc.clientLeft || body && body.clientLeft || 0); 33 | event.pageY = event.clientY + 34 | (doc && doc.scrollTop || body && body.scrollTop || 0) - 35 | (doc && doc.clientTop || body && body.clientTop || 0); 36 | } 37 | 38 | var polCoor = event.pageX + " " + event.pageY; 39 | 40 | var poLstring = "500 150 " + polCoor; 41 | poL.setAttribute('points', poLstring); 42 | } -------------------------------------------------------------------------------- /3-chapter-1-5-nature-of-code-in-js-svg/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /3-chapter-1-5-nature-of-code-in-js-svg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chapter 1.5 of The Nature of Code, in JS 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /3-chapter-1-5-nature-of-code-in-js-svg/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Processing to JS from https://github.com/shiffman/The-Nature-of-Code-Examples/blob/master/chp01_vectors/NOC_1_5_vector_magnitude/NOC_1_5_vector_magnitude.pde 2 | // live demo at http://codepen.io/sdras/pen/13bfbe6ec5bfc9e17e61fac39030c6e8 3 | 4 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 5 | svgNS = svg.namespaceURI, 6 | vbx = document.createElementNS(svgNS, "viewBox"), 7 | poL = document.createElementNS(svgNS, "polyline"), 8 | rct = document.createElementNS(svgNS, "rect"); 9 | 10 | svg.appendChild(poL); 11 | svg.appendChild(rct); 12 | document.body.appendChild(svg); 13 | document.body.style.background = '#222'; 14 | svg.setAttribute("viewBox", "0 0 1000 600"); 15 | svg.setAttribute("width", "1000"); 16 | svg.setAttribute("height", "600"); 17 | rct.setAttribute("height", "8"); 18 | 19 | document.onmousemove = handleMouseMove; 20 | 21 | function handleMouseMove(event) { 22 | var dot, eventDoc, doc, body, pageX, pageY; 23 | 24 | event = event || window.event; // IE-ism 25 | 26 | if (event.pageX == null && event.clientX != null) { 27 | eventDoc = (event.target && event.target.ownerDocument) || document; 28 | doc = eventDoc.documentElement; 29 | body = eventDoc.body; 30 | 31 | event.pageX = event.clientX + 32 | (doc && doc.scrollLeft || body && body.scrollLeft || 0) - 33 | (doc && doc.clientLeft || body && body.clientLeft || 0); 34 | event.pageY = event.clientY + 35 | (doc && doc.scrollTop || body && body.scrollTop || 0) - 36 | (doc && doc.clientTop || body && body.clientTop || 0); 37 | } 38 | 39 | var polCoor = event.pageX + " " + event.pageY; 40 | 41 | var poLstring = "500 150 " + polCoor; 42 | poL.setAttribute('points', poLstring); 43 | 44 | rct.setAttribute('width', event.pageX); 45 | } -------------------------------------------------------------------------------- /4-hack-physics-and-js-nocanvas-svg-1/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /4-hack-physics-and-js-nocanvas-svg-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hack Physics and JS, SVG no Canvas version part 1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /4-hack-physics-and-js-nocanvas-svg-1/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this post http://codepen.io/rachsmith/post/hack-physics-and-javascript-1 2 | // live demo at http://codepen.io/sdras/pen/b2ed94b0b4eaf55b4b6e2d4a92c318ed 3 | 4 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 5 | svgNS = svg.namespaceURI, 6 | vbx = document.createElementNS(svgNS, "viewBox"), 7 | circ = document.createElementNS(svgNS, "circle"), 8 | coord = 20, 9 | width = window.innerWidth, 10 | height = window.innerHeight; 11 | 12 | document.body.appendChild(svg); 13 | document.body.style.background = '#222'; 14 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 15 | svg.setAttribute("width", width); 16 | svg.setAttribute("height", height); 17 | svg.appendChild(circ); 18 | circ.setAttribute("r", "10"); 19 | circ.setAttribute("fill", "orangered"); 20 | 21 | function repeatOften() { 22 | coord += 2; 23 | circ.setAttribute("cx", coord); 24 | circ.setAttribute("cy", coord); 25 | 26 | if (coord > height) { 27 | coord = 0; 28 | } 29 | 30 | requestAnimationFrame(repeatOften); 31 | } 32 | requestAnimationFrame(repeatOften); -------------------------------------------------------------------------------- /5-hack-physics-and-js-nocanvas-svg-2/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /5-hack-physics-and-js-nocanvas-svg-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hack Physics and JS, SVG no Canvas version part 2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /5-hack-physics-and-js-nocanvas-svg-2/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this post http://codepen.io/rachsmith/post/hack-physics-and-javascript-1 2 | // live demo at http://codepen.io/sdras/pen/aceb6170e4d70e9d5cff8f4a2ff37245 3 | 4 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 5 | svgNS = svg.namespaceURI, 6 | vbx = document.createElementNS(svgNS, "viewBox"), 7 | circ = document.createElementNS(svgNS, "circle"), 8 | coord = 20, 9 | vel = 2, 10 | accel = 0.5, 11 | width = window.innerWidth, 12 | height = window.innerHeight; 13 | 14 | document.body.appendChild(svg); 15 | document.body.style.background = '#222'; 16 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 17 | svg.setAttribute("width", width); 18 | svg.setAttribute("height", height); 19 | svg.appendChild(circ); 20 | circ.setAttribute("r", "10"); 21 | circ.setAttribute("fill", "orangered"); 22 | 23 | function repeatOften() { 24 | vel += accel; 25 | coord += vel; 26 | circ.setAttribute("cx", coord); 27 | circ.setAttribute("cy", coord); 28 | 29 | if (coord > height) { 30 | coord = 0; 31 | vel = 0; 32 | } 33 | 34 | requestAnimationFrame(repeatOften); 35 | } 36 | requestAnimationFrame(repeatOften); -------------------------------------------------------------------------------- /6-hack-physics-and-js-nocanvas-svg-3/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /6-hack-physics-and-js-nocanvas-svg-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hack Physics and JS, SVG no Canvas version part 3 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /6-hack-physics-and-js-nocanvas-svg-3/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this post http://codepen.io/rachsmith/post/hack-physics-and-javascript-1 2 | // live demo at http://codepen.io/sdras/pen/4d353ad01bab58a19d32abf1d435fcaa 3 | 4 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 5 | svgNS = svg.namespaceURI, 6 | vbx = document.createElementNS(svgNS, "viewBox"), 7 | coord = 20, 8 | vel = 2, 9 | accel = 0.5, 10 | width = window.innerWidth, 11 | height = window.innerHeight, 12 | particles = [], 13 | colors = ['#029DAF', '#E5D599', '#FFC219', '#F07C19', '#E32551']; 14 | 15 | document.body.appendChild(svg); 16 | document.body.style.background = '#222'; 17 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 18 | svg.setAttribute("width", width); 19 | svg.setAttribute("height", height); 20 | 21 | //pretty much unchanged from Rachels 22 | function initParticles() { 23 | for (var i = 0; i < 200; i++) { 24 | setTimeout(createParticle, 20*i, i); 25 | } 26 | } 27 | 28 | function createParticle(i) { 29 | // initial position in middle of viewbox 30 | var x = width*0.5; 31 | var y = height*0.5; 32 | // randomize the acceleration a little - but we still want them flying 'up' and 'out' 33 | var accelX = -2+Math.random()*4; 34 | var accelY = Math.random()*-3; 35 | // randomize size and opacity a little & pick a color from our color palette 36 | var size = 5+Math.random()*5; 37 | var color = colors[i%colors.length]; 38 | var opacity = 0.5 + Math.random()*0.5; 39 | var p = new Particle(x, y, accelX, accelY, size, color, opacity); 40 | particles.push(p); 41 | } 42 | 43 | //we create the particles differently because of SVG drawing, we don't need draw() but we still update. 44 | function Particle(x, y, accelX, accelY, size, color, opacity) { 45 | var circ = document.createElementNS(svgNS, "circle"); 46 | svg.appendChild(circ); 47 | circ.setAttribute("r", (size/2)); 48 | circ.setAttribute("fill", color); 49 | 50 | this.update = function() { 51 | x += accelX; 52 | y += accelY; 53 | 54 | circ.setAttribute("cx", x); 55 | circ.setAttribute("cy", y); 56 | } 57 | } 58 | 59 | //rAF part 60 | function repeatOften() { 61 | for (var i = 0; i < particles.length; i++) { 62 | particles[i].update(); 63 | } 64 | requestAnimationFrame(repeatOften); 65 | } 66 | requestAnimationFrame(repeatOften); 67 | 68 | // init 69 | initParticles(); -------------------------------------------------------------------------------- /7-hack-physics-and-js-nocanvas-svg-4/README.txt: -------------------------------------------------------------------------------- 1 | A Pen created at CodePen.io. You can find this one at http://codepen.io/sdras/pen/2bdd461ea2d56a6c1403c8a9282dc6fe. 2 | 3 | -------------------------------------------------------------------------------- /7-hack-physics-and-js-nocanvas-svg-4/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /7-hack-physics-and-js-nocanvas-svg-4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hack Physics and JS, SVG no Canvas version part 4 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /7-hack-physics-and-js-nocanvas-svg-4/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this post http://codepen.io/rachsmith/post/hack-physics-and-javascript-1 2 | // live demo at http://codepen.io/sdras/pen/2bdd461ea2d56a6c1403c8a9282dc6fe 3 | // rewrote particle and create particle function to reduce repetition, but this might have made it more costly because it holds more state. 4 | 5 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 6 | svgNS = svg.namespaceURI, 7 | vbx = document.createElementNS(svgNS, "viewBox"), 8 | coord = 20, 9 | vel = 2, 10 | accel = 0.5, 11 | width = window.innerWidth, 12 | height = window.innerHeight, 13 | particles = [], 14 | colors = ['#029DAF', '#E5D599', '#FFC219', '#F07C19', '#E32551'], 15 | gravity = 0.04; 16 | 17 | document.body.appendChild(svg); 18 | document.body.style.background = '#222'; 19 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 20 | svg.setAttribute("width", width); 21 | svg.setAttribute("height", height); 22 | 23 | function initParticles() { 24 | for (var i = 0; i < 200; i++) { 25 | setTimeout(createParticle, 20*i, i); 26 | } 27 | } 28 | 29 | function createParticle(i) { 30 | var p = new Particle(i); 31 | particles.push(p); 32 | } 33 | 34 | function Particle(i) { 35 | // initial position in middle of viewbox 36 | var x, 37 | y, 38 | accelX, 39 | accelY, 40 | opacity, 41 | size = 5+Math.random()*5, 42 | color = colors[i%colors.length]; 43 | 44 | var circ = document.createElementNS(svgNS, "circle"); 45 | svg.appendChild(circ); 46 | circ.setAttribute("r", (size/2)); 47 | circ.setAttribute("fill", color); 48 | 49 | this.reset = function() { 50 | x = width*0.5; 51 | y = height*0.5; 52 | 53 | opacity = 0.5 + Math.random()*0.5; 54 | accelX = -2+Math.random()*4; 55 | accelY = Math.random()*-3; 56 | }; 57 | 58 | this.reset(); 59 | 60 | this.update = function() { 61 | if (opacity - 0.005 > 0) opacity -= 0.005 ; 62 | else this.reset(); 63 | 64 | accelY += gravity; 65 | x += accelX; 66 | y += accelY; 67 | 68 | circ.setAttribute("cx", x); 69 | circ.setAttribute("cy", y); 70 | } 71 | } 72 | 73 | //rAF part 74 | function repeatOften() { 75 | for (var i = 0; i < particles.length; i++) { 76 | particles[i].update(); 77 | } 78 | requestAnimationFrame(repeatOften); 79 | } 80 | requestAnimationFrame(repeatOften); 81 | 82 | // init 83 | initParticles(); -------------------------------------------------------------------------------- /8-better-way-utilizing-object-pool-nocanvas-svg/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /8-better-way-utilizing-object-pool-nocanvas-svg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Better way utilizing object pool - no canvas, SVG version 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /8-better-way-utilizing-object-pool-nocanvas-svg/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this pen http://codepen.io/rachsmith/pen/PPzoxv?editors=1010 2 | // live demo at http://codepen.io/sdras/pen/e805476fd38a7cc3657e2027f3fc0b17 3 | 4 | //step one: changed bubble and bubbles to be single and lots, because I couldn't easily see what was bubble and what was Bubble and what was bubbles. 5 | //step two: changed to using height and width instead of hard-coded integers, create conditionals for large heights 6 | //step three: convert to svg 7 | //step four: incorporated PR to use elapsed time to calculate animation, https://github.com/sdras/JS-stroll/pull/2 + performs better 8 | 9 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 10 | svgNS = svg.namespaceURI, 11 | vbx = document.createElementNS(svgNS, "viewBox"), 12 | width = window.innerWidth, 13 | height = window.innerHeight, 14 | gravity = 0.00009, 15 | friction = 0.000001, 16 | lots = [], 17 | prevTime; 18 | 19 | document.body.appendChild(svg); 20 | document.body.style.background = '#222'; 21 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 22 | svg.setAttribute("width", width); 23 | svg.setAttribute("height", height); 24 | 25 | Bubble.prototype = { 26 | init: function (x, y, vx, vy) { 27 | this.x = x; 28 | this.y = y; 29 | this.vx = vx; 30 | this.vy = vy; 31 | }, 32 | update: function (dt) { 33 | // friction opposes the direction of velocity 34 | var acceleration = -Math.sign(this.vx) * friction; 35 | // distance = velocity * time + 0.5 * acceleration * (time ^ 2) 36 | this.x += this.vx * dt + 0.5 * acceleration * (dt ^ 2); 37 | this.y += this.vy * dt + 0.5 * gravity * (dt ^ 2); 38 | // velocity = velocity + acceleration * time 39 | this.vy += gravity * dt; 40 | this.vx += acceleration * dt; 41 | this.circ.setAttribute("cx", this.x); 42 | this.circ.setAttribute("cy", this.y); 43 | this.circ.setAttribute("stroke", "rgba(1,146,190," + this.opacity + ")"); 44 | } 45 | }; 46 | 47 | for (var i = 0; i < 150; i++) { 48 | setTimeout(function () { 49 | var single = new Bubble(0.5+Math.random()*0.5, 5 + Math.random()*10); 50 | initBubble(single); 51 | lots.push(single); 52 | }, i*18); 53 | } 54 | 55 | function Bubble(opacity, radius) { 56 | this.init(width/2, height/2, 0, 0); 57 | this.opacity = opacity; 58 | this.radius = radius; 59 | var circ = document.createElementNS(svgNS, "circle"); 60 | svg.appendChild(circ); 61 | circ.setAttribute("r", this.radius); 62 | circ.setAttribute("fill", "none"); 63 | circ.setAttribute("stroke-width", "1px"); 64 | this.circ = circ; 65 | } 66 | 67 | function initBubble(single) { 68 | single.init(width/2, height/2, -0.05 + Math.random()*0.1, -0.1 + Math.random()*0.1); 69 | } 70 | 71 | (function animate(currentTime) { 72 | var dt; 73 | requestAnimationFrame(animate); 74 | if (!prevTime) { 75 | // only save previous time 76 | prevTime = currentTime; 77 | return; 78 | } else { 79 | // calculate the time difference between frames 80 | // it has to be less than 25ms because of switching between tabs 81 | dt = Math.min(currentTime - prevTime, 25); 82 | prevTime = currentTime; 83 | } 84 | for (var i = 0; i < lots.length; i++) { 85 | lots[i].update(dt); 86 | 87 | //if the height is small, just let it start over when it gets to the bottom, otherwise, at 3/4 (so that there aren't big gaps) 88 | if (height < 500) { 89 | if (lots[i].y > height) { 90 | initBubble(lots[i]); 91 | } 92 | } else { 93 | if (lots[i].y > height*0.85) { 94 | initBubble(lots[i]); 95 | } 96 | } 97 | } 98 | }()); 99 | -------------------------------------------------------------------------------- /9-changing-linear-gradient-particle-fountain/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */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,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /9-changing-linear-gradient-particle-fountain/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Changing Linear Gradient Particle Fountain - no canvas, SVG version 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /9-changing-linear-gradient-particle-fountain/js/index.js: -------------------------------------------------------------------------------- 1 | // rewritten from Canvas to SVG and Vanilla JS from this pen http://codepen.io/rachsmith/pen/PPzoxv?editors=1010 2 | // similar to directory 8, but changed initBubble to be a reset method on the Bubble prototype 3 | // added in changing linear gradients per bubble, altered opacity to be on the fill 4 | // live demo at http://codepen.io/sdras/pen/76bd5fe8dd7f98c9e2df47a57865f44d 5 | 6 | var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), 7 | svgNS = svg.namespaceURI, 8 | vbx = document.createElementNS(svgNS, "viewBox"), 9 | width = window.innerWidth, 10 | height = window.innerHeight, 11 | gravity = 0.00009, 12 | friction = 0.000001, 13 | lots = [], 14 | prevTime; 15 | 16 | document.body.appendChild(svg); 17 | document.body.style.background = '#222'; 18 | svg.setAttribute("viewBox", "0 0 " + width + " " + height); 19 | svg.setAttribute("width", width); 20 | svg.setAttribute("height", height); 21 | 22 | var defs = document.createElementNS(svgNS, "defs"); 23 | svg.appendChild(defs); 24 | 25 | //makin' gradients 26 | for (var i = 0; i < 10; i++) { 27 | var lg = document.createElementNS(svgNS, "linearGradient"); 28 | defs.appendChild(lg); 29 | lg.setAttribute("id", "linear-gradient" + i); 30 | var stop1 = document.createElementNS(svgNS, "stop"); 31 | lg.appendChild(stop1); 32 | var stop2 = document.createElementNS(svgNS, "stop"); 33 | lg.appendChild(stop2); 34 | stop1.setAttribute("offset", "0%"); 35 | stop1.setAttribute("stop-color", "rgb(29, " + (Math.floor(Math.random() * (i * 20)) + 1) + ", 214)"); 36 | stop2.setAttribute("offset", "100%"); 37 | stop2.setAttribute("stop-color", "#d7191c"); 38 | } 39 | 40 | function Bubble(opacity, radius) { 41 | this.init(width/2, height/2, 0, 0); 42 | this.opacity = opacity; 43 | this.radius = radius; 44 | var circ = document.createElementNS(svgNS, "circle"); 45 | svg.appendChild(circ); 46 | circ.setAttribute("r", this.radius); 47 | circ.setAttribute("fill", "url(#linear-gradient" + (Math.floor(Math.random() * 10) + 1) + ")"); 48 | this.circ = circ; 49 | } 50 | 51 | Bubble.prototype = { 52 | init: function (x, y, vx, vy) { 53 | this.x = x; 54 | this.y = y; 55 | this.vx = vx; 56 | this.vy = vy; 57 | }, 58 | reset: function () { 59 | this.init(width/2, height/2, -0.05 + Math.random()*0.1, -0.1 + Math.random()*0.1); 60 | }, 61 | update: function (dt) { 62 | // friction opposes the direction of velocity 63 | var acceleration = -Math.sign(this.vx) * friction; 64 | // distance = velocity * time + 0.5 * acceleration * (time ^ 2) 65 | this.x += this.vx * dt + 0.5 * acceleration * (dt ^ 2); 66 | this.y += this.vy * dt + 0.5 * gravity * (dt ^ 2); 67 | // velocity = velocity + acceleration * time 68 | this.vy += gravity * dt; 69 | this.vx += acceleration * dt; 70 | this.circ.setAttribute("cx", this.x); 71 | this.circ.setAttribute("cy", this.y); 72 | this.circ.setAttribute("opacity", this.opacity); 73 | } 74 | }; 75 | 76 | for (var i = 0; i < 150; i++) { 77 | setTimeout(function () { 78 | var single = new Bubble(0.5+Math.random()*0.5, 5 + Math.random()*10); 79 | single.reset(); 80 | lots.push(single); 81 | }, i*18); 82 | } 83 | 84 | (function animate(currentTime) { 85 | var dt; 86 | requestAnimationFrame(animate); 87 | if (!prevTime) { 88 | // only save previous time 89 | prevTime = currentTime; 90 | return; 91 | } else { 92 | // calculate the time difference between frames 93 | // it has to be less than 25ms because of switching between tabs 94 | dt = Math.min(currentTime - prevTime, 25); 95 | prevTime = currentTime; 96 | } 97 | for (var i = 0; i < lots.length; i++) { 98 | lots[i].update(dt); 99 | 100 | //if the height is small, just let it start over when it gets to the bottom, otherwise, at 3/4 (so that there aren't big gaps) 101 | if (height < 500) { 102 | if (lots[i].y > height) { 103 | lots[i].reset(); 104 | } 105 | } else { 106 | if (lots[i].y > height*0.85) { 107 | lots[i].reset(); 108 | } 109 | } 110 | } 111 | }()); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JS-stroll 2 | 3 | This repo is comprised of tiny JavaScript and SVG excercises for generative effects. 4 | 5 | Some of these demos are rewriting code from 'The Nature of Code', originally written in Processing, in JavaScript to solidify the unerlying concepts. Some are rewriting Rachel Smith's Hack Physics with JavaScript posts in SVG and vanilla JS (originals are in Canvas). Some are just taking physics equations and using them to write demos with SVG. 6 | 7 | If it was rewritten from another source, commented at the top of the main.js file of every directory is the url to the original code, where applicable. 8 | 9 | If I used ES6, the babel file will have the original source code, and the linked js will have the compiled JavaScript. 10 | 11 | All files have a link to a CodePen demo of the output. --------------------------------------------------------------------------------