From d319f523e97bd9ea40d1a19dc6378f1f13f8e606 Mon Sep 17 00:00:00 2001 From: Keith Peters Date: Wed, 18 Mar 2015 08:20:04 -0400 Subject: [PATCH] episode 38. plus it looks like a lot of line endings got changed. --- README.md | 20 +- application1/index.html | 44 +-- application1/main.js | 100 +++--- application1/particle.js | 94 ++--- application1/utils.js | 32 +- application1/vector.js | 164 ++++----- application2/index.html | 44 +-- application2/main.js | 192 +++++----- application2/particle.js | 94 ++--- application2/utils.js | 32 +- application2/vector.js | 164 ++++----- application3/code.sublime-project | 14 +- application3/index.html | 44 +-- application3/main.js | 218 ++++++------ application3/main2.js | 226 ++++++------ application3/particle.js | 94 ++--- application3/utils.js | 32 +- application3/vector.js | 164 ++++----- application4/index.html | 44 +-- application4/main.js | 262 +++++++------- application4/particle.js | 116 +++--- application4/utils.js | 144 ++++---- application4/vector.js | 164 ++++----- episode1/index.html | 38 +- episode1/main.js | 24 +- episode10/animation_template.js | 32 +- episode10/main.js | 224 ++++++------ episode10/particle.js | 40 +-- episode10/ship1.js | 174 ++++----- episode10/ship2.js | 198 +++++------ episode10/vector.js | 164 ++++----- episode11/animation_template.js | 32 +- episode11/index.html | 42 +-- episode11/main.js | 66 ++-- episode11/orbit.js | 66 ++-- episode11/particle.js | 82 ++--- episode11/vector.js | 164 ++++----- episode12/bounce.js | 80 ++--- episode12/index.html | 42 +-- episode12/particle.js | 92 ++--- episode12/regen.js | 80 ++--- episode12/regen_extra.js | 82 ++--- episode12/removal.js | 100 +++--- episode12/vector.js | 164 ++++----- episode12/wrapping.js | 74 ++-- episode13/friction1.js | 64 ++-- episode13/friction2.js | 50 +-- episode13/index.html | 42 +-- episode13/particle.js | 96 ++--- episode13/ship2.js | 202 +++++------ episode13/vector.js | 164 ++++----- episode14/circle-circle.js | 84 ++--- episode14/circle-point.js | 58 +-- episode14/index.html | 44 +-- episode14/main.js | 16 +- episode14/particle.js | 96 ++--- episode14/rect-point.js | 46 +-- episode14/rect-rect.js | 70 ++-- episode14/utils.js | 112 +++--- episode14/vector.js | 164 ++++----- episode15/index.html | 44 +-- episode15/particle.js | 96 ++--- episode15/spring1.js | 98 +++--- episode15/utils.js | 112 +++--- episode15/vector.js | 164 ++++----- episode16/index.html | 44 +-- episode16/particle.js | 96 ++--- episode16/spring1.js | 102 +++--- episode16/spring2.js | 180 +++++----- episode16/utils.js | 144 ++++---- episode16/vector.js | 164 ++++----- episode17/index.html | 44 +-- episode17/orbit.js | 66 ++-- episode17/particle.js | 114 +++--- episode17/spring1.js | 116 +++--- episode17/utils.js | 144 ++++---- episode17/vector.js | 164 ++++----- episode18/index.html | 44 +-- episode18/main.js | 262 +++++++------- episode18/multigravity.js | 124 +++---- episode18/particle.js | 274 +++++++-------- episode18/spring1.js | 110 +++--- episode18/utils.js | 144 ++++---- episode18/vector.js | 164 ++++----- episode19/demo1.js | 146 ++++---- episode19/demo2.js | 190 +++++----- episode19/demo3.js | 210 +++++------ episode19/demo4.js | 248 ++++++------- episode19/demo5.js | 258 +++++++------- episode19/demo6.js | 358 +++++++++---------- episode19/index.html | 40 +-- episode19/main1.js | 104 +++--- episode19/main2.js | 86 ++--- episode19/main3.js | 96 ++--- episode19/utils.js | 210 +++++------ episode2/index.html | 34 +- episode2/trig01.js | 40 +-- episode20/index.html | 40 +-- episode20/main1.js | 90 ++--- episode20/main2.js | 70 ++-- episode20/main3.js | 64 ++-- episode20/utils.js | 244 ++++++------- episode21/index.html | 52 +-- episode21/main.js | 90 ++--- episode21/particle.js | 274 +++++++-------- episode21/utils.js | 244 ++++++------- episode22/index.html | 44 +-- episode22/main.js | 42 +-- episode22/main2.js | 118 +++---- episode22/particle.js | 274 +++++++-------- episode22/postcards.js | 94 ++--- episode22/stars.js | 38 +- episode22/utils.js | 244 ++++++------- episode23/final.js | 134 +++---- episode23/index.html | 46 +-- episode23/particle.js | 274 +++++++-------- episode23/postcards.js | 120 +++---- episode23/spiral.js | 124 +++---- episode23/stars.js | 126 +++---- episode23/utils.js | 244 ++++++------- episode24/index.html | 46 +-- episode24/particle.js | 274 +++++++-------- episode24/spiral.js | 124 +++---- episode24/utils.js | 244 ++++++------- episode25/index.html | 38 +- episode25/main.js | 192 +++++----- episode26/2d.js | 64 ++-- episode26/index.html | 38 +- episode26/main.js | 310 ++++++++-------- episode27/index.html | 44 +-- episode27/main.js | 90 ++--- episode28/click.js | 116 +++--- episode28/index.html | 46 +-- episode28/main.js | 108 +++--- episode28/steering.js | 74 ++-- episode28/string.js | 112 +++--- episode28/utils.js | 244 ++++++------- episode29/index.html | 44 +-- episode29/main.js | 154 ++++---- episode29/penner_easing.as | 564 +++++++++++++++--------------- episode29/utils.js | 244 ++++++------- episode3/index.html | 34 +- episode3/trig02.js | 58 +-- episode30/index.html | 44 +-- episode30/tweenBasic.js | 140 ++++---- episode30/tweenFull.js | 168 ++++----- episode30/tweenx.js | 136 +++---- episode32/index.html | 44 +-- episode32/main.js | 108 +++--- episode32/main_interactive.js | 214 ++++++------ episode33/index.html | 44 +-- episode33/main_interactive.js | 288 +++++++-------- episode33/parallel.js | 116 +++--- episode34/index.html | 44 +-- episode34/particles.js | 214 ++++++------ episode34/shapes.js | 296 ++++++++-------- episode35/index.html | 44 +-- episode35/koch.js | 122 +++---- episode35/kochanimated.js | 154 ++++---- episode35/sierpinski.js | 110 +++--- episode35/twist.js | 140 ++++---- episode36/index.html | 44 +-- episode36/main.js | 138 ++++---- episode38/cat.jpg | Bin 0 -> 46674 bytes episode38/image.js | 230 ++++++++++++ episode38/index.html | 23 ++ episode38/main.js | 227 ++++++++++++ episode38/ragdoll.js | 262 ++++++++++++++ episode4/bees.js | 104 +++--- episode4/circle.js | 48 +-- episode4/code.js | 46 +-- episode4/index.html | 34 +- episode5/arctangent.js | 86 ++--- episode5/index.html | 34 +- episode7/vector.js | 164 ++++----- episode8/index.html | 42 +-- episode8/main.js | 54 +-- episode8/particle.js | 32 +- episode8/vector.js | 164 ++++----- episode9/fireworks.js | 56 +-- episode9/index.html | 42 +-- episode9/main.js | 46 +-- episode9/particle.js | 46 +-- episode9/vector.js | 164 ++++----- mini1/index.html | 38 +- mini1/main.js | 82 ++--- mini10/circle.js | 54 +-- mini10/index.html | 42 +-- mini10/main.js | 36 +- mini10/main2.js | 54 +-- mini10/particle.js | 274 +++++++-------- mini10/utils.js | 210 +++++------ mini11/bezier.js | 178 +++++----- mini11/index.html | 40 +-- mini11/main.js | 88 ++--- mini11/utils.js | 210 +++++------ mini2/index.html | 38 +- mini2/main.js | 82 ++--- mini3/index.html | 38 +- mini3/main.js | 58 +-- mini4/index.html | 38 +- mini4/main.js | 60 ++-- mini6/index.html | 38 +- mini6/main.js | 58 +-- mini7/index.html | 40 +-- mini7/main.js | 40 +-- mini7/utils.js | 128 +++---- mini8/index.html | 40 +-- mini8/main.js | 70 ++-- mini8/test1.js | 12 +- mini8/test2.js | 12 +- mini8/utils.js | 146 ++++---- mini9/highres.js | 88 ++--- mini9/index.html | 40 +-- mini9/main.js | 68 ++-- mini9/main2.js | 74 ++-- mini9/main3.js | 26 +- mini9/utils.js | 162 ++++----- 218 files changed, 12586 insertions(+), 11844 deletions(-) create mode 100644 episode38/cat.jpg create mode 100644 episode38/image.js create mode 100644 episode38/index.html create mode 100644 episode38/main.js create mode 100644 episode38/ragdoll.js diff --git a/README.md b/README.md index 645b2ba..9c13536 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -CodingMath -========== - -This repo will house any applicable files from the Coding Math videos. - -Site: http://codingmath.com - -YouTube: http://www.youtube.com/user/codingmath - -Support: http://www.patreon.com/codingmath +CodingMath +========== + +This repo will house any applicable files from the Coding Math videos. + +Site: http://codingmath.com + +YouTube: http://www.youtube.com/user/codingmath + +Support: http://www.patreon.com/codingmath diff --git a/application1/index.html b/application1/index.html index e8000db..8b3dc92 100644 --- a/application1/index.html +++ b/application1/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/application1/main.js b/application1/main.js index b539abc..543d16e 100644 --- a/application1/main.js +++ b/application1/main.js @@ -1,51 +1,51 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }; - - draw(); - - document.body.addEventListener("mousedown", onMouseDown); - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - draw(); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }; + + draw(); + + document.body.addEventListener("mousedown", onMouseDown); + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + draw(); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + } + }; \ No newline at end of file diff --git a/application1/particle.js b/application1/particle.js index 5580676..ca34379 100644 --- a/application1/particle.js +++ b/application1/particle.js @@ -1,48 +1,48 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/application1/utils.js b/application1/utils.js index 28df0b6..fc95532 100644 --- a/application1/utils.js +++ b/application1/utils.js @@ -1,17 +1,17 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return lerp(norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, min), max); - } +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return lerp(norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, min), max); + } } \ No newline at end of file diff --git a/application1/vector.js b/application1/vector.js index 609f6d5..4d66796 100644 --- a/application1/vector.js +++ b/application1/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/application2/index.html b/application2/index.html index e892cce..f55c3a4 100644 --- a/application2/index.html +++ b/application2/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/application2/main.js b/application2/main.js index a9db1d6..20879e0 100644 --- a/application2/main.js +++ b/application2/main.js @@ -1,97 +1,97 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }, - cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), - canShoot = true; - - cannonball.radius = 7; - - draw(); - - document.body.addEventListener("mousedown", onMouseDown); - - document.body.addEventListener("keyup", function(event) { - switch(event.keyCode) { - case 32: // space - if(canShoot) { - shoot(); - } - break; - - default: - break; - } - }); - - function shoot() { - cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); - cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); - cannonball.velocity.setLength(15); - cannonball.velocity.setAngle(gun.angle); - - canShoot = false; - update(); - } - - function update() { - cannonball.update(); - draw(); - - if(cannonball.position.getY() > height) { - canShoot = true; - } - else { - requestAnimationFrame(update); - } - } - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - draw(); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - - context.beginPath(); - context.arc(cannonball.position.getX(), - cannonball.position.getY(), - cannonball.radius, - 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }, + cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), + canShoot = true; + + cannonball.radius = 7; + + draw(); + + document.body.addEventListener("mousedown", onMouseDown); + + document.body.addEventListener("keyup", function(event) { + switch(event.keyCode) { + case 32: // space + if(canShoot) { + shoot(); + } + break; + + default: + break; + } + }); + + function shoot() { + cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); + cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); + cannonball.velocity.setLength(15); + cannonball.velocity.setAngle(gun.angle); + + canShoot = false; + update(); + } + + function update() { + cannonball.update(); + draw(); + + if(cannonball.position.getY() > height) { + canShoot = true; + } + else { + requestAnimationFrame(update); + } + } + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + draw(); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + + context.beginPath(); + context.arc(cannonball.position.getX(), + cannonball.position.getY(), + cannonball.radius, + 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/application2/particle.js b/application2/particle.js index 5580676..ca34379 100644 --- a/application2/particle.js +++ b/application2/particle.js @@ -1,48 +1,48 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/application2/utils.js b/application2/utils.js index a34cfec..0d6fd7b 100644 --- a/application2/utils.js +++ b/application2/utils.js @@ -1,17 +1,17 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, min), max); - } +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, min), max); + } } \ No newline at end of file diff --git a/application2/vector.js b/application2/vector.js index 609f6d5..4d66796 100644 --- a/application2/vector.js +++ b/application2/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/application3/code.sublime-project b/application3/code.sublime-project index 2862388..be2f241 100644 --- a/application3/code.sublime-project +++ b/application3/code.sublime-project @@ -1,8 +1,8 @@ -{ - "folders": - [ - { - "path": "." - } - ] +{ + "folders": + [ + { + "path": "." + } + ] } \ No newline at end of file diff --git a/application3/index.html b/application3/index.html index e8000db..8b3dc92 100644 --- a/application3/index.html +++ b/application3/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/application3/main.js b/application3/main.js index 6b8af4d..55d7893 100644 --- a/application3/main.js +++ b/application3/main.js @@ -1,110 +1,110 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }, - cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), - isShooting = false, - forceAngle = 0, - forceSpeed = 0.1, - rawForce = 0; - - cannonball.radius = 7; - - update (); - - document.body.addEventListener("mousedown", onMouseDown); - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 32: // space - if(!isShooting) { - shoot(); - } - break; - - default: - break; - } - }); - - function shoot() { - cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); - cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); - cannonball.velocity.setLength(utils.map(rawForce, -1, 1, 2, 20)); - cannonball.velocity.setAngle(gun.angle); - - isShooting = true; - } - - function update() { - if(!isShooting) { - forceAngle += forceSpeed; - } - rawForce = Math.sin(forceAngle); - if(isShooting) { - cannonball.update(); - } - draw(); - - if(cannonball.position.getY() > height) { - isShooting = false; - } - requestAnimationFrame(update); - } - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.fillStyle = "#ccc"; - context.fillRect(10, height - 10, 20, -100); - - context.fillStyle = "#666"; - context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); - - context.fillStyle = "#000"; - - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - - context.beginPath(); - context.arc(cannonball.position.getX(), - cannonball.position.getY(), - cannonball.radius, - 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }, + cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), + isShooting = false, + forceAngle = 0, + forceSpeed = 0.1, + rawForce = 0; + + cannonball.radius = 7; + + update (); + + document.body.addEventListener("mousedown", onMouseDown); + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 32: // space + if(!isShooting) { + shoot(); + } + break; + + default: + break; + } + }); + + function shoot() { + cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); + cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); + cannonball.velocity.setLength(utils.map(rawForce, -1, 1, 2, 20)); + cannonball.velocity.setAngle(gun.angle); + + isShooting = true; + } + + function update() { + if(!isShooting) { + forceAngle += forceSpeed; + } + rawForce = Math.sin(forceAngle); + if(isShooting) { + cannonball.update(); + } + draw(); + + if(cannonball.position.getY() > height) { + isShooting = false; + } + requestAnimationFrame(update); + } + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.fillStyle = "#ccc"; + context.fillRect(10, height - 10, 20, -100); + + context.fillStyle = "#666"; + context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); + + context.fillStyle = "#000"; + + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + + context.beginPath(); + context.arc(cannonball.position.getX(), + cannonball.position.getY(), + cannonball.radius, + 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/application3/main2.js b/application3/main2.js index 5bb68ed..21a291f 100644 --- a/application3/main2.js +++ b/application3/main2.js @@ -1,114 +1,114 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }, - cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), - isShooting = false, - forceAngle = 0, - forceSpeed = 0.1, - rawForce = 0; - - cannonball.radius = 7; - - update(); - - document.body.addEventListener("mousedown", onMouseDown); - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 32: // space - if(!isShooting) { - shoot(); - } - break; - - default: - break; - } - }); - - function shoot() { - cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); - cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); - cannonball.velocity.setLength(utils.map(rawForce, -1, 1, 2, 20)); - cannonball.velocity.setAngle(gun.angle); - - isShooting = true; - } - - function update() { - if(isShooting) { - cannonball.update(); - } - else { - forceAngle += forceSpeed; - rawForce = Math.sin(forceAngle); - } - draw(); - - if(cannonball.position.getY() > height) { - isShooting = false; - } - requestAnimationFrame(update); - } - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - draw(); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.fillStyle = "#ccc"; - context.beginPath(); - context.rect(10, height - 10, 20, -100); - context.fill(); - - context.fillStyle = "#666"; - context.beginPath(); - context.rect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); - context.fill(); - - context.fillStyle = "#000"; - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - - context.beginPath(); - context.arc(cannonball.position.getX(), - cannonball.position.getY(), - cannonball.radius, - 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }, + cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), + isShooting = false, + forceAngle = 0, + forceSpeed = 0.1, + rawForce = 0; + + cannonball.radius = 7; + + update(); + + document.body.addEventListener("mousedown", onMouseDown); + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 32: // space + if(!isShooting) { + shoot(); + } + break; + + default: + break; + } + }); + + function shoot() { + cannonball.position.setX(gun.x + Math.cos(gun.angle) * 40); + cannonball.position.setY(gun.y + Math.sin(gun.angle) * 40); + cannonball.velocity.setLength(utils.map(rawForce, -1, 1, 2, 20)); + cannonball.velocity.setAngle(gun.angle); + + isShooting = true; + } + + function update() { + if(isShooting) { + cannonball.update(); + } + else { + forceAngle += forceSpeed; + rawForce = Math.sin(forceAngle); + } + draw(); + + if(cannonball.position.getY() > height) { + isShooting = false; + } + requestAnimationFrame(update); + } + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + draw(); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.fillStyle = "#ccc"; + context.beginPath(); + context.rect(10, height - 10, 20, -100); + context.fill(); + + context.fillStyle = "#666"; + context.beginPath(); + context.rect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); + context.fill(); + + context.fillStyle = "#000"; + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + + context.beginPath(); + context.arc(cannonball.position.getX(), + cannonball.position.getY(), + cannonball.radius, + 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/application3/particle.js b/application3/particle.js index 5580676..ca34379 100644 --- a/application3/particle.js +++ b/application3/particle.js @@ -1,48 +1,48 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/application3/utils.js b/application3/utils.js index a34cfec..0d6fd7b 100644 --- a/application3/utils.js +++ b/application3/utils.js @@ -1,17 +1,17 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, min), max); - } +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, min), max); + } } \ No newline at end of file diff --git a/application3/vector.js b/application3/vector.js index 609f6d5..4d66796 100644 --- a/application3/vector.js +++ b/application3/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/application4/index.html b/application4/index.html index e8000db..8b3dc92 100644 --- a/application4/index.html +++ b/application4/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/application4/main.js b/application4/main.js index bfcad3d..dd0c680 100644 --- a/application4/main.js +++ b/application4/main.js @@ -1,132 +1,132 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }, - cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), - isShooting = false, - forceAngle = 0, - forceSpeed = 0.1, - rawForce = 0, - target = {}; - - cannonball.radius = 7; - - setTarget(); - update (); - - function setTarget() { - target.x = utils.randomRange(200, width); - target.y = height; - target.radius = utils.randomRange(10, 40); - } - - document.body.addEventListener("mousedown", onMouseDown); - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 32: // space - if(!isShooting) { - shoot(); - } - break; - - default: - break; - } - }); - - function shoot() { - var force = utils.map(rawForce, -1, 1, 2, 20); - cannonball.x = gun.x + Math.cos(gun.angle) * 40; - cannonball.y = gun.y + Math.sin(gun.angle) * 40; - cannonball.vx = Math.cos(gun.angle) * force; - cannonball.vy = Math.sin(gun.angle) * force; - - isShooting = true; - } - - function update() { - if(!isShooting) { - forceAngle += forceSpeed; - } - rawForce = Math.sin(forceAngle); - if(isShooting) { - cannonball.update(); - checkTarget(); - } - draw(); - - if(cannonball.y > height) { - isShooting = false; - } - requestAnimationFrame(update); - } - - function checkTarget() { - if(utils.circleCollision(target, cannonball)) { - // create amazing collision reaction!!! - setTarget(); - } - } - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.fillStyle = "#ccc"; - context.fillRect(10, height - 10, 20, -100); - - context.fillStyle = "#666"; - context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); - - context.fillStyle = "#000"; - - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - - context.beginPath(); - context.arc(cannonball.x, - cannonball.y, - cannonball.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "red"; - context.beginPath(); - context.arc(target.x, target.y, target.radius, 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }, + cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), + isShooting = false, + forceAngle = 0, + forceSpeed = 0.1, + rawForce = 0, + target = {}; + + cannonball.radius = 7; + + setTarget(); + update (); + + function setTarget() { + target.x = utils.randomRange(200, width); + target.y = height; + target.radius = utils.randomRange(10, 40); + } + + document.body.addEventListener("mousedown", onMouseDown); + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 32: // space + if(!isShooting) { + shoot(); + } + break; + + default: + break; + } + }); + + function shoot() { + var force = utils.map(rawForce, -1, 1, 2, 20); + cannonball.x = gun.x + Math.cos(gun.angle) * 40; + cannonball.y = gun.y + Math.sin(gun.angle) * 40; + cannonball.vx = Math.cos(gun.angle) * force; + cannonball.vy = Math.sin(gun.angle) * force; + + isShooting = true; + } + + function update() { + if(!isShooting) { + forceAngle += forceSpeed; + } + rawForce = Math.sin(forceAngle); + if(isShooting) { + cannonball.update(); + checkTarget(); + } + draw(); + + if(cannonball.y > height) { + isShooting = false; + } + requestAnimationFrame(update); + } + + function checkTarget() { + if(utils.circleCollision(target, cannonball)) { + // create amazing collision reaction!!! + setTarget(); + } + } + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.fillStyle = "#ccc"; + context.fillRect(10, height - 10, 20, -100); + + context.fillStyle = "#666"; + context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); + + context.fillStyle = "#000"; + + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + + context.beginPath(); + context.arc(cannonball.x, + cannonball.y, + cannonball.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "red"; + context.beginPath(); + context.arc(target.x, target.y, target.radius, 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/application4/particle.js b/application4/particle.js index 7e15dc5..03706a6 100644 --- a/application4/particle.js +++ b/application4/particle.js @@ -1,59 +1,59 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - console.log("x: ", x); - var obj = Object.create(this); - this.x = x; - this.y = y; - this.vx = Math.cos(direction) * speed; - this.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - return obj; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = this.x - p2.x, - dy = this.y - p2.y, - distSQ = dx * dx + dy * dy, - distance = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / distance * force, - ay = dy / distance * force; - - this.vx += ax; - this.vy += ay; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + console.log("x: ", x); + var obj = Object.create(this); + this.x = x; + this.y = y; + this.vx = Math.cos(direction) * speed; + this.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + return obj; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = this.x - p2.x, + dy = this.y - p2.y, + distSQ = dx * dx + dy * dy, + distance = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / distance * force, + ay = dy / distance * force; + + this.vx += ax; + this.vy += ay; + } }; \ No newline at end of file diff --git a/application4/utils.js b/application4/utils.js index 37ae5ef..9728633 100644 --- a/application4/utils.js +++ b/application4/utils.js @@ -1,73 +1,73 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + } + } \ No newline at end of file diff --git a/application4/vector.js b/application4/vector.js index 609f6d5..4d66796 100644 --- a/application4/vector.js +++ b/application4/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode1/index.html b/episode1/index.html index 719fb94..dfde07f 100644 --- a/episode1/index.html +++ b/episode1/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode1/main.js b/episode1/main.js index 5e6c4da..98a2a2e 100644 --- a/episode1/main.js +++ b/episode1/main.js @@ -1,13 +1,13 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - for(var i = 0; i < 100; i += 1) { - context.beginPath(); - context.moveTo(Math.random() * width, Math.random() * height); - context.lineTo(Math.random() * width, Math.random() * height); - context.stroke(); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + for(var i = 0; i < 100; i += 1) { + context.beginPath(); + context.moveTo(Math.random() * width, Math.random() * height); + context.lineTo(Math.random() * width, Math.random() * height); + context.stroke(); + } }; \ No newline at end of file diff --git a/episode10/animation_template.js b/episode10/animation_template.js index e557225..916d3d5 100644 --- a/episode10/animation_template.js +++ b/episode10/animation_template.js @@ -1,17 +1,17 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - update(); - - - function update() { - context.clearRect(0, 0, width, height); - - // animation goes here - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + update(); + + + function update() { + context.clearRect(0, 0, width, height); + + // animation goes here + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode10/main.js b/episode10/main.js index 25d329d..f465dfd 100644 --- a/episode10/main.js +++ b/episode10/main.js @@ -1,113 +1,113 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - ship = particle.create(width / 2, height / 2, 0, 0), - thrust = vector.create(0, 0), - angle = 0, - turningLeft = false, - turningRight = false, - thrusting = false; - - update(); - - - document.body.addEventListener("keydown", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = true; - break; - - case 37: // left - turningLeft = true; - break; - - case 39: // right - turningRight = true; - break; - - default: - break; - - } - }); - - document.body.addEventListener("keyup", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = false; - break; - - case 37: // left - turningLeft = false; - break; - - case 39: // right - turningRight = false; - break; - - default: - break; - - } - }); - - function update() { - context.clearRect(0, 0, width, height); - - if(turningLeft) { - angle -= 0.05; - } - if(turningRight) { - angle += 0.05; - } - - thrust.setAngle(angle); - - if(thrusting) { - thrust.setLength(0.1); - } - else { - thrust.setLength(0); - } - - // animation goes here - ship.accelerate(thrust); - ship.update(); - - context.save(); - context.translate(ship.position.getX(), ship.position.getY()); - context.rotate(angle); - - context.beginPath(); - context.moveTo(10, 0); - context.lineTo(-10, -7); - context.lineTo(-10, 7); - context.lineTo(10, 0); - if(thrusting) { - context.moveTo(-10, 0); - context.lineTo(-18, 0); - } - context.stroke(); - - context.restore(); - - if(ship.position.getX() > width) { - ship.position.setX(0); - } - if(ship.position.getX() < 0) { - ship.position.setX(width); - } - if(ship.position.getY() > height) { - ship.position.setY(0); - } - if(ship.position.getY() < 0) { - ship.position.setY(height); - } - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + ship = particle.create(width / 2, height / 2, 0, 0), + thrust = vector.create(0, 0), + angle = 0, + turningLeft = false, + turningRight = false, + thrusting = false; + + update(); + + + document.body.addEventListener("keydown", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = true; + break; + + case 37: // left + turningLeft = true; + break; + + case 39: // right + turningRight = true; + break; + + default: + break; + + } + }); + + document.body.addEventListener("keyup", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = false; + break; + + case 37: // left + turningLeft = false; + break; + + case 39: // right + turningRight = false; + break; + + default: + break; + + } + }); + + function update() { + context.clearRect(0, 0, width, height); + + if(turningLeft) { + angle -= 0.05; + } + if(turningRight) { + angle += 0.05; + } + + thrust.setAngle(angle); + + if(thrusting) { + thrust.setLength(0.1); + } + else { + thrust.setLength(0); + } + + // animation goes here + ship.accelerate(thrust); + ship.update(); + + context.save(); + context.translate(ship.position.getX(), ship.position.getY()); + context.rotate(angle); + + context.beginPath(); + context.moveTo(10, 0); + context.lineTo(-10, -7); + context.lineTo(-10, 7); + context.lineTo(10, 0); + if(thrusting) { + context.moveTo(-10, 0); + context.lineTo(-18, 0); + } + context.stroke(); + + context.restore(); + + if(ship.position.getX() > width) { + ship.position.setX(0); + } + if(ship.position.getX() < 0) { + ship.position.setX(width); + } + if(ship.position.getY() > height) { + ship.position.setY(0); + } + if(ship.position.getY() < 0) { + ship.position.setY(height); + } + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode10/particle.js b/episode10/particle.js index ea5eb1e..8d9d391 100644 --- a/episode10/particle.js +++ b/episode10/particle.js @@ -1,21 +1,21 @@ -var particle = { - position: null, - velocity: null, - - create: function(x, y, speed, direction) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.position.addTo(this.velocity); - } +var particle = { + position: null, + velocity: null, + + create: function(x, y, speed, direction) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.position.addTo(this.velocity); + } }; \ No newline at end of file diff --git a/episode10/ship1.js b/episode10/ship1.js index 74c765c..0470e1e 100644 --- a/episode10/ship1.js +++ b/episode10/ship1.js @@ -1,88 +1,88 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - ship = particle.create(width / 2, height / 2, 0, 0), - thrust = vector.create(0, 0); - - update(); - - - document.body.addEventListener("keydown", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrust.setY(-0.1); - break; - - case 40: // down - thrust.setY(0.1); - break; - - case 37: // left - thrust.setX(-0.1); - break; - - case 39: // right - thrust.setX(0.1); - break; - - default: - break; - - } - }); - - document.body.addEventListener("keyup", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrust.setY(0); - break; - - case 40: // down - thrust.setY(0); - break; - - case 37: // left - thrust.setX(0); - break; - - case 39: // right - thrust.setX(0); - break; - - default: - break; - - } - }); - - function update() { - context.clearRect(0, 0, width, height); - - // animation goes here - ship.accelerate(thrust); - ship.update(); - - context.beginPath(); - context.arc(ship.position.getX(), ship.position.getY(), 10, 0, Math.PI * 2, false); - context.fill(); - - if(ship.position.getX() > width) { - ship.position.setX(0); - } - if(ship.position.getX() < 0) { - ship.position.setX(width); - } - if(ship.position.getY() > height) { - ship.position.setY(0); - } - if(ship.position.getY() < 0) { - ship.position.setY(height); - } - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + ship = particle.create(width / 2, height / 2, 0, 0), + thrust = vector.create(0, 0); + + update(); + + + document.body.addEventListener("keydown", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrust.setY(-0.1); + break; + + case 40: // down + thrust.setY(0.1); + break; + + case 37: // left + thrust.setX(-0.1); + break; + + case 39: // right + thrust.setX(0.1); + break; + + default: + break; + + } + }); + + document.body.addEventListener("keyup", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrust.setY(0); + break; + + case 40: // down + thrust.setY(0); + break; + + case 37: // left + thrust.setX(0); + break; + + case 39: // right + thrust.setX(0); + break; + + default: + break; + + } + }); + + function update() { + context.clearRect(0, 0, width, height); + + // animation goes here + ship.accelerate(thrust); + ship.update(); + + context.beginPath(); + context.arc(ship.position.getX(), ship.position.getY(), 10, 0, Math.PI * 2, false); + context.fill(); + + if(ship.position.getX() > width) { + ship.position.setX(0); + } + if(ship.position.getX() < 0) { + ship.position.setX(width); + } + if(ship.position.getY() > height) { + ship.position.setY(0); + } + if(ship.position.getY() < 0) { + ship.position.setY(height); + } + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode10/ship2.js b/episode10/ship2.js index ea137b9..90cb4d3 100644 --- a/episode10/ship2.js +++ b/episode10/ship2.js @@ -1,100 +1,100 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight - ship = particle.create(width / 2, height / 2, 0, 0), - thrust = vector.create(0, 0), - angle = 0, - turningLeft = false, - turningRight = false, - thrusting = false; - - document.body.addEventListener("keydown", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = true; - break; - case 37: // left - turningLeft = true; - break; - case 39: // right - turningRight = true; - default: - break - } - }); - - document.body.addEventListener("keyup", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = false; - break; - case 37: // left - turningLeft = false; - break; - case 39: // right - turningRight = false; - default: - break - } - }); - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - if(turningRight) { - angle += .05; - } - if(turningLeft) { - angle -= .05; - } - - if(thrusting) { - thrust.setLength(.1); - } - else { - thrust.setLength(0); - } - thrust.setAngle(angle); - - ship.accelerate(thrust); - ship.update(); - - if(ship.position.getX() > width) { - ship.position.setX(0); - } - if(ship.position.getX() < 0) { - ship.position.setX(width); - } - if(ship.position.getY() > height) { - ship.position.setY(0); - } - if(ship.position.getY() < 0) { - ship.position.setY(height); - } - - context.save(); - - context.translate(ship.position.getX(), ship.position.getY()); - context.rotate(angle); - context.beginPath(); - context.moveTo(10, 0); - context.lineTo(-10, -7); - context.lineTo(-10, 7 ); - context.lineTo(10, 0); - if(thrusting) { - context.moveTo(-10, 0); - context.lineTo(-18, 0); - } - context.stroke(); - - context.restore(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight + ship = particle.create(width / 2, height / 2, 0, 0), + thrust = vector.create(0, 0), + angle = 0, + turningLeft = false, + turningRight = false, + thrusting = false; + + document.body.addEventListener("keydown", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = true; + break; + case 37: // left + turningLeft = true; + break; + case 39: // right + turningRight = true; + default: + break + } + }); + + document.body.addEventListener("keyup", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = false; + break; + case 37: // left + turningLeft = false; + break; + case 39: // right + turningRight = false; + default: + break + } + }); + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + if(turningRight) { + angle += .05; + } + if(turningLeft) { + angle -= .05; + } + + if(thrusting) { + thrust.setLength(.1); + } + else { + thrust.setLength(0); + } + thrust.setAngle(angle); + + ship.accelerate(thrust); + ship.update(); + + if(ship.position.getX() > width) { + ship.position.setX(0); + } + if(ship.position.getX() < 0) { + ship.position.setX(width); + } + if(ship.position.getY() > height) { + ship.position.setY(0); + } + if(ship.position.getY() < 0) { + ship.position.setY(height); + } + + context.save(); + + context.translate(ship.position.getX(), ship.position.getY()); + context.rotate(angle); + context.beginPath(); + context.moveTo(10, 0); + context.lineTo(-10, -7); + context.lineTo(-10, 7 ); + context.lineTo(10, 0); + if(thrusting) { + context.moveTo(-10, 0); + context.lineTo(-18, 0); + } + context.stroke(); + + context.restore(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode10/vector.js b/episode10/vector.js index 609f6d5..4d66796 100644 --- a/episode10/vector.js +++ b/episode10/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode11/animation_template.js b/episode11/animation_template.js index e557225..916d3d5 100644 --- a/episode11/animation_template.js +++ b/episode11/animation_template.js @@ -1,17 +1,17 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - update(); - - - function update() { - context.clearRect(0, 0, width, height); - - // animation goes here - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + update(); + + + function update() { + context.clearRect(0, 0, width, height); + + // animation goes here + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode11/index.html b/episode11/index.html index f6702d7..532a094 100644 --- a/episode11/index.html +++ b/episode11/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode11/main.js b/episode11/main.js index 213c791..b1a6483 100644 --- a/episode11/main.js +++ b/episode11/main.js @@ -1,34 +1,34 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - sun = particle.create(width / 2, height / 2, 0, 0), - planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); - - sun.mass = 100000; - - update(); - - - function update() { - context.clearRect(0, 0, width, height); - - planet.gravitateTo(sun); - planet.update(); - - context.beginPath(); - context.fillStyle = "#ffff00"; - context.arc(sun.position.getX(), sun.position.getY(), 20, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.fillStyle = "#0000ff"; - context.arc(planet.position.getX(), planet.position.getY(), 5, 0, Math.PI * 2, false); - context.fill(); - - // animation goes here - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + sun = particle.create(width / 2, height / 2, 0, 0), + planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); + + sun.mass = 100000; + + update(); + + + function update() { + context.clearRect(0, 0, width, height); + + planet.gravitateTo(sun); + planet.update(); + + context.beginPath(); + context.fillStyle = "#ffff00"; + context.arc(sun.position.getX(), sun.position.getY(), 20, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.fillStyle = "#0000ff"; + context.arc(planet.position.getX(), planet.position.getY(), 5, 0, Math.PI * 2, false); + context.fill(); + + // animation goes here + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode11/orbit.js b/episode11/orbit.js index 3a0b3b8..d4fa70f 100644 --- a/episode11/orbit.js +++ b/episode11/orbit.js @@ -1,34 +1,34 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - sun = particle.create(width / 2, height / 2, 0, 0); - planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); - - sun.mass = 20000; - - update(); - - - function update() { - context.clearRect(0, 0, width, height); - - // animation goes here - - planet.gravitateTo(sun); - planet.update(); - - context.beginPath(); - context.fillStyle = "#ffff00"; - context.arc(sun.position.getX(), sun.position.getY(), 20, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.fillStyle = "#0000ff"; - context.arc(planet.position.getX(), planet.position.getY(), 4, 0, Math.PI * 2, false); - context.fill(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + sun = particle.create(width / 2, height / 2, 0, 0); + planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); + + sun.mass = 20000; + + update(); + + + function update() { + context.clearRect(0, 0, width, height); + + // animation goes here + + planet.gravitateTo(sun); + planet.update(); + + context.beginPath(); + context.fillStyle = "#ffff00"; + context.arc(sun.position.getX(), sun.position.getY(), 20, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.fillStyle = "#0000ff"; + context.arc(planet.position.getX(), planet.position.getY(), 4, 0, Math.PI * 2, false); + context.fill(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode11/particle.js b/episode11/particle.js index 5959aeb..af3e0a2 100644 --- a/episode11/particle.js +++ b/episode11/particle.js @@ -1,42 +1,42 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - - create: function(x, y, speed, direction) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + + create: function(x, y, speed, direction) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode11/vector.js b/episode11/vector.js index 609f6d5..4d66796 100644 --- a/episode11/vector.js +++ b/episode11/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode12/bounce.js b/episode12/bounce.js index 8151aeb..dc376ce 100644 --- a/episode12/bounce.js +++ b/episode12/bounce.js @@ -1,41 +1,41 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p = particle.create(width / 2, height / 2, 5, Math.random() * Math.PI * 2, 0.1); - - p.radius = 40; - p.bounce = -0.9; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - if(p.position.getX() + p.radius > width) { - p.position.setX(width - p.radius); - p.velocity.setX(p.velocity.getX() * p.bounce); - } - if(p.position.getX() - p.radius < 0) { - p.position.setX(p.radius); - p.velocity.setX(p.velocity.getX() * p.bounce); - } - if(p.position.getY() + p.radius > height) { - p.position.setY(height - p.radius); - p.velocity.setY(p.velocity.getY() * p.bounce); - } - if(p.position.getY() - p.radius < 0) { - p.position.setY(p.radius); - p.velocity.setY(p.velocity.getY() * p.bounce); - } - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p = particle.create(width / 2, height / 2, 5, Math.random() * Math.PI * 2, 0.1); + + p.radius = 40; + p.bounce = -0.9; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + if(p.position.getX() + p.radius > width) { + p.position.setX(width - p.radius); + p.velocity.setX(p.velocity.getX() * p.bounce); + } + if(p.position.getX() - p.radius < 0) { + p.position.setX(p.radius); + p.velocity.setX(p.velocity.getX() * p.bounce); + } + if(p.position.getY() + p.radius > height) { + p.position.setY(height - p.radius); + p.velocity.setY(p.velocity.getY() * p.bounce); + } + if(p.position.getY() - p.radius < 0) { + p.position.setY(p.radius); + p.velocity.setY(p.velocity.getY() * p.bounce); + } + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode12/index.html b/episode12/index.html index 4618452..b7716e8 100644 --- a/episode12/index.html +++ b/episode12/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode12/particle.js b/episode12/particle.js index 4139869..fe49a65 100644 --- a/episode12/particle.js +++ b/episode12/particle.js @@ -1,47 +1,47 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode12/regen.js b/episode12/regen.js index 1951134..c6fb0ad 100644 --- a/episode12/regen.js +++ b/episode12/regen.js @@ -1,41 +1,41 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = []; - - for(var i = 0; i < 100; i += 1) { - var p = particle.create(width / 2, height, Math.random() * 8 + 5, -Math.PI / 2 + (Math.random() * .2 - .1), 0.1); - p.radius = Math.random() * 10 + 2; - particles.push(p); - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - - for(var i = 0; i < 100; i += 1) { - var p = particles[i]; - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - if(p.position.getY() - p.radius > height) { - p.position.setX(width / 2); - p.position.setY(height); - p.velocity.setLength(Math.random() * 8 + 5); - p.velocity.setAngle(-Math.PI / 2 + (Math.random() * .2 - .1)); - } - - } - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = []; + + for(var i = 0; i < 100; i += 1) { + var p = particle.create(width / 2, height, Math.random() * 8 + 5, -Math.PI / 2 + (Math.random() * .2 - .1), 0.1); + p.radius = Math.random() * 10 + 2; + particles.push(p); + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + + for(var i = 0; i < 100; i += 1) { + var p = particles[i]; + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + if(p.position.getY() - p.radius > height) { + p.position.setX(width / 2); + p.position.setY(height); + p.velocity.setLength(Math.random() * 8 + 5); + p.velocity.setAngle(-Math.PI / 2 + (Math.random() * .2 - .1)); + } + + } + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode12/regen_extra.js b/episode12/regen_extra.js index d2a5b1c..3737ff9 100644 --- a/episode12/regen_extra.js +++ b/episode12/regen_extra.js @@ -1,42 +1,42 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = []; - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - // if we have less than 100 particles, create one and add it to the array - // once we have 100, this will be skipped. - if(particles.length < 100) { - var p = particle.create(width / 2, height, 5 + Math.random() * 8, -Math.PI / 2 + (Math.random() * .2 - .1), 0.1); - p.radius = Math.random() * 10 + 2; - particles.push(p); - } - - for(var i = 0; i < particles.length; i += 1) { - var p = particles[i]; - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - if(p.position.getY() - p.radius > height) { - p.position.setX(width / 2); - p.position.setY(height); - p.velocity.setLength(5 + Math.random() * 8); - p.velocity.setAngle(-Math.PI / 2 + (Math.random() * .2 - .1)); - } - } - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = []; + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + // if we have less than 100 particles, create one and add it to the array + // once we have 100, this will be skipped. + if(particles.length < 100) { + var p = particle.create(width / 2, height, 5 + Math.random() * 8, -Math.PI / 2 + (Math.random() * .2 - .1), 0.1); + p.radius = Math.random() * 10 + 2; + particles.push(p); + } + + for(var i = 0; i < particles.length; i += 1) { + var p = particles[i]; + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + if(p.position.getY() - p.radius > height) { + p.position.setX(width / 2); + p.position.setY(height); + p.velocity.setLength(5 + Math.random() * 8); + p.velocity.setAngle(-Math.PI / 2 + (Math.random() * .2 - .1)); + } + } + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode12/removal.js b/episode12/removal.js index a02bf65..3ff77e8 100644 --- a/episode12/removal.js +++ b/episode12/removal.js @@ -1,51 +1,51 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = []; - - for(var i = 0; i < 100; i += 1) { - var p = particle.create(width / 2, height / 2, Math.random() * 5 + 2, Math.random() * Math.PI * 2); - p.radius = 10; - particles.push(p); - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - console.log(particles.length); - - - for(var i = 0; i < particles.length; i += 1) { - var p = particles[i]; - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - } - - removeDeadParticles(); - - requestAnimationFrame(update); - } - - - function removeDeadParticles() { - for(var i = particles.length - 1; i >= 0; i -= 1) { - var p = particles[i]; - if(p.position.getX() - p.radius > width || - p.position.getX() + p.radius < 0 || - p.position.getY() - p.radius > height || - p.position.getY() + p.radius < 0) { - - particles.splice(i, 1); - } - } - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = []; + + for(var i = 0; i < 100; i += 1) { + var p = particle.create(width / 2, height / 2, Math.random() * 5 + 2, Math.random() * Math.PI * 2); + p.radius = 10; + particles.push(p); + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + console.log(particles.length); + + + for(var i = 0; i < particles.length; i += 1) { + var p = particles[i]; + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + } + + removeDeadParticles(); + + requestAnimationFrame(update); + } + + + function removeDeadParticles() { + for(var i = particles.length - 1; i >= 0; i -= 1) { + var p = particles[i]; + if(p.position.getX() - p.radius > width || + p.position.getX() + p.radius < 0 || + p.position.getY() - p.radius > height || + p.position.getY() + p.radius < 0) { + + particles.splice(i, 1); + } + } + } }; \ No newline at end of file diff --git a/episode12/vector.js b/episode12/vector.js index 609f6d5..4d66796 100644 --- a/episode12/vector.js +++ b/episode12/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode12/wrapping.js b/episode12/wrapping.js index a5706b0..f698acd 100644 --- a/episode12/wrapping.js +++ b/episode12/wrapping.js @@ -1,38 +1,38 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p = particle.create(width / 2, height / 2, 3, Math.random() * Math.PI * 2); - - p.radius = 50; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - if(p.position.getX() - p.radius > width) { - p.position.setX(-p.radius); - } - if(p.position.getX() + p.radius < 0) { - p.position.setX(width + p.radius); - } - if(p.position.getY() - p.radius > height) { - p.position.setY(-p.radius); - } - if(p.position.getY() + p.radius < 0) { - p.position.setY(height + p.radius); - } - - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p = particle.create(width / 2, height / 2, 3, Math.random() * Math.PI * 2); + + p.radius = 50; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + if(p.position.getX() - p.radius > width) { + p.position.setX(-p.radius); + } + if(p.position.getX() + p.radius < 0) { + p.position.setX(width + p.radius); + } + if(p.position.getY() - p.radius > height) { + p.position.setY(-p.radius); + } + if(p.position.getY() + p.radius < 0) { + p.position.setY(height + p.radius); + } + + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode13/friction1.js b/episode13/friction1.js index 8b719e7..a10a61b 100644 --- a/episode13/friction1.js +++ b/episode13/friction1.js @@ -1,33 +1,33 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p = particle.create(width / 2, height / 2, 10, Math.random() * Math.PI * 2), - friction = vector.create(0.15, 0); - - p.radius = 10; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - friction.setAngle(p.velocity.getAngle()); - - if(p.velocity.getLength() > friction.getLength()) { - p.velocity.subtractFrom(friction); - } - else { - p.velocity.setLength(0); - } - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p = particle.create(width / 2, height / 2, 10, Math.random() * Math.PI * 2), + friction = vector.create(0.15, 0); + + p.radius = 10; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + friction.setAngle(p.velocity.getAngle()); + + if(p.velocity.getLength() > friction.getLength()) { + p.velocity.subtractFrom(friction); + } + else { + p.velocity.setLength(0); + } + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode13/friction2.js b/episode13/friction2.js index e5b5e40..46ec238 100644 --- a/episode13/friction2.js +++ b/episode13/friction2.js @@ -1,26 +1,26 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p = particle.create(width / 2, height / 2, 10, Math.random() * Math.PI * 2), - friction = 0.97; - - p.radius = 10; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - p.velocity.multiplyBy(friction); - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); - context.fill(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p = particle.create(width / 2, height / 2, 10, Math.random() * Math.PI * 2), + friction = 0.97; + + p.radius = 10; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + p.velocity.multiplyBy(friction); + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), p.radius, 0, Math.PI * 2, false); + context.fill(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode13/index.html b/episode13/index.html index 9ad4a10..1ac566f 100644 --- a/episode13/index.html +++ b/episode13/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode13/particle.js b/episode13/particle.js index 2269cf9..53e94c1 100644 --- a/episode13/particle.js +++ b/episode13/particle.js @@ -1,49 +1,49 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode13/ship2.js b/episode13/ship2.js index a93b849..26de8f0 100644 --- a/episode13/ship2.js +++ b/episode13/ship2.js @@ -1,102 +1,102 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight - ship = particle.create(width / 2, height / 2, 0, 0), - thrust = vector.create(0, 0), - angle = 0, - turningLeft = false, - turningRight = false, - thrusting = false; - - ship.friction = 0.99; - - document.body.addEventListener("keydown", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = true; - break; - case 37: // left - turningLeft = true; - break; - case 39: // right - turningRight = true; - default: - break - } - }); - - document.body.addEventListener("keyup", function(event) { - // console.log(event.keyCode); - switch(event.keyCode) { - case 38: // up - thrusting = false; - break; - case 37: // left - turningLeft = false; - break; - case 39: // right - turningRight = false; - default: - break - } - }); - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - if(turningRight) { - angle += .05; - } - if(turningLeft) { - angle -= .05; - } - - if(thrusting) { - thrust.setLength(.1); - } - else { - thrust.setLength(0); - } - thrust.setAngle(angle); - - ship.accelerate(thrust); - ship.update(); - - if(ship.position.getX() > width) { - ship.position.setX(0); - } - if(ship.position.getX() < 0) { - ship.position.setX(width); - } - if(ship.position.getY() > height) { - ship.position.setY(0); - } - if(ship.position.getY() < 0) { - ship.position.setY(height); - } - - context.save(); - - context.translate(ship.position.getX(), ship.position.getY()); - context.rotate(angle); - context.beginPath(); - context.moveTo(10, 0); - context.lineTo(-10, -7); - context.lineTo(-10, 7 ); - context.lineTo(10, 0); - if(thrusting) { - context.moveTo(-10, 0); - context.lineTo(-18, 0); - } - context.stroke(); - - context.restore(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight + ship = particle.create(width / 2, height / 2, 0, 0), + thrust = vector.create(0, 0), + angle = 0, + turningLeft = false, + turningRight = false, + thrusting = false; + + ship.friction = 0.99; + + document.body.addEventListener("keydown", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = true; + break; + case 37: // left + turningLeft = true; + break; + case 39: // right + turningRight = true; + default: + break + } + }); + + document.body.addEventListener("keyup", function(event) { + // console.log(event.keyCode); + switch(event.keyCode) { + case 38: // up + thrusting = false; + break; + case 37: // left + turningLeft = false; + break; + case 39: // right + turningRight = false; + default: + break + } + }); + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + if(turningRight) { + angle += .05; + } + if(turningLeft) { + angle -= .05; + } + + if(thrusting) { + thrust.setLength(.1); + } + else { + thrust.setLength(0); + } + thrust.setAngle(angle); + + ship.accelerate(thrust); + ship.update(); + + if(ship.position.getX() > width) { + ship.position.setX(0); + } + if(ship.position.getX() < 0) { + ship.position.setX(width); + } + if(ship.position.getY() > height) { + ship.position.setY(0); + } + if(ship.position.getY() < 0) { + ship.position.setY(height); + } + + context.save(); + + context.translate(ship.position.getX(), ship.position.getY()); + context.rotate(angle); + context.beginPath(); + context.moveTo(10, 0); + context.lineTo(-10, -7); + context.lineTo(-10, 7 ); + context.lineTo(10, 0); + if(thrusting) { + context.moveTo(-10, 0); + context.lineTo(-18, 0); + } + context.stroke(); + + context.restore(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode13/vector.js b/episode13/vector.js index 609f6d5..4d66796 100644 --- a/episode13/vector.js +++ b/episode13/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode14/circle-circle.js b/episode14/circle-circle.js index 6338230..258490d 100644 --- a/episode14/circle-circle.js +++ b/episode14/circle-circle.js @@ -1,43 +1,43 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - circle0 = { - x: Math.random() * width, - y: Math.random() * height, - radius: 50 + Math.random() * 100 - }, - - circle1 = { - x: Math.random() * width, - y: Math.random() * height, - radius: 50 + Math.random() * 100 - }; - - document.body.addEventListener("mousemove", function(event) { - circle1.x = event.clientX; - circle1.y = event.clientY; - - if(utils.circleCollision(circle0, circle1)) { - context.fillStyle = "#f66"; - } - else { - context.fillStyle = "#999"; - } - - context.clearRect(0, 0, width, height); - context.beginPath(); - context.arc(circle0.x, circle0.y, circle0.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(circle1.x, circle1.y, circle1.radius, - 0, Math.PI * 2, false); - context.fill(); - - }) - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + circle0 = { + x: Math.random() * width, + y: Math.random() * height, + radius: 50 + Math.random() * 100 + }, + + circle1 = { + x: Math.random() * width, + y: Math.random() * height, + radius: 50 + Math.random() * 100 + }; + + document.body.addEventListener("mousemove", function(event) { + circle1.x = event.clientX; + circle1.y = event.clientY; + + if(utils.circleCollision(circle0, circle1)) { + context.fillStyle = "#f66"; + } + else { + context.fillStyle = "#999"; + } + + context.clearRect(0, 0, width, height); + context.beginPath(); + context.arc(circle0.x, circle0.y, circle0.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(circle1.x, circle1.y, circle1.radius, + 0, Math.PI * 2, false); + context.fill(); + + }) + + }; \ No newline at end of file diff --git a/episode14/circle-point.js b/episode14/circle-point.js index 4e09e9f..03e31b8 100644 --- a/episode14/circle-point.js +++ b/episode14/circle-point.js @@ -1,30 +1,30 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - circle = { - x: Math.random() * width, - y: Math.random() * height, - radius: 50 + Math.random() * 100 - }; - - document.body.addEventListener("mousemove", function(event) { - - if(utils.circlePointCollision(event.clientX, event.clientY, circle)) { - context.fillStyle = "#f66"; - } - else { - context.fillStyle = "#999"; - } - - context.clearRect(0, 0, width, height); - context.beginPath(); - context.arc(circle.x, circle.y, circle.radius, - 0, Math.PI * 2, false); - context.fill(); - - }) - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + circle = { + x: Math.random() * width, + y: Math.random() * height, + radius: 50 + Math.random() * 100 + }; + + document.body.addEventListener("mousemove", function(event) { + + if(utils.circlePointCollision(event.clientX, event.clientY, circle)) { + context.fillStyle = "#f66"; + } + else { + context.fillStyle = "#999"; + } + + context.clearRect(0, 0, width, height); + context.beginPath(); + context.arc(circle.x, circle.y, circle.radius, + 0, Math.PI * 2, false); + context.fill(); + + }) + + }; \ No newline at end of file diff --git a/episode14/index.html b/episode14/index.html index b9547fa..df145f8 100644 --- a/episode14/index.html +++ b/episode14/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode14/main.js b/episode14/main.js index 44dc5bd..61deb1f 100644 --- a/episode14/main.js +++ b/episode14/main.js @@ -1,9 +1,9 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + + }; \ No newline at end of file diff --git a/episode14/particle.js b/episode14/particle.js index 2269cf9..53e94c1 100644 --- a/episode14/particle.js +++ b/episode14/particle.js @@ -1,49 +1,49 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode14/rect-point.js b/episode14/rect-point.js index 6aba12b..8e34b5b 100644 --- a/episode14/rect-point.js +++ b/episode14/rect-point.js @@ -1,24 +1,24 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - rect = { - x: 300, - y: 200, - width: -200, - height: -100 - }; - - document.body.addEventListener("mousemove", function(event) { - - context.clearRect(0, 0, width, height); - if(utils.pointInRect(event.clientX, event.clientY, rect)) { - context.fillStyle = "#ff6666"; - } - else { - context.fillStyle = "#999999"; - } - context.fillRect(rect.x, rect.y, rect.width, rect.height); - }) +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + rect = { + x: 300, + y: 200, + width: -200, + height: -100 + }; + + document.body.addEventListener("mousemove", function(event) { + + context.clearRect(0, 0, width, height); + if(utils.pointInRect(event.clientX, event.clientY, rect)) { + context.fillStyle = "#ff6666"; + } + else { + context.fillStyle = "#999999"; + } + context.fillRect(rect.x, rect.y, rect.width, rect.height); + }) }; \ No newline at end of file diff --git a/episode14/rect-rect.js b/episode14/rect-rect.js index 1da4d0d..9dfc79a 100644 --- a/episode14/rect-rect.js +++ b/episode14/rect-rect.js @@ -1,36 +1,36 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - rect0 = { - x: 200, - y: 200, - width: -200, - height: -100 - }, - rect1 = { - x: 0, - y: 0, - width: -100, - height: -200 - }; - - document.body.addEventListener("mousemove", function(event) { - rect1.x = event.clientX - 50; - rect1.y = event.clientY - 100; - - context.clearRect(0, 0, width, height); - if(utils.rectIntersect(rect0, rect1)) { - context.fillStyle = "#ff6666"; - } - else { - context.fillStyle = "#999999"; - } - context.fillRect(rect0.x, rect0.y, rect0.width, rect0.height); - context.fillRect(rect1.x, rect1.y, rect1.width, rect1.height); - }) - - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + rect0 = { + x: 200, + y: 200, + width: -200, + height: -100 + }, + rect1 = { + x: 0, + y: 0, + width: -100, + height: -200 + }; + + document.body.addEventListener("mousemove", function(event) { + rect1.x = event.clientX - 50; + rect1.y = event.clientY - 100; + + context.clearRect(0, 0, width, height); + if(utils.rectIntersect(rect0, rect1)) { + context.fillStyle = "#ff6666"; + } + else { + context.fillStyle = "#999999"; + } + context.fillRect(rect0.x, rect0.y, rect0.width, rect0.height); + context.fillRect(rect1.x, rect1.y, rect1.width, rect1.height); + }) + + + }; \ No newline at end of file diff --git a/episode14/utils.js b/episode14/utils.js index bd5b5e6..5eecdc3 100644 --- a/episode14/utils.js +++ b/episode14/utils.js @@ -1,57 +1,57 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + } + } \ No newline at end of file diff --git a/episode14/vector.js b/episode14/vector.js index 609f6d5..4d66796 100644 --- a/episode14/vector.js +++ b/episode14/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode15/index.html b/episode15/index.html index 26a2d0a..f0073e4 100644 --- a/episode15/index.html +++ b/episode15/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode15/particle.js b/episode15/particle.js index 2269cf9..53e94c1 100644 --- a/episode15/particle.js +++ b/episode15/particle.js @@ -1,49 +1,49 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode15/spring1.js b/episode15/spring1.js index d480dc9..b73b478 100644 --- a/episode15/spring1.js +++ b/episode15/spring1.js @@ -1,50 +1,50 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - springPoint = vector.create(width / 2, height / 2), - weight = particle.create(Math.random() * width, Math.random() * height, - 50, Math.random() * Math.PI * 2), - k = 0.01 + Math.random() * .5; - - weight.radius = 20; - weight.friction = 0.5 + Math.random() * .5; - - document.body.addEventListener("mousemove", function(event) { - springPoint.setX(event.clientX); - springPoint.setY(event.clientY); - }); - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - var distance = springPoint.subtract(weight.position), - springForce = distance.multiply(k); - - weight.velocity.addTo(springForce); - - weight.update(); - - context.beginPath(); - context.arc(weight.position.getX(), weight.position.getY(), weight.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(springPoint.getX(), springPoint.getY(), 4, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(weight.position.getX(), weight.position.getY()); - context.lineTo(springPoint.getX(), springPoint.getY()); - context.stroke(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + springPoint = vector.create(width / 2, height / 2), + weight = particle.create(Math.random() * width, Math.random() * height, + 50, Math.random() * Math.PI * 2), + k = 0.01 + Math.random() * .5; + + weight.radius = 20; + weight.friction = 0.5 + Math.random() * .5; + + document.body.addEventListener("mousemove", function(event) { + springPoint.setX(event.clientX); + springPoint.setY(event.clientY); + }); + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + var distance = springPoint.subtract(weight.position), + springForce = distance.multiply(k); + + weight.velocity.addTo(springForce); + + weight.update(); + + context.beginPath(); + context.arc(weight.position.getX(), weight.position.getY(), weight.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(springPoint.getX(), springPoint.getY(), 4, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(weight.position.getX(), weight.position.getY()); + context.lineTo(springPoint.getX(), springPoint.getY()); + context.stroke(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode15/utils.js b/episode15/utils.js index bd5b5e6..5eecdc3 100644 --- a/episode15/utils.js +++ b/episode15/utils.js @@ -1,57 +1,57 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + } + } \ No newline at end of file diff --git a/episode15/vector.js b/episode15/vector.js index 609f6d5..4d66796 100644 --- a/episode15/vector.js +++ b/episode15/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode16/index.html b/episode16/index.html index 9721461..0aa0e0f 100644 --- a/episode16/index.html +++ b/episode16/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode16/particle.js b/episode16/particle.js index 2269cf9..53e94c1 100644 --- a/episode16/particle.js +++ b/episode16/particle.js @@ -1,49 +1,49 @@ -var particle = { - position: null, - velocity: null, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.multiplyBy(this.friction); - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - }, - - angleTo: function(p2) { - return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); - }, - - distanceTo: function(p2) { - var dx = p2.position.getX() - this.position.getX(), - dy = p2.position.getY() - this.position.getY(); - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var grav = vector.create(0, 0), - dist = this.distanceTo(p2); - - grav.setLength(p2.mass / (dist * dist)); - grav.setAngle(this.angleTo(p2)); - this.velocity.addTo(grav); - } +var particle = { + position: null, + velocity: null, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.multiplyBy(this.friction); + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + }, + + angleTo: function(p2) { + return Math.atan2(p2.position.getY() - this.position.getY(), p2.position.getX() - this.position.getX()); + }, + + distanceTo: function(p2) { + var dx = p2.position.getX() - this.position.getX(), + dy = p2.position.getY() - this.position.getY(); + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var grav = vector.create(0, 0), + dist = this.distanceTo(p2); + + grav.setLength(p2.mass / (dist * dist)); + grav.setAngle(this.angleTo(p2)); + this.velocity.addTo(grav); + } }; \ No newline at end of file diff --git a/episode16/spring1.js b/episode16/spring1.js index 036e6dd..6f58036 100644 --- a/episode16/spring1.js +++ b/episode16/spring1.js @@ -1,52 +1,52 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - springPoint = vector.create(width / 2, height / 2), - weight = particle.create(Math.random() * width, Math.random() * height, - 50, Math.random() * Math.PI * 2, 0.5), - k = 0.1, - springLength = 100; - - weight.radius = 20; - weight.friction = 0.95; - - document.body.addEventListener("mousemove", function(event) { - springPoint.setX(event.clientX); - springPoint.setY(event.clientY); - }); - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - var distance = springPoint.subtract(weight.position); - distance.setLength(distance.getLength() - springLength); - var springForce = distance.multiply(k); - - weight.velocity.addTo(springForce); - - weight.update(); - - context.beginPath(); - context.arc(weight.position.getX(), weight.position.getY(), weight.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(springPoint.getX(), springPoint.getY(), 4, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(weight.position.getX(), weight.position.getY()); - context.lineTo(springPoint.getX(), springPoint.getY()); - context.stroke(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + springPoint = vector.create(width / 2, height / 2), + weight = particle.create(Math.random() * width, Math.random() * height, + 50, Math.random() * Math.PI * 2, 0.5), + k = 0.1, + springLength = 100; + + weight.radius = 20; + weight.friction = 0.95; + + document.body.addEventListener("mousemove", function(event) { + springPoint.setX(event.clientX); + springPoint.setY(event.clientY); + }); + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + var distance = springPoint.subtract(weight.position); + distance.setLength(distance.getLength() - springLength); + var springForce = distance.multiply(k); + + weight.velocity.addTo(springForce); + + weight.update(); + + context.beginPath(); + context.arc(weight.position.getX(), weight.position.getY(), weight.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(springPoint.getX(), springPoint.getY(), 4, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(weight.position.getX(), weight.position.getY()); + context.lineTo(springPoint.getX(), springPoint.getY()); + context.stroke(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode16/spring2.js b/episode16/spring2.js index addc051..5077219 100644 --- a/episode16/spring2.js +++ b/episode16/spring2.js @@ -1,91 +1,91 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particleA = particle.create(utils.randomRange(0, width), - utils.randomRange(0, height), - utils.randomRange(0, 50), - utils.randomRange(0, Math.PI * 2), - 0.2), - particleB = particle.create(utils.randomRange(0, width), - utils.randomRange(0, height), - utils.randomRange(0, 50), - utils.randomRange(0, Math.PI * 2), - 0.2), - particleC = particle.create(utils.randomRange(0, width), - utils.randomRange(0, height), - utils.randomRange(0, 50), - utils.randomRange(0, Math.PI * 2), - 0.2), - k = 0.01, - separation = 200; - - particleA.friction = 0.9; - particleA.radius = 20; - - particleB.friction = 0.9; - particleB.radius = 20; - - particleC.friction = 0.9; - particleC.radius = 20; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - spring(particleA, particleB, separation); - spring(particleB, particleC, separation); - spring(particleC, particleA, separation); - - checkEdges(particleA); - checkEdges(particleB); - checkEdges(particleC); - - particleA.update(); - particleB.update(); - particleC.update(); - - context.beginPath(); - context.arc(particleA.position.getX(), particleA.position.getY(), - particleA.radius, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(particleB.position.getX(), particleB.position.getY(), - particleB.radius, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(particleC.position.getX(), particleC.position.getY(), - particleC.radius, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(particleA.position.getX(), particleA.position.getY()); - context.lineTo(particleB.position.getX(), particleB.position.getY()); - context.lineTo(particleC.position.getX(), particleC.position.getY()); - context.lineTo(particleA.position.getX(), particleA.position.getY()); - context.stroke(); - - requestAnimationFrame(update); - } - - function spring(p0, p1, separation) { - var distance = p0.position.subtract(p1.position); - distance.setLength(distance.getLength() - separation); - - var springForce = distance.multiply(k); - - p1.velocity.addTo(springForce); - p0.velocity.subtractFrom(springForce); - } - - function checkEdges(p) { - if(p.position.getY() + p.radius > height) { - p.position.setY(height - p.radius); - p.velocity.setY(p.velocity.getY() * -0.95); - } - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particleA = particle.create(utils.randomRange(0, width), + utils.randomRange(0, height), + utils.randomRange(0, 50), + utils.randomRange(0, Math.PI * 2), + 0.2), + particleB = particle.create(utils.randomRange(0, width), + utils.randomRange(0, height), + utils.randomRange(0, 50), + utils.randomRange(0, Math.PI * 2), + 0.2), + particleC = particle.create(utils.randomRange(0, width), + utils.randomRange(0, height), + utils.randomRange(0, 50), + utils.randomRange(0, Math.PI * 2), + 0.2), + k = 0.01, + separation = 200; + + particleA.friction = 0.9; + particleA.radius = 20; + + particleB.friction = 0.9; + particleB.radius = 20; + + particleC.friction = 0.9; + particleC.radius = 20; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + spring(particleA, particleB, separation); + spring(particleB, particleC, separation); + spring(particleC, particleA, separation); + + checkEdges(particleA); + checkEdges(particleB); + checkEdges(particleC); + + particleA.update(); + particleB.update(); + particleC.update(); + + context.beginPath(); + context.arc(particleA.position.getX(), particleA.position.getY(), + particleA.radius, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(particleB.position.getX(), particleB.position.getY(), + particleB.radius, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(particleC.position.getX(), particleC.position.getY(), + particleC.radius, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(particleA.position.getX(), particleA.position.getY()); + context.lineTo(particleB.position.getX(), particleB.position.getY()); + context.lineTo(particleC.position.getX(), particleC.position.getY()); + context.lineTo(particleA.position.getX(), particleA.position.getY()); + context.stroke(); + + requestAnimationFrame(update); + } + + function spring(p0, p1, separation) { + var distance = p0.position.subtract(p1.position); + distance.setLength(distance.getLength() - separation); + + var springForce = distance.multiply(k); + + p1.velocity.addTo(springForce); + p0.velocity.subtractFrom(springForce); + } + + function checkEdges(p) { + if(p.position.getY() + p.radius > height) { + p.position.setY(height - p.radius); + p.velocity.setY(p.velocity.getY() * -0.95); + } + } }; \ No newline at end of file diff --git a/episode16/utils.js b/episode16/utils.js index 37ae5ef..9728633 100644 --- a/episode16/utils.js +++ b/episode16/utils.js @@ -1,73 +1,73 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + } + } \ No newline at end of file diff --git a/episode16/vector.js b/episode16/vector.js index 609f6d5..4d66796 100644 --- a/episode16/vector.js +++ b/episode16/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode17/index.html b/episode17/index.html index 26a2d0a..f0073e4 100644 --- a/episode17/index.html +++ b/episode17/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode17/orbit.js b/episode17/orbit.js index 0121e8a..eec5651 100644 --- a/episode17/orbit.js +++ b/episode17/orbit.js @@ -1,34 +1,34 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - sun = particle.create(width / 2, height / 2, 0, 0); - planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); - - sun.mass = 20000; - - update(); - - - function update() { - context.clearRect(0, 0, width, height); - - // animation goes here - - planet.gravitateTo(sun); - planet.update(); - - context.beginPath(); - context.fillStyle = "#ffff00"; - context.arc(sun.x, sun.y, 20, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.fillStyle = "#0000ff"; - context.arc(planet.x, planet.y, 4, 0, Math.PI * 2, false); - context.fill(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + sun = particle.create(width / 2, height / 2, 0, 0); + planet = particle.create(width / 2 + 200, height / 2, 10, -Math.PI / 2); + + sun.mass = 20000; + + update(); + + + function update() { + context.clearRect(0, 0, width, height); + + // animation goes here + + planet.gravitateTo(sun); + planet.update(); + + context.beginPath(); + context.fillStyle = "#ffff00"; + context.arc(sun.x, sun.y, 20, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.fillStyle = "#0000ff"; + context.arc(planet.x, planet.y, 4, 0, Math.PI * 2, false); + context.fill(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode17/particle.js b/episode17/particle.js index 76ad889..5265c6a 100644 --- a/episode17/particle.js +++ b/episode17/particle.js @@ -1,58 +1,58 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - return obj; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + return obj; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + } }; \ No newline at end of file diff --git a/episode17/spring1.js b/episode17/spring1.js index 896a012..82d1f32 100644 --- a/episode17/spring1.js +++ b/episode17/spring1.js @@ -1,59 +1,59 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - springPoint = { - x: width / 2, - y: height / 2 - }, - weight = particle.create(Math.random() * width, Math.random() * height, - 50, Math.random() * Math.PI * 2, 0.5), - k = 0.1, - springLength = 100; - - weight.radius = 20; - weight.friction = 0.95; - - document.body.addEventListener("mousemove", function(event) { - springPoint.x = event.clientX ; - springPoint.y = event.clientY; - }); - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - var dx = springPoint.x - weight.x, - dy = springPoint.y - weight.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - springLength) * k, - ax = dx / distance * springForce, - ay = dy / distance * springForce; - - weight.vx += ax; - weight.vy += ay; - - weight.update(); - - context.beginPath(); - context.arc(weight.x, weight.y, weight.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(springPoint.x, springPoint.y, 4, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(weight.x, weight.y); - context.lineTo(springPoint.x, springPoint.y); - context.stroke(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + springPoint = { + x: width / 2, + y: height / 2 + }, + weight = particle.create(Math.random() * width, Math.random() * height, + 50, Math.random() * Math.PI * 2, 0.5), + k = 0.1, + springLength = 100; + + weight.radius = 20; + weight.friction = 0.95; + + document.body.addEventListener("mousemove", function(event) { + springPoint.x = event.clientX ; + springPoint.y = event.clientY; + }); + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + var dx = springPoint.x - weight.x, + dy = springPoint.y - weight.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - springLength) * k, + ax = dx / distance * springForce, + ay = dy / distance * springForce; + + weight.vx += ax; + weight.vy += ay; + + weight.update(); + + context.beginPath(); + context.arc(weight.x, weight.y, weight.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(springPoint.x, springPoint.y, 4, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(weight.x, weight.y); + context.lineTo(springPoint.x, springPoint.y); + context.stroke(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode17/utils.js b/episode17/utils.js index 37ae5ef..9728633 100644 --- a/episode17/utils.js +++ b/episode17/utils.js @@ -1,73 +1,73 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + } + } \ No newline at end of file diff --git a/episode17/vector.js b/episode17/vector.js index 609f6d5..4d66796 100644 --- a/episode17/vector.js +++ b/episode17/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode18/index.html b/episode18/index.html index cb3cccd..1f0560b 100644 --- a/episode18/index.html +++ b/episode18/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode18/main.js b/episode18/main.js index 928ac35..46c59ac 100644 --- a/episode18/main.js +++ b/episode18/main.js @@ -1,132 +1,132 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gun = { - x: 100, - y: height, - angle: -Math.PI / 4 - }, - cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), - isShooting = false, - forceAngle = 0, - forceSpeed = 0.1, - rawForce = 0, - target = {}; - - cannonball.radius = 7; - - setTarget(); - update (); - - function setTarget() { - target.x = utils.randomRange(200, width); - target.y = height; - target.radius = utils.randomRange(10, 40); - } - - document.body.addEventListener("mousedown", onMouseDown); - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 32: // space - if(!isShooting) { - shoot(); - } - break; - - default: - break; - } - }); - - function shoot() { - var force = utils.map(rawForce, -1, 1, 2, 20); - cannonball.x = gun.x + Math.cos(gun.angle) * 40; - cannonball.y = gun.y + Math.sin(gun.angle) * 40; - cannonball.setSpeed(force); - cannonball.setHeading(gun.angle); - - isShooting = true; - } - - function update() { - if(!isShooting) { - forceAngle += forceSpeed; - } - rawForce = Math.sin(forceAngle); - if(isShooting) { - cannonball.update(); - checkTarget(); - } - draw(); - - if(cannonball.y > height) { - isShooting = false; - } - requestAnimationFrame(update); - } - - function checkTarget() { - if(utils.circleCollision(target, cannonball)) { - // create amazing collision reaction!!! - setTarget(); - } - } - - function onMouseDown(event) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function onMouseMove(event) { - aimGun(event.clientX, event.clientY); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - aimGun(event.clientX, event.clientY); - } - - function aimGun(mouseX, mouseY) { - gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); - } - - function draw() { - context.clearRect(0, 0, width, height); - - context.fillStyle = "#ccc"; - context.fillRect(10, height - 10, 20, -100); - - context.fillStyle = "#666"; - context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); - - context.fillStyle = "#000"; - - context.beginPath(); - context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); - context.fill(); - - context.save(); - context.translate(gun.x, gun.y); - context.rotate(gun.angle); - context.fillRect(0, -8, 40, 16); - context.restore(); - - context.beginPath(); - context.arc(cannonball.x, - cannonball.y, - cannonball.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "red"; - context.beginPath(); - context.arc(target.x, target.y, target.radius, 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gun = { + x: 100, + y: height, + angle: -Math.PI / 4 + }, + cannonball = particle.create(gun.x, gun.y, 15, gun.angle, 0.2), + isShooting = false, + forceAngle = 0, + forceSpeed = 0.1, + rawForce = 0, + target = {}; + + cannonball.radius = 7; + + setTarget(); + update (); + + function setTarget() { + target.x = utils.randomRange(200, width); + target.y = height; + target.radius = utils.randomRange(10, 40); + } + + document.body.addEventListener("mousedown", onMouseDown); + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 32: // space + if(!isShooting) { + shoot(); + } + break; + + default: + break; + } + }); + + function shoot() { + var force = utils.map(rawForce, -1, 1, 2, 20); + cannonball.x = gun.x + Math.cos(gun.angle) * 40; + cannonball.y = gun.y + Math.sin(gun.angle) * 40; + cannonball.setSpeed(force); + cannonball.setHeading(gun.angle); + + isShooting = true; + } + + function update() { + if(!isShooting) { + forceAngle += forceSpeed; + } + rawForce = Math.sin(forceAngle); + if(isShooting) { + cannonball.update(); + checkTarget(); + } + draw(); + + if(cannonball.y > height) { + isShooting = false; + } + requestAnimationFrame(update); + } + + function checkTarget() { + if(utils.circleCollision(target, cannonball)) { + // create amazing collision reaction!!! + setTarget(); + } + } + + function onMouseDown(event) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function onMouseMove(event) { + aimGun(event.clientX, event.clientY); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + aimGun(event.clientX, event.clientY); + } + + function aimGun(mouseX, mouseY) { + gun.angle = utils.clamp(Math.atan2(mouseY - gun.y, mouseX - gun.x), -Math.PI / 2, -0.3); + } + + function draw() { + context.clearRect(0, 0, width, height); + + context.fillStyle = "#ccc"; + context.fillRect(10, height - 10, 20, -100); + + context.fillStyle = "#666"; + context.fillRect(10, height - 10, 20, utils.map(rawForce, -1, 1, 0, -100)); + + context.fillStyle = "#000"; + + context.beginPath(); + context.arc(gun.x, gun.y, 24, 0, Math.PI * 2, false); + context.fill(); + + context.save(); + context.translate(gun.x, gun.y); + context.rotate(gun.angle); + context.fillRect(0, -8, 40, 16); + context.restore(); + + context.beginPath(); + context.arc(cannonball.x, + cannonball.y, + cannonball.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "red"; + context.beginPath(); + context.arc(target.x, target.y, target.radius, 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/episode18/multigravity.js b/episode18/multigravity.js index 55c22df..cc960d1 100644 --- a/episode18/multigravity.js +++ b/episode18/multigravity.js @@ -1,63 +1,63 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - sun1 = particle.create(300, 200, 0, 0), - sun2 = particle.create(800, 600, 0, 0), - emitter = { - x: 100, - y: 0 - }, - particles = [], - numParticles = 100; - - - sun1.mass = 10000; - sun1.radius = 10; - sun2.mass = 20000; - sun2.radius = 20; - - for(var i = 0; i < numParticles; i += 1) { - var p = particle.create(emitter.x, emitter.y, utils.randomRange(7, 8), Math.PI / 2 + utils.randomRange(-0.1, 0.1)); - p.addGravitation(sun1); - p.addGravitation(sun2); - p.radius = 3; - particles.push(p); - } - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - draw(sun1, "yellow"); - draw(sun2, "yellow"); - - for(var i = 0; i < numParticles; i += 1) { - var p = particles[i]; - p.update(); - draw(p, "black"); - if(p.x > width || - p.x < 0 || - p.y > height || - p.y < 0) { - p.x = emitter.x; - p.y = emitter.y; - p.setSpeed(utils.randomRange(7, 8)); - p.setHeading(Math.PI / 2 + utils.randomRange(-.1, .1)); - } - } - - requestAnimationFrame(update); - } - - function draw(p, color) { - context.fillStyle = color; - context.beginPath(); - context.arc(p.x, p.y, p.radius, 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + sun1 = particle.create(300, 200, 0, 0), + sun2 = particle.create(800, 600, 0, 0), + emitter = { + x: 100, + y: 0 + }, + particles = [], + numParticles = 100; + + + sun1.mass = 10000; + sun1.radius = 10; + sun2.mass = 20000; + sun2.radius = 20; + + for(var i = 0; i < numParticles; i += 1) { + var p = particle.create(emitter.x, emitter.y, utils.randomRange(7, 8), Math.PI / 2 + utils.randomRange(-0.1, 0.1)); + p.addGravitation(sun1); + p.addGravitation(sun2); + p.radius = 3; + particles.push(p); + } + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + draw(sun1, "yellow"); + draw(sun2, "yellow"); + + for(var i = 0; i < numParticles; i += 1) { + var p = particles[i]; + p.update(); + draw(p, "black"); + if(p.x > width || + p.x < 0 || + p.y > height || + p.y < 0) { + p.x = emitter.x; + p.y = emitter.y; + p.setSpeed(utils.randomRange(7, 8)); + p.setHeading(Math.PI / 2 + utils.randomRange(-.1, .1)); + } + } + + requestAnimationFrame(update); + } + + function draw(p, color) { + context.fillStyle = color; + context.beginPath(); + context.arc(p.x, p.y, p.radius, 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/episode18/particle.js b/episode18/particle.js index b6ef621..948e47a 100644 --- a/episode18/particle.js +++ b/episode18/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/episode18/spring1.js b/episode18/spring1.js index 1b81c3c..73bea15 100644 --- a/episode18/spring1.js +++ b/episode18/spring1.js @@ -1,56 +1,56 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - springPoint = { - x: width / 2, - y: height / 2 - }, - springPoint2 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - weight = particle.create(Math.random() * width, Math.random() * height, - 50, Math.random() * Math.PI * 2, 0.5), - k = 0.1, - springLength = 100; - - weight.radius = 20; - weight.friction = 0.95; - weight.addSpring(springPoint, k, springLength); - weight.addSpring(springPoint2, k, springLength); - - document.body.addEventListener("mousemove", function(event) { - springPoint.x = event.clientX ; - springPoint.y = event.clientY; - }); - - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - weight.update(); - - context.beginPath(); - context.arc(weight.x, weight.y, weight.radius, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(springPoint.x, springPoint.y, 4, - 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(springPoint2.x, springPoint2.y); - context.lineTo(weight.x, weight.y); - context.lineTo(springPoint.x, springPoint.y); - context.stroke(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + springPoint = { + x: width / 2, + y: height / 2 + }, + springPoint2 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + weight = particle.create(Math.random() * width, Math.random() * height, + 50, Math.random() * Math.PI * 2, 0.5), + k = 0.1, + springLength = 100; + + weight.radius = 20; + weight.friction = 0.95; + weight.addSpring(springPoint, k, springLength); + weight.addSpring(springPoint2, k, springLength); + + document.body.addEventListener("mousemove", function(event) { + springPoint.x = event.clientX ; + springPoint.y = event.clientY; + }); + + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + weight.update(); + + context.beginPath(); + context.arc(weight.x, weight.y, weight.radius, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(springPoint.x, springPoint.y, 4, + 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(springPoint2.x, springPoint2.y); + context.lineTo(weight.x, weight.y); + context.lineTo(springPoint.x, springPoint.y); + context.stroke(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode18/utils.js b/episode18/utils.js index 37ae5ef..9728633 100644 --- a/episode18/utils.js +++ b/episode18/utils.js @@ -1,73 +1,73 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + } + } \ No newline at end of file diff --git a/episode18/vector.js b/episode18/vector.js index 609f6d5..4d66796 100644 --- a/episode18/vector.js +++ b/episode18/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode19/demo1.js b/episode19/demo1.js index 51b154e..b6ca34f 100644 --- a/episode19/demo1.js +++ b/episode19/demo1.js @@ -1,74 +1,74 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 600, - y: 200 - }, - pA = {}, - t = 0; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - draw(); - - document.body.addEventListener("click", function() { - draw(); - }); - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(pA.x, pA.y); - context.stroke(); - - labelPointLeft(p0, "p0"); - labelPointLeft(p1, "p1 "); - labelPoint(pA, "pA"); - labelT(); - - t += .1; - t = Math.min(t, 1); - - } - - function labelPoint(p, name) { - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(t, 1), 200, 250); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 600, + y: 200 + }, + pA = {}, + t = 0; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + draw(); + + document.body.addEventListener("click", function() { + draw(); + }); + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(pA.x, pA.y); + context.stroke(); + + labelPointLeft(p0, "p0"); + labelPointLeft(p1, "p1 "); + labelPoint(pA, "pA"); + labelT(); + + t += .1; + t = Math.min(t, 1); + + } + + function labelPoint(p, name) { + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(t, 1), 200, 250); + } + }; \ No newline at end of file diff --git a/episode19/demo2.js b/episode19/demo2.js index 52dff70..6b43846 100644 --- a/episode19/demo2.js +++ b/episode19/demo2.js @@ -1,96 +1,96 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 600, - y: 200 - }, - p2 = { - x: 1000, - y: 400 - }, - pA = {}, - pB = {}, - t = 0; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - draw(); - - document.body.addEventListener("click", function() { - draw(); - }); - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - pB.x = utils.lerp(t, p1.x, p2.x); - pB.y = utils.lerp(t, p1.y, p2.y); - - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(pA.x, pA.y); - context.moveTo(p1.x, p1.y); - context.lineTo(pB.x, pB.y); - context.stroke(); - - labelPointLeft(p0, "p0"); - labelPointLeft(p1, "p1"); - labelPointLeft(p2, "p2"); - labelPoint(pA, "pA"); - labelPoint(pB, "pB"); - labelT(); - - t += .1; - t = Math.min(t, 1); - - } - - function labelPoint(p, name) { - context.fillStyle = "black"; - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillStyle = "gray"; - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(t, 1), 200, 300); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 600, + y: 200 + }, + p2 = { + x: 1000, + y: 400 + }, + pA = {}, + pB = {}, + t = 0; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + draw(); + + document.body.addEventListener("click", function() { + draw(); + }); + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + pB.x = utils.lerp(t, p1.x, p2.x); + pB.y = utils.lerp(t, p1.y, p2.y); + + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(pA.x, pA.y); + context.moveTo(p1.x, p1.y); + context.lineTo(pB.x, pB.y); + context.stroke(); + + labelPointLeft(p0, "p0"); + labelPointLeft(p1, "p1"); + labelPointLeft(p2, "p2"); + labelPoint(pA, "pA"); + labelPoint(pB, "pB"); + labelT(); + + t += .1; + t = Math.min(t, 1); + + } + + function labelPoint(p, name) { + context.fillStyle = "black"; + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillStyle = "gray"; + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(t, 1), 200, 300); + } + }; \ No newline at end of file diff --git a/episode19/demo3.js b/episode19/demo3.js index b709cac..2f5cf38 100644 --- a/episode19/demo3.js +++ b/episode19/demo3.js @@ -1,106 +1,106 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 600, - y: 200 - }, - p2 = { - x: 1000, - y: 400 - }, - pA = {}, - pB = {}, - t = 0, - maxT = 0; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - draw(); - - document.body.addEventListener("click", function() { - draw(); - }); - - function draw() { - context.clearRect(0, 0, width, height); - - context.strokeStyle = "#ccc"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.stroke(); - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.strokeStyle = "black"; - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - for(var t = 0; t <= maxT; t += .1) { - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - pB.x = utils.lerp(t, p1.x, p2.x); - pB.y = utils.lerp(t, p1.y, p2.y); - - context.beginPath(); - context.moveTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.stroke(); - } - - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); - context.fill(); - - - // labelPointLeft(p0, "p0"); - // labelPointLeft(p1, "p1"); - // labelPointLeft(p2, "p2"); - // labelPoint(pA, "pA"); - // labelPoint(pB, "pB"); - labelT(); - - maxT += .1; - maxT = Math.min(t, 1); - - } - - function labelPoint(p, name) { - context.fillStyle = "black"; - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillStyle = "gray"; - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(maxT, 1), 200, 250); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 600, + y: 200 + }, + p2 = { + x: 1000, + y: 400 + }, + pA = {}, + pB = {}, + t = 0, + maxT = 0; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + draw(); + + document.body.addEventListener("click", function() { + draw(); + }); + + function draw() { + context.clearRect(0, 0, width, height); + + context.strokeStyle = "#ccc"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.stroke(); + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.strokeStyle = "black"; + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + for(var t = 0; t <= maxT; t += .1) { + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + pB.x = utils.lerp(t, p1.x, p2.x); + pB.y = utils.lerp(t, p1.y, p2.y); + + context.beginPath(); + context.moveTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.stroke(); + } + + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); + context.fill(); + + + // labelPointLeft(p0, "p0"); + // labelPointLeft(p1, "p1"); + // labelPointLeft(p2, "p2"); + // labelPoint(pA, "pA"); + // labelPoint(pB, "pB"); + labelT(); + + maxT += .1; + maxT = Math.min(t, 1); + + } + + function labelPoint(p, name) { + context.fillStyle = "black"; + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillStyle = "gray"; + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(maxT, 1), 200, 250); + } + }; \ No newline at end of file diff --git a/episode19/demo4.js b/episode19/demo4.js index b966be7..c0fc7e9 100644 --- a/episode19/demo4.js +++ b/episode19/demo4.js @@ -1,125 +1,125 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 100, - y: 300 - }, - p2 = { - x: 1000, - y: 400 - }, - pA = {}, - pB = {}, - pFinal = {}, - t = 0, - maxT = 0; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - draw(); - - document.body.addEventListener("click", function() { - draw(); - }); - - function draw() { - context.clearRect(0, 0, width, height); - - context.strokeStyle = "#ccc"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.stroke(); - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - - context.strokeStyle = "red"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - - for(t = 0; t <= maxT; t += .1) { - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - pB.x = utils.lerp(t, p1.x, p2.x); - pB.y = utils.lerp(t, p1.y, p2.y); - - pFinal.x = utils.lerp(t, pA.x, pB.x); - pFinal.y = utils.lerp(t, pA.y, pB.y); - - context.lineTo(pFinal.x, pFinal.y); - } - context.stroke(); - - context.beginPath(); - context.strokeStyle = "gray"; - context.moveTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.stroke(); - - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "red"; - context.beginPath(); - context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); - context.fill(); - context.fillStyle = "black"; - - - - // labelPointLeft(p0, "p0"); - // labelPointLeft(p1, "p1"); - // labelPointLeft(p2, "p2"); - // labelPoint(pA, "pA"); - // labelPoint(pB, "pB"); - labelT(); - - maxT += .1; - maxT = Math.min(t, 1); - - } - - function labelPoint(p, name) { - context.fillStyle = "black"; - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillStyle = "gray"; - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(maxT, 1), 200, 250); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 100, + y: 300 + }, + p2 = { + x: 1000, + y: 400 + }, + pA = {}, + pB = {}, + pFinal = {}, + t = 0, + maxT = 0; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + draw(); + + document.body.addEventListener("click", function() { + draw(); + }); + + function draw() { + context.clearRect(0, 0, width, height); + + context.strokeStyle = "#ccc"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.stroke(); + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + + context.strokeStyle = "red"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + + for(t = 0; t <= maxT; t += .1) { + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + pB.x = utils.lerp(t, p1.x, p2.x); + pB.y = utils.lerp(t, p1.y, p2.y); + + pFinal.x = utils.lerp(t, pA.x, pB.x); + pFinal.y = utils.lerp(t, pA.y, pB.y); + + context.lineTo(pFinal.x, pFinal.y); + } + context.stroke(); + + context.beginPath(); + context.strokeStyle = "gray"; + context.moveTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.stroke(); + + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "red"; + context.beginPath(); + context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); + context.fill(); + context.fillStyle = "black"; + + + + // labelPointLeft(p0, "p0"); + // labelPointLeft(p1, "p1"); + // labelPointLeft(p2, "p2"); + // labelPoint(pA, "pA"); + // labelPoint(pB, "pB"); + labelT(); + + maxT += .1; + maxT = Math.min(t, 1); + + } + + function labelPoint(p, name) { + context.fillStyle = "black"; + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillStyle = "gray"; + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(maxT, 1), 200, 250); + } + }; \ No newline at end of file diff --git a/episode19/demo5.js b/episode19/demo5.js index c9000cf..ac0993b 100644 --- a/episode19/demo5.js +++ b/episode19/demo5.js @@ -1,130 +1,130 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 600, - y: 200 - }, - p2 = { - x: 1000, - y: 400 - }, - pA = {}, - pB = {}, - pFinal = {}, - t = 0, - maxT = 0, - dir = 0.01; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - - context.strokeStyle = "#ccc"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.stroke(); - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - - context.strokeStyle = "red"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - - for(t = 0; t <= maxT; t += Math.abs(dir)) { - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - pB.x = utils.lerp(t, p1.x, p2.x); - pB.y = utils.lerp(t, p1.y, p2.y); - - pFinal.x = utils.lerp(t, pA.x, pB.x); - pFinal.y = utils.lerp(t, pA.y, pB.y); - - context.lineTo(pFinal.x, pFinal.y); - } - context.stroke(); - - context.beginPath(); - context.strokeStyle = "gray"; - context.moveTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.stroke(); - - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "red"; - context.beginPath(); - context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); - context.fill(); - context.fillStyle = "black"; - - - - // labelPointLeft(p0, "p0"); - // labelPointLeft(p1, "p1"); - // labelPointLeft(p2, "p2"); - // labelPoint(pA, "pA"); - // labelPoint(pB, "pB"); - labelT(); - - maxT += dir; - if(maxT >= 1) { - maxT = 1; - dir *= -1; - } - if(maxT <= 0) { - maxT = 0; - dir *= -1; - } - - requestAnimationFrame(draw); - } - - function labelPoint(p, name) { - context.fillStyle = "black"; - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillStyle = "gray"; - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(maxT, 2), 200, 250); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 600, + y: 200 + }, + p2 = { + x: 1000, + y: 400 + }, + pA = {}, + pB = {}, + pFinal = {}, + t = 0, + maxT = 0, + dir = 0.01; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + + context.strokeStyle = "#ccc"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.stroke(); + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + + context.strokeStyle = "red"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + + for(t = 0; t <= maxT; t += Math.abs(dir)) { + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + pB.x = utils.lerp(t, p1.x, p2.x); + pB.y = utils.lerp(t, p1.y, p2.y); + + pFinal.x = utils.lerp(t, pA.x, pB.x); + pFinal.y = utils.lerp(t, pA.y, pB.y); + + context.lineTo(pFinal.x, pFinal.y); + } + context.stroke(); + + context.beginPath(); + context.strokeStyle = "gray"; + context.moveTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.stroke(); + + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "red"; + context.beginPath(); + context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); + context.fill(); + context.fillStyle = "black"; + + + + // labelPointLeft(p0, "p0"); + // labelPointLeft(p1, "p1"); + // labelPointLeft(p2, "p2"); + // labelPoint(pA, "pA"); + // labelPoint(pB, "pB"); + labelT(); + + maxT += dir; + if(maxT >= 1) { + maxT = 1; + dir *= -1; + } + if(maxT <= 0) { + maxT = 0; + dir *= -1; + } + + requestAnimationFrame(draw); + } + + function labelPoint(p, name) { + context.fillStyle = "black"; + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillStyle = "gray"; + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(maxT, 2), 200, 250); + } + }; \ No newline at end of file diff --git a/episode19/demo6.js b/episode19/demo6.js index ab2d52d..00e4eb8 100644 --- a/episode19/demo6.js +++ b/episode19/demo6.js @@ -1,180 +1,180 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: 100, - y: 500 - }, - p1 = { - x: 400, - y: 200 - }, - p2 = { - x: 1000, - y: 400 - }, - p3 = { - x: 800, - y: 50 - }, - pA = {}, - pB = {}, - pC = {}, - pM = {}, - pN = {}, - pFinal = {}, - t = 0, - maxT = 0, - dir = 0.005, - animating = false;; - - context.scale(1.5, 1.5); - context.font = "16px Arial"; - - draw(); - document.body.addEventListener("click", function() { - animating = true; - draw(); - }); - - function draw() { - context.clearRect(0, 0, width, height); - - context.strokeStyle = "#ccc"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.lineTo(p3.x, p3.y); - context.stroke(); - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p3.x, p3.y, 4, 0, Math.PI * 2, false); - context.fill(); - - - context.strokeStyle = "red"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - - for(t = 0; t <= maxT; t += Math.abs(dir)) { - pA.x = utils.lerp(t, p0.x, p1.x); - pA.y = utils.lerp(t, p0.y, p1.y); - - pB.x = utils.lerp(t, p1.x, p2.x); - pB.y = utils.lerp(t, p1.y, p2.y); - - pC.x = utils.lerp(t, p2.x, p3.x); - pC.y = utils.lerp(t, p2.y, p3.y); - - pM.x = utils.lerp(t, pA.x, pB.x); - pM.y = utils.lerp(t, pA.y, pB.y); - - pN.x = utils.lerp(t, pB.x, pC.x); - pN.y = utils.lerp(t, pB.y, pC.y); - - pFinal.x = utils.lerp(t, pM.x, pN.x); - pFinal.y = utils.lerp(t, pM.y, pN.y); - - context.lineTo(pFinal.x, pFinal.y); - } - context.stroke(); - - context.beginPath(); - context.strokeStyle = "green"; - context.moveTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.lineTo(pC.x, pC.y); - context.stroke(); - - context.beginPath(); - context.strokeStyle = "blue"; - context.moveTo(pM.x, pM.y); - context.lineTo(pN.x, pN.y); - context.stroke(); - - context.fillStyle = "green"; - context.beginPath(); - context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pC.x, pC.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "blue"; - context.beginPath(); - context.arc(pM.x, pM.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(pN.x, pN.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "red"; - context.beginPath(); - context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.fillStyle = "black"; - - - - // labelPointLeft(p0, "p0"); - // labelPointLeft(p1, "p1"); - // labelPointLeft(p2, "p2"); - // labelPoint(pA, "pA"); - // labelPoint(pB, "pB"); - labelT(); - - maxT += dir; - if(maxT >= 1) { - maxT = 1; - dir *= -1; - } - if(maxT <= 0) { - maxT = 0; - dir *= -1; - } - - if(animating) - requestAnimationFrame(draw); - } - - function labelPoint(p, name) { - context.fillStyle = "black"; - context.fillText(name, p.x + 10, p.y + 10); - context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); - context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); - } - - function labelPointLeft(p, name) { - context.fillStyle = "gray"; - context.fillText(name, p.x - 40, p.y - 40); - context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); - context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); - } - - function labelT() { - context.fillText("t = " + utils.roundToPlaces(maxT, 2), 200, 250); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: 100, + y: 500 + }, + p1 = { + x: 400, + y: 200 + }, + p2 = { + x: 1000, + y: 400 + }, + p3 = { + x: 800, + y: 50 + }, + pA = {}, + pB = {}, + pC = {}, + pM = {}, + pN = {}, + pFinal = {}, + t = 0, + maxT = 0, + dir = 0.005, + animating = false;; + + context.scale(1.5, 1.5); + context.font = "16px Arial"; + + draw(); + document.body.addEventListener("click", function() { + animating = true; + draw(); + }); + + function draw() { + context.clearRect(0, 0, width, height); + + context.strokeStyle = "#ccc"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.lineTo(p3.x, p3.y); + context.stroke(); + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p3.x, p3.y, 4, 0, Math.PI * 2, false); + context.fill(); + + + context.strokeStyle = "red"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + + for(t = 0; t <= maxT; t += Math.abs(dir)) { + pA.x = utils.lerp(t, p0.x, p1.x); + pA.y = utils.lerp(t, p0.y, p1.y); + + pB.x = utils.lerp(t, p1.x, p2.x); + pB.y = utils.lerp(t, p1.y, p2.y); + + pC.x = utils.lerp(t, p2.x, p3.x); + pC.y = utils.lerp(t, p2.y, p3.y); + + pM.x = utils.lerp(t, pA.x, pB.x); + pM.y = utils.lerp(t, pA.y, pB.y); + + pN.x = utils.lerp(t, pB.x, pC.x); + pN.y = utils.lerp(t, pB.y, pC.y); + + pFinal.x = utils.lerp(t, pM.x, pN.x); + pFinal.y = utils.lerp(t, pM.y, pN.y); + + context.lineTo(pFinal.x, pFinal.y); + } + context.stroke(); + + context.beginPath(); + context.strokeStyle = "green"; + context.moveTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.lineTo(pC.x, pC.y); + context.stroke(); + + context.beginPath(); + context.strokeStyle = "blue"; + context.moveTo(pM.x, pM.y); + context.lineTo(pN.x, pN.y); + context.stroke(); + + context.fillStyle = "green"; + context.beginPath(); + context.arc(pA.x, pA.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pB.x, pB.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pC.x, pC.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "blue"; + context.beginPath(); + context.arc(pM.x, pM.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(pN.x, pN.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "red"; + context.beginPath(); + context.arc(pFinal.x, pFinal.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.fillStyle = "black"; + + + + // labelPointLeft(p0, "p0"); + // labelPointLeft(p1, "p1"); + // labelPointLeft(p2, "p2"); + // labelPoint(pA, "pA"); + // labelPoint(pB, "pB"); + labelT(); + + maxT += dir; + if(maxT >= 1) { + maxT = 1; + dir *= -1; + } + if(maxT <= 0) { + maxT = 0; + dir *= -1; + } + + if(animating) + requestAnimationFrame(draw); + } + + function labelPoint(p, name) { + context.fillStyle = "black"; + context.fillText(name, p.x + 10, p.y + 10); + context.fillText("x: " + Math.round(p.x), p.x + 10, p.y + 25); + context.fillText("y: " + Math.round(p.y), p.x + 10, p.y + 40); + } + + function labelPointLeft(p, name) { + context.fillStyle = "gray"; + context.fillText(name, p.x - 40, p.y - 40); + context.fillText("x: " + Math.round(p.x), p.x - 40, p.y - 25); + context.fillText("y: " + Math.round(p.y), p.x - 40, p.y - 10); + } + + function labelT() { + context.fillText("t = " + utils.roundToPlaces(maxT, 2), 200, 250); + } + }; \ No newline at end of file diff --git a/episode19/index.html b/episode19/index.html index ec278a5..30c3a9a 100644 --- a/episode19/index.html +++ b/episode19/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/episode19/main1.js b/episode19/main1.js index 7538236..4e63997 100644 --- a/episode19/main1.js +++ b/episode19/main1.js @@ -1,53 +1,53 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p1 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p2 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p3 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }; - - context.beginPath(); - context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.arc(p3.x, p3.y, 4, 0, Math.PI * 2, false); - context.fill(); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); - context.stroke(); - - var pFinal = {}; - - for(var t = 0; t <= 1; t += 0.01) { - utils.cubicBezier(p0, p1, p2, p3, t, pFinal); - context.beginPath(); - context.arc(pFinal.x, pFinal.y, 10, 0, Math.PI * 2, false); - context.stroke(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p1 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p2 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p3 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }; + + context.beginPath(); + context.arc(p0.x, p0.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p1.x, p1.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p2.x, p2.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.arc(p3.x, p3.y, 4, 0, Math.PI * 2, false); + context.fill(); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + context.stroke(); + + var pFinal = {}; + + for(var t = 0; t <= 1; t += 0.01) { + utils.cubicBezier(p0, p1, p2, p3, t, pFinal); + context.beginPath(); + context.arc(pFinal.x, pFinal.y, 10, 0, Math.PI * 2, false); + context.stroke(); + } + }; \ No newline at end of file diff --git a/episode19/main2.js b/episode19/main2.js index c794624..0eb8097 100644 --- a/episode19/main2.js +++ b/episode19/main2.js @@ -1,44 +1,44 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p1 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p2 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p3 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - maxT = 0, - pFinal = {}; - - - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - context.beginPath(); - context.moveTo(p0.x, p0.y); - for(var t = 0; t <= maxT; t += 0.01) { - utils.cubicBezier(p0, p1, p2, p3, t, pFinal); - context.lineTo(pFinal.x, pFinal.y); - } - context.stroke(); - maxT += 0.01; - if(maxT > 1) { - maxT = 0; - } - - requestAnimationFrame(draw); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p1 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p2 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p3 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + maxT = 0, + pFinal = {}; + + + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + context.beginPath(); + context.moveTo(p0.x, p0.y); + for(var t = 0; t <= maxT; t += 0.01) { + utils.cubicBezier(p0, p1, p2, p3, t, pFinal); + context.lineTo(pFinal.x, pFinal.y); + } + context.stroke(); + maxT += 0.01; + if(maxT > 1) { + maxT = 0; + } + + requestAnimationFrame(draw); + } }; \ No newline at end of file diff --git a/episode19/main3.js b/episode19/main3.js index da0e8a9..33c7ecf 100644 --- a/episode19/main3.js +++ b/episode19/main3.js @@ -1,49 +1,49 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p1 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p2 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - p3 = { - x: utils.randomRange(0, width), - y: utils.randomRange(0, height) - }, - t = 0, - direction = 0.01, - pFinal = {}; - - - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); - context.stroke(); - - utils.cubicBezier(p0, p1, p2, p3, t, pFinal); - context.beginPath(); - context.arc(pFinal.x, pFinal.y, 10, 0, Math.PI * 2, false); - context.fill(); - - t += direction; - if(t > 1 || t < 0) { - direction = -direction; - } - - requestAnimationFrame(draw); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p1 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p2 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + p3 = { + x: utils.randomRange(0, width), + y: utils.randomRange(0, height) + }, + t = 0, + direction = 0.01, + pFinal = {}; + + + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + context.stroke(); + + utils.cubicBezier(p0, p1, p2, p3, t, pFinal); + context.beginPath(); + context.arc(pFinal.x, pFinal.y, 10, 0, Math.PI * 2, false); + context.fill(); + + t += direction; + if(t > 1 || t < 0) { + direction = -direction; + } + + requestAnimationFrame(draw); + } }; \ No newline at end of file diff --git a/episode19/utils.js b/episode19/utils.js index 7c659e4..25aa5da 100644 --- a/episode19/utils.js +++ b/episode19/utils.js @@ -1,106 +1,106 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + } + } \ No newline at end of file diff --git a/episode2/index.html b/episode2/index.html index 157f160..8c1aafb 100644 --- a/episode2/index.html +++ b/episode2/index.html @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode2/trig01.js b/episode2/trig01.js index 52ddad6..296d191 100644 --- a/episode2/trig01.js +++ b/episode2/trig01.js @@ -1,21 +1,21 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - context.translate(0, height / 2); - context.scale(1, -1); - - for(var angle = 0; angle < Math.PI * 2; angle += .01) { - var x = angle * 200, - y = Math.sin(angle) * 200; - - context.fillStyle = "black"; - context.fillRect(x, y, 5, 5); - - y = Math.cos(angle) * 200; - context.fillStyle = "red"; - context.fillRect(x, y, 5, 5); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + context.translate(0, height / 2); + context.scale(1, -1); + + for(var angle = 0; angle < Math.PI * 2; angle += .01) { + var x = angle * 200, + y = Math.sin(angle) * 200; + + context.fillStyle = "black"; + context.fillRect(x, y, 5, 5); + + y = Math.cos(angle) * 200; + context.fillStyle = "red"; + context.fillRect(x, y, 5, 5); + } }; \ No newline at end of file diff --git a/episode20/index.html b/episode20/index.html index ec278a5..30c3a9a 100644 --- a/episode20/index.html +++ b/episode20/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/episode20/main1.js b/episode20/main1.js index 044e788..2a0a17c 100644 --- a/episode20/main1.js +++ b/episode20/main1.js @@ -1,46 +1,46 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: Math.random() * width, - y: Math.random() * height - }, - p1 = { - x: Math.random() * width, - y: Math.random() * height - }, - p2 = { - x: Math.random() * width, - y: Math.random() * height - }, - cp = {}; - - cp.x = p1.x * 2 - (p0.x + p2.x) / 2; - cp.y = p1.y * 2 - (p0.y + p2.y) / 2; - - drawPoint(p0); - drawPoint(p1); - drawPoint(p2); - drawPoint(cp); - - context.strokeStyle = "lightgray"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(cp.x, cp.y); - context.lineTo(p2.x, p2.y); - context.stroke(); - - context.strokeStyle = "black"; - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.quadraticCurveTo(cp.x, cp.y, p2.x, p2.y); - context.stroke(); - - function drawPoint(p) { - context.beginPath(); - context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); - context.fill(); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: Math.random() * width, + y: Math.random() * height + }, + p1 = { + x: Math.random() * width, + y: Math.random() * height + }, + p2 = { + x: Math.random() * width, + y: Math.random() * height + }, + cp = {}; + + cp.x = p1.x * 2 - (p0.x + p2.x) / 2; + cp.y = p1.y * 2 - (p0.y + p2.y) / 2; + + drawPoint(p0); + drawPoint(p1); + drawPoint(p2); + drawPoint(cp); + + context.strokeStyle = "lightgray"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(cp.x, cp.y); + context.lineTo(p2.x, p2.y); + context.stroke(); + + context.strokeStyle = "black"; + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.quadraticCurveTo(cp.x, cp.y, p2.x, p2.y); + context.stroke(); + + function drawPoint(p) { + context.beginPath(); + context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); + context.fill(); + } }; \ No newline at end of file diff --git a/episode20/main2.js b/episode20/main2.js index 9d2c7bc..c5031ab 100644 --- a/episode20/main2.js +++ b/episode20/main2.js @@ -1,36 +1,36 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - points = [], - numPoints = 10; - - for(var i = 0; i < numPoints; i += 1) { - var p = { - x: Math.random() * width, - y: Math.random() * height - }; - - context.beginPath(); - context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); - context.fill(); - - points.push(p); - } - - context.strokeStyle = "lightgray"; - context.beginPath(); - context.moveTo(points[0].x, points[0].y); - for(var i = 1; i < numPoints; i += 1) { - context.lineTo(points[i].x, points[i].y); - } - context.stroke(); - - context.strokeStyle = "black"; - - context.beginPath(); - utils.multicurve(points, context); - context.stroke(); - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + points = [], + numPoints = 10; + + for(var i = 0; i < numPoints; i += 1) { + var p = { + x: Math.random() * width, + y: Math.random() * height + }; + + context.beginPath(); + context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); + context.fill(); + + points.push(p); + } + + context.strokeStyle = "lightgray"; + context.beginPath(); + context.moveTo(points[0].x, points[0].y); + for(var i = 1; i < numPoints; i += 1) { + context.lineTo(points[i].x, points[i].y); + } + context.stroke(); + + context.strokeStyle = "black"; + + context.beginPath(); + utils.multicurve(points, context); + context.stroke(); + }; \ No newline at end of file diff --git a/episode20/main3.js b/episode20/main3.js index 68347c9..fd2b2a6 100644 --- a/episode20/main3.js +++ b/episode20/main3.js @@ -1,33 +1,33 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p0 = { - x: Math.random() * width, - y: Math.random() * height - }, - p1 = { - x: Math.random() * width, - y: Math.random() * height - }, - p2 = { - x: Math.random() * width, - y: Math.random() * height - }, - p3 = { - x: Math.random() * width, - y: Math.random() * height - }; - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); - context.stroke(); - - context.strokeStyle = "red"; - context.beginPath(); - utils.multicurve([p0, p1, p2, p3], context); - context.stroke(); - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p0 = { + x: Math.random() * width, + y: Math.random() * height + }, + p1 = { + x: Math.random() * width, + y: Math.random() * height + }, + p2 = { + x: Math.random() * width, + y: Math.random() * height + }, + p3 = { + x: Math.random() * width, + y: Math.random() * height + }; + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + context.stroke(); + + context.strokeStyle = "red"; + context.beginPath(); + utils.multicurve([p0, p1, p2, p3], context); + context.stroke(); + }; \ No newline at end of file diff --git a/episode20/utils.js b/episode20/utils.js index 3c0f824..04715df 100644 --- a/episode20/utils.js +++ b/episode20/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode21/index.html b/episode21/index.html index 5a12f32..570ae0b 100644 --- a/episode21/index.html +++ b/episode21/index.html @@ -1,27 +1,27 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/episode21/main.js b/episode21/main.js index aac23c0..7c879c7 100644 --- a/episode21/main.js +++ b/episode21/main.js @@ -1,46 +1,46 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - targetCanvas = document.getElementById("target"), - targetContext = targetCanvas.getContext("2d"), - width = canvas.width = targetCanvas.width = window.innerWidth, - height = canvas.height = targetCanvas.height = window.innerHeight, - p = particle.create(0, height / 2, 10, 0); - - targetContext.beginPath(); - targetContext.arc(width / 2, height / 2, 200, 0, Math.PI * 2, false); - targetContext.fill(); - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - p.update(); - context.beginPath(); - context.arc(p.x, p.y, 4, 0, Math.PI * 2, false); - context.fill(); - - var imageData = targetContext.getImageData(p.x, p.y, 1, 1); - if(imageData.data[3] > 0) { - targetContext.globalCompositeOperation = "destination-out"; - targetContext.beginPath(); - targetContext.arc(p.x, p.y, 20, 0, Math.PI * 2, false); - targetContext.fill(); - - resetParticle(); - } - else if(p.x > width) { - resetParticle(); - } - requestAnimationFrame(update); - } - - function resetParticle() { - p.x = 0; - p.y = height / 2; - p.setHeading(utils.randomRange(-0.1, 0.1)); - } - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + targetCanvas = document.getElementById("target"), + targetContext = targetCanvas.getContext("2d"), + width = canvas.width = targetCanvas.width = window.innerWidth, + height = canvas.height = targetCanvas.height = window.innerHeight, + p = particle.create(0, height / 2, 10, 0); + + targetContext.beginPath(); + targetContext.arc(width / 2, height / 2, 200, 0, Math.PI * 2, false); + targetContext.fill(); + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + p.update(); + context.beginPath(); + context.arc(p.x, p.y, 4, 0, Math.PI * 2, false); + context.fill(); + + var imageData = targetContext.getImageData(p.x, p.y, 1, 1); + if(imageData.data[3] > 0) { + targetContext.globalCompositeOperation = "destination-out"; + targetContext.beginPath(); + targetContext.arc(p.x, p.y, 20, 0, Math.PI * 2, false); + targetContext.fill(); + + resetParticle(); + } + else if(p.x > width) { + resetParticle(); + } + requestAnimationFrame(update); + } + + function resetParticle() { + p.x = 0; + p.y = height / 2; + p.setHeading(utils.randomRange(-0.1, 0.1)); + } + + }; \ No newline at end of file diff --git a/episode21/particle.js b/episode21/particle.js index b6ef621..948e47a 100644 --- a/episode21/particle.js +++ b/episode21/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/episode21/utils.js b/episode21/utils.js index 3c0f824..04715df 100644 --- a/episode21/utils.js +++ b/episode21/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode22/index.html b/episode22/index.html index 3723d24..f8d8212 100644 --- a/episode22/index.html +++ b/episode22/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode22/main.js b/episode22/main.js index b53403f..c040ba8 100644 --- a/episode22/main.js +++ b/episode22/main.js @@ -1,22 +1,22 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - shapePos = { - x: 500, - y: 300, - z: 10000 - }; - - context.translate(width / 2, height / 2); - - var perspective = fl / (fl + shapePos.z); - context.translate(shapePos.x * perspective, shapePos.y * perspective); - context.scale(perspective, perspective); - context.fillRect(-100, -100, 200, 200); - - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + shapePos = { + x: 500, + y: 300, + z: 10000 + }; + + context.translate(width / 2, height / 2); + + var perspective = fl / (fl + shapePos.z); + context.translate(shapePos.x * perspective, shapePos.y * perspective); + context.scale(perspective, perspective); + context.fillRect(-100, -100, 200, 200); + + + }; \ No newline at end of file diff --git a/episode22/main2.js b/episode22/main2.js index 61c9d28..3f6ef2e 100644 --- a/episode22/main2.js +++ b/episode22/main2.js @@ -1,60 +1,60 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - shapes = [], - numShapes = 100; - - for(var i = 0; i < numShapes; i += 1) { - shapes[i] = { - x: utils.randomRange(-1000, 1000), - y: utils.randomRange(-1000, 1000), - z: utils.randomRange(0, 10000), - char: String.fromCharCode(utils.randomRange(65, 91)) - }; - } - - context.translate(width / 2, height / 2); - context.font = "200px Arial"; - - update(); - - function update() { - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numShapes; i += 1) { - var shape = shapes[i], - perspective = fl / (fl + shape.z); - - context.save(); - context.translate(shape.x * perspective, shape.y * perspective); - context.scale(perspective, perspective); - // square: - // context.fillRect(-100, -100, 200, 200); - - // circle: - // context.beginPath(); - // context.arc(0, 0, 100, 0, Math.PI * 2, false); - // context.fill(); - - // letter: - context.fillText(shape.char, -100, -100) - - context.restore(); - - // move away: - // shape.z += 5; - // if(shape.z > 10000) { - // shape.z = 0; - // } - - // move toward: - shape.z -= 5; - if(shape.z < 0) { - shape.z = 10000; - } - } - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + shapes = [], + numShapes = 100; + + for(var i = 0; i < numShapes; i += 1) { + shapes[i] = { + x: utils.randomRange(-1000, 1000), + y: utils.randomRange(-1000, 1000), + z: utils.randomRange(0, 10000), + char: String.fromCharCode(utils.randomRange(65, 91)) + }; + } + + context.translate(width / 2, height / 2); + context.font = "200px Arial"; + + update(); + + function update() { + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numShapes; i += 1) { + var shape = shapes[i], + perspective = fl / (fl + shape.z); + + context.save(); + context.translate(shape.x * perspective, shape.y * perspective); + context.scale(perspective, perspective); + // square: + // context.fillRect(-100, -100, 200, 200); + + // circle: + // context.beginPath(); + // context.arc(0, 0, 100, 0, Math.PI * 2, false); + // context.fill(); + + // letter: + context.fillText(shape.char, -100, -100) + + context.restore(); + + // move away: + // shape.z += 5; + // if(shape.z > 10000) { + // shape.z = 0; + // } + + // move toward: + shape.z -= 5; + if(shape.z < 0) { + shape.z = 10000; + } + } + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode22/particle.js b/episode22/particle.js index b6ef621..948e47a 100644 --- a/episode22/particle.js +++ b/episode22/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/episode22/postcards.js b/episode22/postcards.js index cea41ca..08166c8 100644 --- a/episode22/postcards.js +++ b/episode22/postcards.js @@ -1,48 +1,48 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - cards = [], - numCards = 21; - - for(var i = 0; i < numCards; i += 1) { - var card = { - x: utils.randomRange(-1000, 1000), - y: utils.randomRange(-1000, 1000), - z: utils.randomRange(0, 5000), - img: document.createElement("img") - }; - card.img.src = "postcard" + (i % 7) + ".jpg"; - cards.push(card); - } - - context.translate(width / 2, height / 2); - context.font = "200px Arial"; - - update(); - - function update() { - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numCards; i += 1) { - var card = cards[i], - perspective = fl / (fl + card.z); - - context.save(); - context.translate(card.x * perspective, card.y * perspective); - context.scale(perspective, perspective); - - context.translate(-card.img.width / 2, -card.img.height / 2); - context.drawImage(card.img, 0, 0); - - context.restore(); - - card.z -= 5; - if(card.z < 0) { - card.z = 5000; - } - } - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + cards = [], + numCards = 21; + + for(var i = 0; i < numCards; i += 1) { + var card = { + x: utils.randomRange(-1000, 1000), + y: utils.randomRange(-1000, 1000), + z: utils.randomRange(0, 5000), + img: document.createElement("img") + }; + card.img.src = "postcard" + (i % 7) + ".jpg"; + cards.push(card); + } + + context.translate(width / 2, height / 2); + context.font = "200px Arial"; + + update(); + + function update() { + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numCards; i += 1) { + var card = cards[i], + perspective = fl / (fl + card.z); + + context.save(); + context.translate(card.x * perspective, card.y * perspective); + context.scale(perspective, perspective); + + context.translate(-card.img.width / 2, -card.img.height / 2); + context.drawImage(card.img, 0, 0); + + context.restore(); + + card.z -= 5; + if(card.z < 0) { + card.z = 5000; + } + } + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode22/stars.js b/episode22/stars.js index 3d8b16f..8751810 100644 --- a/episode22/stars.js +++ b/episode22/stars.js @@ -1,20 +1,20 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - context.fillRect(0, 0, width, height); - context.fillStyle = "white"; - - for(var i = 0; i < 800; i += 1) { - context.beginPath(); - context.arc(utils.randomRange(0, width), - utils.randomRange(0, height), - utils.randomRange(0, 1), - 0, Math.PI * 2, false); - context.fill(); - } - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + context.fillRect(0, 0, width, height); + context.fillStyle = "white"; + + for(var i = 0; i < 800; i += 1) { + context.beginPath(); + context.arc(utils.randomRange(0, width), + utils.randomRange(0, height), + utils.randomRange(0, 1), + 0, Math.PI * 2, false); + context.fill(); + } + + }; \ No newline at end of file diff --git a/episode22/utils.js b/episode22/utils.js index 3c0f824..04715df 100644 --- a/episode22/utils.js +++ b/episode22/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode23/final.js b/episode23/final.js index 4544081..f552c04 100644 --- a/episode23/final.js +++ b/episode23/final.js @@ -1,68 +1,68 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - cards = [], - numCards = 200, - centerZ = 1000, - baseAngle = 0, - rotationSpeed = 0.01; - - - for(var i = 0; i < numCards; i += 1) { - var card = { - angle: utils.randomRange(0, Math.PI * 2), - radius: utils.randomRange(100, 1100), - y: utils.randomRange(2000, -2000) - }; - card.x = Math.cos(card.angle + baseAngle) * card.radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * card.radius; - cards.push(card); - } - - context.translate(width / 2, height / 2); - context.fillStyle = "white"; - - document.body.addEventListener("mousemove", function(event) { - rotationSpeed = (event.clientX - width / 2) * 0.00005; - ypos = (event.clientY - height / 2) * 2; - }); - - update(); - - function update() { - baseAngle += rotationSpeed; - cards.sort(zsort); - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numCards; i += 1) { - var card = cards[i], - perspective = fl / (fl + card.z); - - context.save(); - context.scale(perspective, perspective); - context.translate(card.x, card.y); - context.globalAlpha = utils.map(card.y, 2000, -2000, 1, 0); - - context.beginPath(); - context.arc(0, 0, 40, 0, Math.PI * 2, false); - context.fill(); - - context.restore(); - - card.x = Math.cos(card.angle + baseAngle) * card.radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * card.radius; - card.y -= 10; - - if(card.y < -2000) { - card.y = 2000; - } - } - requestAnimationFrame(update); - } - - function zsort(cardA, cardB) { - return cardB.z - cardA.z; - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + cards = [], + numCards = 200, + centerZ = 1000, + baseAngle = 0, + rotationSpeed = 0.01; + + + for(var i = 0; i < numCards; i += 1) { + var card = { + angle: utils.randomRange(0, Math.PI * 2), + radius: utils.randomRange(100, 1100), + y: utils.randomRange(2000, -2000) + }; + card.x = Math.cos(card.angle + baseAngle) * card.radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * card.radius; + cards.push(card); + } + + context.translate(width / 2, height / 2); + context.fillStyle = "white"; + + document.body.addEventListener("mousemove", function(event) { + rotationSpeed = (event.clientX - width / 2) * 0.00005; + ypos = (event.clientY - height / 2) * 2; + }); + + update(); + + function update() { + baseAngle += rotationSpeed; + cards.sort(zsort); + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numCards; i += 1) { + var card = cards[i], + perspective = fl / (fl + card.z); + + context.save(); + context.scale(perspective, perspective); + context.translate(card.x, card.y); + context.globalAlpha = utils.map(card.y, 2000, -2000, 1, 0); + + context.beginPath(); + context.arc(0, 0, 40, 0, Math.PI * 2, false); + context.fill(); + + context.restore(); + + card.x = Math.cos(card.angle + baseAngle) * card.radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * card.radius; + card.y -= 10; + + if(card.y < -2000) { + card.y = 2000; + } + } + requestAnimationFrame(update); + } + + function zsort(cardA, cardB) { + return cardB.z - cardA.z; + } }; \ No newline at end of file diff --git a/episode23/index.html b/episode23/index.html index 1fdfdf9..71cd261 100644 --- a/episode23/index.html +++ b/episode23/index.html @@ -1,24 +1,24 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode23/particle.js b/episode23/particle.js index b6ef621..948e47a 100644 --- a/episode23/particle.js +++ b/episode23/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/episode23/postcards.js b/episode23/postcards.js index 827465d..9285644 100644 --- a/episode23/postcards.js +++ b/episode23/postcards.js @@ -1,61 +1,61 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - cards = [], - numCards = 7, - centerZ = 1000, - radius = 1000, - baseAngle = 0, - rotationSpeed = 0.01; - - for(var i = 0; i < numCards; i += 1) { - var card = { - y: 0, - angle: Math.PI * 2 / numCards * i, - img: document.createElement("img") - }; - card.img.src = "postcard" + i + ".jpg"; - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - cards.push(card); - } - - context.translate(width / 2, height / 2); - context.font = "200px Arial"; - - document.body.addEventListener("mousemove", function(event) { - rotationSpeed = (event.clientX - width / 2) * 0.00005; - }); - - update(); - - function update() { - baseAngle += rotationSpeed; - cards.sort(zsort); - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numCards; i += 1) { - var card = cards[i], - perspective = fl / (fl + card.z); - - context.save(); - context.scale(perspective, perspective); - context.translate(card.x, card.y); - - context.translate(-card.img.width / 2, -card.img.height / 2); - context.drawImage(card.img, 0, 0); - - context.restore(); - - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - } - requestAnimationFrame(update); - } - - function zsort(cardA, cardB) { - return cardB.z - cardA.z; - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + cards = [], + numCards = 7, + centerZ = 1000, + radius = 1000, + baseAngle = 0, + rotationSpeed = 0.01; + + for(var i = 0; i < numCards; i += 1) { + var card = { + y: 0, + angle: Math.PI * 2 / numCards * i, + img: document.createElement("img") + }; + card.img.src = "postcard" + i + ".jpg"; + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + cards.push(card); + } + + context.translate(width / 2, height / 2); + context.font = "200px Arial"; + + document.body.addEventListener("mousemove", function(event) { + rotationSpeed = (event.clientX - width / 2) * 0.00005; + }); + + update(); + + function update() { + baseAngle += rotationSpeed; + cards.sort(zsort); + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numCards; i += 1) { + var card = cards[i], + perspective = fl / (fl + card.z); + + context.save(); + context.scale(perspective, perspective); + context.translate(card.x, card.y); + + context.translate(-card.img.width / 2, -card.img.height / 2); + context.drawImage(card.img, 0, 0); + + context.restore(); + + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + } + requestAnimationFrame(update); + } + + function zsort(cardA, cardB) { + return cardB.z - cardA.z; + } }; \ No newline at end of file diff --git a/episode23/spiral.js b/episode23/spiral.js index acd9ebe..1800bd2 100644 --- a/episode23/spiral.js +++ b/episode23/spiral.js @@ -1,63 +1,63 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - cards = [], - numCards = 200, - centerZ = 2000, - radius = 1000, - baseAngle = 0, - rotationSpeed = 0.01; - - - for(var i = 0; i < numCards; i += 1) { - var card = { - angle: 0.2 * i, - y: 2000 - 4000 / numCards * i, - img: document.createElement("img") - }; - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - cards.push(card); - } - - context.translate(width / 2, height / 2); - context.font = "200px Arial"; - - document.body.addEventListener("mousemove", function(event) { - rotationSpeed = (event.clientX - width / 2) * 0.00005; - ypos = (event.clientY - height / 2) * 2; - }); - - update(); - - function update() { - baseAngle += rotationSpeed; - cards.sort(zsort); - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numCards; i += 1) { - var card = cards[i], - perspective = fl / (fl + card.z); - - context.save(); - context.scale(perspective, perspective); - context.translate(card.x, card.y); - - context.beginPath(); - context.arc(0, 0, 40, 0, Math.PI * 2, false); - context.fill(); - - context.restore(); - - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - } - requestAnimationFrame(update); - } - - function zsort(cardA, cardB) { - return cardB.z - cardA.z; - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + cards = [], + numCards = 200, + centerZ = 2000, + radius = 1000, + baseAngle = 0, + rotationSpeed = 0.01; + + + for(var i = 0; i < numCards; i += 1) { + var card = { + angle: 0.2 * i, + y: 2000 - 4000 / numCards * i, + img: document.createElement("img") + }; + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + cards.push(card); + } + + context.translate(width / 2, height / 2); + context.font = "200px Arial"; + + document.body.addEventListener("mousemove", function(event) { + rotationSpeed = (event.clientX - width / 2) * 0.00005; + ypos = (event.clientY - height / 2) * 2; + }); + + update(); + + function update() { + baseAngle += rotationSpeed; + cards.sort(zsort); + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numCards; i += 1) { + var card = cards[i], + perspective = fl / (fl + card.z); + + context.save(); + context.scale(perspective, perspective); + context.translate(card.x, card.y); + + context.beginPath(); + context.arc(0, 0, 40, 0, Math.PI * 2, false); + context.fill(); + + context.restore(); + + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + } + requestAnimationFrame(update); + } + + function zsort(cardA, cardB) { + return cardB.z - cardA.z; + } }; \ No newline at end of file diff --git a/episode23/stars.js b/episode23/stars.js index 0de703a..89b76f5 100644 --- a/episode23/stars.js +++ b/episode23/stars.js @@ -1,64 +1,64 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - cards = [], - numCards = 20, - centerZ = 1000, - ypos = 0, - radius = 1000, - baseAngle = 0, - rotationSpeed = 0.01, - star = document.createElement("img"); - - star.src = "star.png" - - for(var i = 0; i < numCards; i += 1) { - var card = { - angle: Math.PI * 2 / numCards * i, - img: document.createElement("img") - }; - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - cards.push(card); - } - - context.translate(width / 2, height / 2); - context.font = "200px Arial"; - - document.body.addEventListener("mousemove", function(event) { - rotationSpeed = (event.clientX - width / 2) * 0.00005; - ypos = (event.clientY - height / 2) * 2; - }); - - update(); - - function update() { - baseAngle += rotationSpeed; - cards.sort(zsort); - context.clearRect(-width / 2, -height / 2, width, height); - for(var i = 0; i < numCards; i += 1) { - var card = cards[i], - perspective = fl / (fl + card.z); - - context.save(); - context.scale(perspective, perspective); - context.translate(card.x, ypos); - - context.translate(-card.img.width / 2, -card.img.height / 2); - context.drawImage(star, 0, 0); - - context.restore(); - - card.x = Math.cos(card.angle + baseAngle) * radius; - card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; - } - requestAnimationFrame(update); - } - - function zsort(cardA, cardB) { - return cardB.z - cardA.z; - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + cards = [], + numCards = 20, + centerZ = 1000, + ypos = 0, + radius = 1000, + baseAngle = 0, + rotationSpeed = 0.01, + star = document.createElement("img"); + + star.src = "star.png" + + for(var i = 0; i < numCards; i += 1) { + var card = { + angle: Math.PI * 2 / numCards * i, + img: document.createElement("img") + }; + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + cards.push(card); + } + + context.translate(width / 2, height / 2); + context.font = "200px Arial"; + + document.body.addEventListener("mousemove", function(event) { + rotationSpeed = (event.clientX - width / 2) * 0.00005; + ypos = (event.clientY - height / 2) * 2; + }); + + update(); + + function update() { + baseAngle += rotationSpeed; + cards.sort(zsort); + context.clearRect(-width / 2, -height / 2, width, height); + for(var i = 0; i < numCards; i += 1) { + var card = cards[i], + perspective = fl / (fl + card.z); + + context.save(); + context.scale(perspective, perspective); + context.translate(card.x, ypos); + + context.translate(-card.img.width / 2, -card.img.height / 2); + context.drawImage(star, 0, 0); + + context.restore(); + + card.x = Math.cos(card.angle + baseAngle) * radius; + card.z = centerZ + Math.sin(card.angle + baseAngle) * radius; + } + requestAnimationFrame(update); + } + + function zsort(cardA, cardB) { + return cardB.z - cardA.z; + } }; \ No newline at end of file diff --git a/episode23/utils.js b/episode23/utils.js index 3c0f824..04715df 100644 --- a/episode23/utils.js +++ b/episode23/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode24/index.html b/episode24/index.html index e9da3d3..d9672be 100644 --- a/episode24/index.html +++ b/episode24/index.html @@ -1,24 +1,24 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode24/particle.js b/episode24/particle.js index b6ef621..948e47a 100644 --- a/episode24/particle.js +++ b/episode24/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/episode24/spiral.js b/episode24/spiral.js index cc64d83..d602b29 100644 --- a/episode24/spiral.js +++ b/episode24/spiral.js @@ -1,63 +1,63 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - fl = 300, - points = [], - numPoints = 200, - centerZ = 2000, - radius = 1000, - baseAngle = 0, - rotationSpeed = 0.01; - - - for(var i = 0; i < numPoints; i += 1) { - var point = { - angle: 0.2 * i, - y: 2000 - 4000 / numPoints * i + Math.random() * 500 - }; - point.x = Math.cos(point.angle + baseAngle) * radius; - point.z = centerZ + Math.sin(point.angle + baseAngle) * radius; - points.push(point); - } - - context.translate(width / 2, height / 2); - - document.body.addEventListener("mousemove", function(event) { - rotationSpeed = (event.clientX - width / 2) * 0.00005; - ypos = (event.clientY - height / 2) * 2; - }); - - update(); - - function update() { - baseAngle += rotationSpeed; - context.clearRect(-width / 2, -height / 2, width, height); - - context.beginPath(); - for(var i = 0; i < numPoints; i += 1) { - var point = points[i], - perspective = fl / (fl + point.z); - - context.save(); - context.scale(perspective, perspective); - context.translate(point.x, point.y); - - if(i == 0) { - context.moveTo(0, 0); - } - else { - context.lineTo(0, 0); - } - - context.restore(); - - point.x = Math.cos(point.angle + baseAngle) * radius; - point.z = centerZ + Math.sin(point.angle + baseAngle) * radius; - } - context.stroke(); - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + fl = 300, + points = [], + numPoints = 200, + centerZ = 2000, + radius = 1000, + baseAngle = 0, + rotationSpeed = 0.01; + + + for(var i = 0; i < numPoints; i += 1) { + var point = { + angle: 0.2 * i, + y: 2000 - 4000 / numPoints * i + Math.random() * 500 + }; + point.x = Math.cos(point.angle + baseAngle) * radius; + point.z = centerZ + Math.sin(point.angle + baseAngle) * radius; + points.push(point); + } + + context.translate(width / 2, height / 2); + + document.body.addEventListener("mousemove", function(event) { + rotationSpeed = (event.clientX - width / 2) * 0.00005; + ypos = (event.clientY - height / 2) * 2; + }); + + update(); + + function update() { + baseAngle += rotationSpeed; + context.clearRect(-width / 2, -height / 2, width, height); + + context.beginPath(); + for(var i = 0; i < numPoints; i += 1) { + var point = points[i], + perspective = fl / (fl + point.z); + + context.save(); + context.scale(perspective, perspective); + context.translate(point.x, point.y); + + if(i == 0) { + context.moveTo(0, 0); + } + else { + context.lineTo(0, 0); + } + + context.restore(); + + point.x = Math.cos(point.angle + baseAngle) * radius; + point.z = centerZ + Math.sin(point.angle + baseAngle) * radius; + } + context.stroke(); + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode24/utils.js b/episode24/utils.js index 3c0f824..04715df 100644 --- a/episode24/utils.js +++ b/episode24/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode25/index.html b/episode25/index.html index cee28ae..738796d 100644 --- a/episode25/index.html +++ b/episode25/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode25/main.js b/episode25/main.js index fc42656..3b5ff2a 100644 --- a/episode25/main.js +++ b/episode25/main.js @@ -1,97 +1,97 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight - fl = 300, - points = [], - needsUpdate = true; - - context.translate(width / 2, height / 2); - - points[0] = { x: -500, y: -500, z: 1000 }; - points[1] = { x: 500, y: -500, z: 1000 }; - points[2] = { x: 500, y: -500, z: 500 }; - points[3] = { x: -500, y: -500, z: 500 }; - points[4] = { x: -500, y: 500, z: 1000 }; - points[5] = { x: 500, y: 500, z: 1000 }; - points[6] = { x: 500, y: 500, z: 500 }; - points[7] = { x: -500, y: 500, z: 500 }; - - function project() { - for(var i = 0; i < points.length; i++) { - var p = points[i], - scale = fl / (fl + p.z); - - p.sx = p.x * scale; - p.sy = p.y * scale; - } - } - - function drawLine() { - var p = points[arguments[0]]; - context.moveTo(p.sx, p.sy); - - for(var i = 1; i < arguments.length; i++) { - p = points[arguments[i]]; - context.lineTo(p.sx, p.sy); - } - } - - function translateModel(x, y, z) { - for(var i = 0; i < points.length; i++) { - points[i].x += x; - points[i].y += y; - points[i].z += z; - } - needsUpdate = true; - } - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 37: // left - translateModel(-20, 0, 0); - break; - case 39: // right - translateModel(20, 0, 0); - break; - case 38: // up - if(event.shiftKey) { - translateModel(0, 0, 20); - } - else { - translateModel(0, -20, 0); - } - break; - case 40: // down - if(event.shiftKey) { - translateModel(0, 0, -20); - } - else { - translateModel(0, 20, 0); - } - break; - } - }); - - update(); - - function update() { - if(needsUpdate) { - context.clearRect(-width / 2, -height / 2, width, height); - project(); - - context.beginPath(); - drawLine(0, 1, 2, 3, 0); - drawLine(4, 5, 6, 7, 4); - drawLine(0, 4); - drawLine(1, 5); - drawLine(2, 6); - drawLine(3, 7); - context.stroke(); - needsUpdate = false; - } - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight + fl = 300, + points = [], + needsUpdate = true; + + context.translate(width / 2, height / 2); + + points[0] = { x: -500, y: -500, z: 1000 }; + points[1] = { x: 500, y: -500, z: 1000 }; + points[2] = { x: 500, y: -500, z: 500 }; + points[3] = { x: -500, y: -500, z: 500 }; + points[4] = { x: -500, y: 500, z: 1000 }; + points[5] = { x: 500, y: 500, z: 1000 }; + points[6] = { x: 500, y: 500, z: 500 }; + points[7] = { x: -500, y: 500, z: 500 }; + + function project() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + scale = fl / (fl + p.z); + + p.sx = p.x * scale; + p.sy = p.y * scale; + } + } + + function drawLine() { + var p = points[arguments[0]]; + context.moveTo(p.sx, p.sy); + + for(var i = 1; i < arguments.length; i++) { + p = points[arguments[i]]; + context.lineTo(p.sx, p.sy); + } + } + + function translateModel(x, y, z) { + for(var i = 0; i < points.length; i++) { + points[i].x += x; + points[i].y += y; + points[i].z += z; + } + needsUpdate = true; + } + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 37: // left + translateModel(-20, 0, 0); + break; + case 39: // right + translateModel(20, 0, 0); + break; + case 38: // up + if(event.shiftKey) { + translateModel(0, 0, 20); + } + else { + translateModel(0, -20, 0); + } + break; + case 40: // down + if(event.shiftKey) { + translateModel(0, 0, -20); + } + else { + translateModel(0, 20, 0); + } + break; + } + }); + + update(); + + function update() { + if(needsUpdate) { + context.clearRect(-width / 2, -height / 2, width, height); + project(); + + context.beginPath(); + drawLine(0, 1, 2, 3, 0); + drawLine(4, 5, 6, 7, 4); + drawLine(0, 4); + drawLine(1, 5); + drawLine(2, 6); + drawLine(3, 7); + context.stroke(); + needsUpdate = false; + } + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode26/2d.js b/episode26/2d.js index 4992c05..b7a5368 100644 --- a/episode26/2d.js +++ b/episode26/2d.js @@ -1,33 +1,33 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - point = { - x: 300, - y: 200 - }, - delta = 0.05; - - context.translate(width / 2, height / 2); - - update(); - - function update() { - context.clearRect(-width / 2, -height / 2, width, height); - - context.beginPath(); - context.arc(point.x, point.y, 20, 0, Math.PI * 2, false); - context.fill(); - - var cos = Math.cos(delta), - sin = Math.sin(delta), - x = point.x * cos - point.y * sin, - y = point.y * cos + point.x * sin; - - point.x = x; - point.y = y; - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + point = { + x: 300, + y: 200 + }, + delta = 0.05; + + context.translate(width / 2, height / 2); + + update(); + + function update() { + context.clearRect(-width / 2, -height / 2, width, height); + + context.beginPath(); + context.arc(point.x, point.y, 20, 0, Math.PI * 2, false); + context.fill(); + + var cos = Math.cos(delta), + sin = Math.sin(delta), + x = point.x * cos - point.y * sin, + y = point.y * cos + point.x * sin; + + point.x = x; + point.y = y; + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode26/index.html b/episode26/index.html index 719fb94..dfde07f 100644 --- a/episode26/index.html +++ b/episode26/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode26/main.js b/episode26/main.js index 61da667..baae68b 100644 --- a/episode26/main.js +++ b/episode26/main.js @@ -1,156 +1,156 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight - fl = 300, - points = [], - needsUpdate = true, - centerZ = 1500; - - context.translate(width / 2, height / 2); - - points[0] = { x: -500, y: -500, z: 500 }; - points[1] = { x: 500, y: -500, z: 500 }; - points[2] = { x: 500, y: -500, z: -500 }; - points[3] = { x: -500, y: -500, z: -500 }; - points[4] = { x: -500, y: 500, z: 500 }; - points[5] = { x: 500, y: 500, z: 500 }; - points[6] = { x: 500, y: 500, z: -500 }; - points[7] = { x: -500, y: 500, z: -500 }; - - function project() { - for(var i = 0; i < points.length; i++) { - var p = points[i], - scale = fl / (fl + p.z + centerZ); - - p.sx = p.x * scale; - p.sy = p.y * scale; - } - } - - function drawLine() { - var p = points[arguments[0]]; - context.moveTo(p.sx, p.sy); - - for(var i = 1; i < arguments.length; i++) { - p = points[arguments[i]]; - context.lineTo(p.sx, p.sy); - } - } - - function translateModel(x, y, z) { - for(var i = 0; i < points.length; i++) { - points[i].x += x; - points[i].y += y; - points[i].z += z; - } - needsUpdate = true; - } - - function rotateX(angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle); - - for(var i = 0; i < points.length; i++) { - var p = points[i], - y = p.y * cos - p.z * sin, - z = p.z * cos + p.y * sin; - p.y = y; - p.z = z; - } - needsUpdate = true; - } - - function rotateY(angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle); - - for(var i = 0; i < points.length; i++) { - var p = points[i], - x = p.x * cos - p.z * sin, - z = p.z * cos + p.x * sin; - p.x = x; - p.z = z; - } - needsUpdate = true; - } - - function rotateZ(angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle); - - for(var i = 0; i < points.length; i++) { - var p = points[i], - x = p.x * cos - p.y * sin, - y = p.y * cos + p.x * sin; - p.x = x; - p.y = y; - } - needsUpdate = true; - } - - document.body.addEventListener("keydown", function(event) { - switch(event.keyCode) { - case 37: // left - if(event.ctrlKey) { - rotateY(0.05); - } - else { - translateModel(-20, 0, 0); - } - break; - case 39: // right - if(event.ctrlKey) { - rotateY(-0.05); - } - else { - translateModel(20, 0, 0); - } - break; - case 38: // up - if(event.shiftKey) { - translateModel(0, 0, 20); - } - else if(event.ctrlKey) { - rotateX(0.05); - } - else { - translateModel(0, -20, 0); - } - break; - case 40: // down - if(event.shiftKey) { - translateModel(0, 0, -20); - } - else if(event.ctrlKey) { - rotateX(-0.05); - } - else { - translateModel(0, 20, 0); - } - break; - } - }); - - update(); - - function update() { - if(needsUpdate) { - context.clearRect(-width / 2, -height / 2, width, height); - project(); - - context.beginPath(); - drawLine(0, 1, 2, 3, 0); - drawLine(4, 5, 6, 7, 4); - drawLine(0, 4); - drawLine(1, 5); - drawLine(2, 6); - drawLine(3, 7); - context.stroke(); - needsUpdate = false; - } - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight + fl = 300, + points = [], + needsUpdate = true, + centerZ = 1500; + + context.translate(width / 2, height / 2); + + points[0] = { x: -500, y: -500, z: 500 }; + points[1] = { x: 500, y: -500, z: 500 }; + points[2] = { x: 500, y: -500, z: -500 }; + points[3] = { x: -500, y: -500, z: -500 }; + points[4] = { x: -500, y: 500, z: 500 }; + points[5] = { x: 500, y: 500, z: 500 }; + points[6] = { x: 500, y: 500, z: -500 }; + points[7] = { x: -500, y: 500, z: -500 }; + + function project() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + scale = fl / (fl + p.z + centerZ); + + p.sx = p.x * scale; + p.sy = p.y * scale; + } + } + + function drawLine() { + var p = points[arguments[0]]; + context.moveTo(p.sx, p.sy); + + for(var i = 1; i < arguments.length; i++) { + p = points[arguments[i]]; + context.lineTo(p.sx, p.sy); + } + } + + function translateModel(x, y, z) { + for(var i = 0; i < points.length; i++) { + points[i].x += x; + points[i].y += y; + points[i].z += z; + } + needsUpdate = true; + } + + function rotateX(angle) { + var cos = Math.cos(angle), + sin = Math.sin(angle); + + for(var i = 0; i < points.length; i++) { + var p = points[i], + y = p.y * cos - p.z * sin, + z = p.z * cos + p.y * sin; + p.y = y; + p.z = z; + } + needsUpdate = true; + } + + function rotateY(angle) { + var cos = Math.cos(angle), + sin = Math.sin(angle); + + for(var i = 0; i < points.length; i++) { + var p = points[i], + x = p.x * cos - p.z * sin, + z = p.z * cos + p.x * sin; + p.x = x; + p.z = z; + } + needsUpdate = true; + } + + function rotateZ(angle) { + var cos = Math.cos(angle), + sin = Math.sin(angle); + + for(var i = 0; i < points.length; i++) { + var p = points[i], + x = p.x * cos - p.y * sin, + y = p.y * cos + p.x * sin; + p.x = x; + p.y = y; + } + needsUpdate = true; + } + + document.body.addEventListener("keydown", function(event) { + switch(event.keyCode) { + case 37: // left + if(event.ctrlKey) { + rotateY(0.05); + } + else { + translateModel(-20, 0, 0); + } + break; + case 39: // right + if(event.ctrlKey) { + rotateY(-0.05); + } + else { + translateModel(20, 0, 0); + } + break; + case 38: // up + if(event.shiftKey) { + translateModel(0, 0, 20); + } + else if(event.ctrlKey) { + rotateX(0.05); + } + else { + translateModel(0, -20, 0); + } + break; + case 40: // down + if(event.shiftKey) { + translateModel(0, 0, -20); + } + else if(event.ctrlKey) { + rotateX(-0.05); + } + else { + translateModel(0, 20, 0); + } + break; + } + }); + + update(); + + function update() { + if(needsUpdate) { + context.clearRect(-width / 2, -height / 2, width, height); + project(); + + context.beginPath(); + drawLine(0, 1, 2, 3, 0); + drawLine(4, 5, 6, 7, 4); + drawLine(0, 4); + drawLine(1, 5); + drawLine(2, 6); + drawLine(3, 7); + context.stroke(); + needsUpdate = false; + } + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode27/index.html b/episode27/index.html index 5989d5a..b211694 100644 --- a/episode27/index.html +++ b/episode27/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode27/main.js b/episode27/main.js index 12399a3..2b0eba4 100644 --- a/episode27/main.js +++ b/episode27/main.js @@ -1,46 +1,46 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - target = { - x: width, - y: Math.random() * height - }, - - position = { - x: 0, - y: Math.random() * height - }, - - ease = 0.1; - - update(); - - document.body.addEventListener("mousemove", function(event) { - target.x = event.clientX; - target.y = event.clientY; - }); - - function update() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(position.x, position.y, 10, 0, Math.PI * 2, false); - context.fill(); - - - var dx = target.x - position.x, - dy = target.y - position.y, - vx = dx * ease, - vy = dy * ease; - - position.x += vx; - position.y += vy; - - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + target = { + x: width, + y: Math.random() * height + }, + + position = { + x: 0, + y: Math.random() * height + }, + + ease = 0.1; + + update(); + + document.body.addEventListener("mousemove", function(event) { + target.x = event.clientX; + target.y = event.clientY; + }); + + function update() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(position.x, position.y, 10, 0, Math.PI * 2, false); + context.fill(); + + + var dx = target.x - position.x, + dy = target.y - position.y, + vx = dx * ease, + vy = dy * ease; + + position.x += vx; + position.y += vy; + + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode28/click.js b/episode28/click.js index 474b91a..7519fdc 100644 --- a/episode28/click.js +++ b/episode28/click.js @@ -1,59 +1,59 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - target = { - x: width, - y: Math.random() * height - }, - - position = { - x: 0, - y: Math.random() * height - }, - - ease = 0.1, - easing = true; - - update(); - - document.body.addEventListener("click", function(event) { - target.x = event.clientX; - target.y = event.clientY; - if(!easing) { - easing = true; - update(); - } - }); - - function update() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.arc(position.x, position.y, 10, 0, Math.PI * 2, false); - context.fill(); - - easing = easeTo(position, target, ease); - - if(easing) { - requestAnimationFrame(update); - } - } - - function easeTo(position, target, ease) { - var dx = target.x - position.x, - dy = target.y - position.y; - position.x += dx * ease; - position.y += dy * ease; - if(Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1) { - position.x = target.x; - position.y = target.y; - console.log("stop"); - return false; - } - return true; - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + target = { + x: width, + y: Math.random() * height + }, + + position = { + x: 0, + y: Math.random() * height + }, + + ease = 0.1, + easing = true; + + update(); + + document.body.addEventListener("click", function(event) { + target.x = event.clientX; + target.y = event.clientY; + if(!easing) { + easing = true; + update(); + } + }); + + function update() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.arc(position.x, position.y, 10, 0, Math.PI * 2, false); + context.fill(); + + easing = easeTo(position, target, ease); + + if(easing) { + requestAnimationFrame(update); + } + } + + function easeTo(position, target, ease) { + var dx = target.x - position.x, + dy = target.y - position.y; + position.x += dx * ease; + position.y += dy * ease; + if(Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1) { + position.x = target.x; + position.y = target.y; + console.log("stop"); + return false; + } + return true; + } + }; \ No newline at end of file diff --git a/episode28/index.html b/episode28/index.html index 4f21121..eb51211 100644 --- a/episode28/index.html +++ b/episode28/index.html @@ -1,24 +1,24 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/episode28/main.js b/episode28/main.js index b4eaa12..781320f 100644 --- a/episode28/main.js +++ b/episode28/main.js @@ -1,55 +1,55 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - target = { - x: width, - y: Math.random() * height - }, - - points = [], - numPoints = 100, - ease = 0.5; - - for(var i = 0; i < numPoints; i++) { - points.push({ - x: 0, - y: 0 - }); - } - - update(); - - document.body.addEventListener("mousemove", function(event) { - target.x = event.clientX; - target.y = event.clientY; - }); - - function update() { - context.clearRect(0, 0, width, height); - - var leader = { - x: target.x, - y: target.y - }; - - for(var i = 0; i < numPoints; i++) { - var point = points[i]; - point.x += (leader.x - point.x) * ease; - point.y += (leader.y - point.y) * ease; - - context.beginPath(); - context.arc(point.x, point.y, 10, 0, Math.PI * 2, false); - context.fill(); - - leader.x = point.x; - leader.y = point.y; - } - - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + target = { + x: width, + y: Math.random() * height + }, + + points = [], + numPoints = 100, + ease = 0.5; + + for(var i = 0; i < numPoints; i++) { + points.push({ + x: 0, + y: 0 + }); + } + + update(); + + document.body.addEventListener("mousemove", function(event) { + target.x = event.clientX; + target.y = event.clientY; + }); + + function update() { + context.clearRect(0, 0, width, height); + + var leader = { + x: target.x, + y: target.y + }; + + for(var i = 0; i < numPoints; i++) { + var point = points[i]; + point.x += (leader.x - point.x) * ease; + point.y += (leader.y - point.y) * ease; + + context.beginPath(); + context.arc(point.x, point.y, 10, 0, Math.PI * 2, false); + context.fill(); + + leader.x = point.x; + leader.y = point.y; + } + + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode28/steering.js b/episode28/steering.js index a22ff37..63d8039 100644 --- a/episode28/steering.js +++ b/episode28/steering.js @@ -1,38 +1,38 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - angle = 0, - targetAngle = 0, - ease = 0.05, - wheel; - - wheel = document.createElement("img"); - wheel.addEventListener("load", function() { - render(); - }); - wheel.src = "wheel.png"; - - - function render() { - context.clearRect(0, 0, width, height); - - angle += (targetAngle - angle) * ease; - - context.save(); - context.translate(width / 2, height / 2); - context.rotate(angle); - - context.drawImage(wheel, -wheel.width / 2, -wheel.height / 2); - - context.restore(); - requestAnimationFrame(render); - } - - document.body.addEventListener("mousemove", function(event) { - targetAngle = utils.map(event.clientX, 0, width, -Math.PI, Math.PI); - }); - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + angle = 0, + targetAngle = 0, + ease = 0.05, + wheel; + + wheel = document.createElement("img"); + wheel.addEventListener("load", function() { + render(); + }); + wheel.src = "wheel.png"; + + + function render() { + context.clearRect(0, 0, width, height); + + angle += (targetAngle - angle) * ease; + + context.save(); + context.translate(width / 2, height / 2); + context.rotate(angle); + + context.drawImage(wheel, -wheel.width / 2, -wheel.height / 2); + + context.restore(); + requestAnimationFrame(render); + } + + document.body.addEventListener("mousemove", function(event) { + targetAngle = utils.map(event.clientX, 0, width, -Math.PI, Math.PI); + }); + + }; \ No newline at end of file diff --git a/episode28/string.js b/episode28/string.js index bce76bd..23692c2 100644 --- a/episode28/string.js +++ b/episode28/string.js @@ -1,57 +1,57 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - target = { - x: width, - y: Math.random() * height - }, - - points = [], - numPoints = 50, - ease = 0.25; - - for(var i = 0; i < numPoints; i++) { - points.push({ - x: 0, - y: 0 - }); - } - - update(); - - document.body.addEventListener("mousemove", function(event) { - target.x = event.clientX; - target.y = event.clientY; - }); - - function update() { - context.clearRect(0, 0, width, height); - - var leader = { - x: target.x, - y: target.y - }; - - context.beginPath(); - context.moveTo(leader.x, leader.y); - - for(var i = 0; i < numPoints; i++) { - var point = points[i]; - point.x += (leader.x - point.x) * ease; - point.y += (leader.y - point.y) * ease; - - context.lineTo(point.x, point.y); - - leader.x = point.x; - leader.y = point.y; - } - - context.stroke(); - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + target = { + x: width, + y: Math.random() * height + }, + + points = [], + numPoints = 50, + ease = 0.25; + + for(var i = 0; i < numPoints; i++) { + points.push({ + x: 0, + y: 0 + }); + } + + update(); + + document.body.addEventListener("mousemove", function(event) { + target.x = event.clientX; + target.y = event.clientY; + }); + + function update() { + context.clearRect(0, 0, width, height); + + var leader = { + x: target.x, + y: target.y + }; + + context.beginPath(); + context.moveTo(leader.x, leader.y); + + for(var i = 0; i < numPoints; i++) { + var point = points[i]; + point.x += (leader.x - point.x) * ease; + point.y += (leader.y - point.y) * ease; + + context.lineTo(point.x, point.y); + + leader.x = point.x; + leader.y = point.y; + } + + context.stroke(); + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/episode28/utils.js b/episode28/utils.js index 3c0f824..04715df 100644 --- a/episode28/utils.js +++ b/episode28/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode29/index.html b/episode29/index.html index 5989d5a..b211694 100644 --- a/episode29/index.html +++ b/episode29/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode29/main.js b/episode29/main.js index 36c55d0..d212622 100644 --- a/episode29/main.js +++ b/episode29/main.js @@ -1,78 +1,78 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - start = { - x: 100, - y: 100 - }, - target = {}, - change = {}, - startTime, - duration = 1000; - - drawCircle(start.x, start.y); - - - document.body.addEventListener("click", function(event) { - target.x = event.clientX; - target.y = event.clientY; - change.x = target.x - start.x; - change.y = target.y - start.y; - startTime = new Date(); - update(); - }); - - function update() { - context.clearRect(0, 0, width, height); - - var time = new Date() - startTime; - if(time < duration) { - var x = easeInOutQuad(time, start.x, change.x, duration), - y = easeInOutQuad(time, start.y, change.y, duration); - drawCircle(x, y); - requestAnimationFrame(update); - } - else { - drawCircle(target.x, target.y); - start.x = target.x; - start.y = target.y; - } - - } - - // simple linear tweening - no easing - // t: current time, b: beginning value, c: change in value, d: duration - function linearTween(t, b, c, d) { - return c * t / d + b; - } - - ///////////// QUADRATIC EASING: t^2 /////////////////// - - // quadratic easing in - accelerating from zero velocity - // t: current time, b: beginning value, c: change in value, d: duration - // t and d can be in frames or seconds/milliseconds - function easeInQuad(t, b, c, d) { - return c*(t/=d)*t + b; - }; - - // quadratic easing out - decelerating to zero velocity - function easeOutQuad(t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }; - - // quadratic easing in/out - acceleration until halfway, then deceleration - function easeInOutQuad(t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }; - - - function drawCircle(x, y) { - context.beginPath(); - context.arc(x, y, 20, 0, Math.PI * 2, false); - context.fill(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + start = { + x: 100, + y: 100 + }, + target = {}, + change = {}, + startTime, + duration = 1000; + + drawCircle(start.x, start.y); + + + document.body.addEventListener("click", function(event) { + target.x = event.clientX; + target.y = event.clientY; + change.x = target.x - start.x; + change.y = target.y - start.y; + startTime = new Date(); + update(); + }); + + function update() { + context.clearRect(0, 0, width, height); + + var time = new Date() - startTime; + if(time < duration) { + var x = easeInOutQuad(time, start.x, change.x, duration), + y = easeInOutQuad(time, start.y, change.y, duration); + drawCircle(x, y); + requestAnimationFrame(update); + } + else { + drawCircle(target.x, target.y); + start.x = target.x; + start.y = target.y; + } + + } + + // simple linear tweening - no easing + // t: current time, b: beginning value, c: change in value, d: duration + function linearTween(t, b, c, d) { + return c * t / d + b; + } + + ///////////// QUADRATIC EASING: t^2 /////////////////// + + // quadratic easing in - accelerating from zero velocity + // t: current time, b: beginning value, c: change in value, d: duration + // t and d can be in frames or seconds/milliseconds + function easeInQuad(t, b, c, d) { + return c*(t/=d)*t + b; + }; + + // quadratic easing out - decelerating to zero velocity + function easeOutQuad(t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }; + + // quadratic easing in/out - acceleration until halfway, then deceleration + function easeInOutQuad(t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }; + + + function drawCircle(x, y) { + context.beginPath(); + context.arc(x, y, 20, 0, Math.PI * 2, false); + context.fill(); + } + }; \ No newline at end of file diff --git a/episode29/penner_easing.as b/episode29/penner_easing.as index f96a2b1..cad54b5 100644 --- a/episode29/penner_easing.as +++ b/episode29/penner_easing.as @@ -1,282 +1,282 @@ -/* - Easing Equations v1.5 - May 1, 2003 - (c) 2003 Robert Penner, all rights reserved. - This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html. - - These tweening functions provide different flavors of - math-based motion under a consistent API. - - Types of easing: - - Linear - Quadratic - Cubic - Quartic - Quintic - Sinusoidal - Exponential - Circular - Elastic - Back - Bounce - - Changes: - 1.5 - added bounce easing - 1.4 - added elastic and back easing - 1.3 - tweaked the exponential easing functions to make endpoints exact - 1.2 - inline optimizations (changing t and multiplying in one step)--thanks to Tatsuo Kato for the idea - - Discussed in Chapter 7 of - Robert Penner's Programming Macromedia Flash MX - (including graphs of the easing equations) - - http://www.robertpenner.com/profmx - http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20 -*/ - - -// simple linear tweening - no easing -// t: current time, b: beginning value, c: change in value, d: duration -Math.linearTween = function (t, b, c, d) { - return c*t/d + b; -}; - - - ///////////// QUADRATIC EASING: t^2 /////////////////// - -// quadratic easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in value, d: duration -// t and d can be in frames or seconds/milliseconds -Math.easeInQuad = function (t, b, c, d) { - return c*(t/=d)*t + b; -}; - -// quadratic easing out - decelerating to zero velocity -Math.easeOutQuad = function (t, b, c, d) { - return -c *(t/=d)*(t-2) + b; -}; - -// quadratic easing in/out - acceleration until halfway, then deceleration -Math.easeInOutQuad = function (t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; -}; - - - ///////////// CUBIC EASING: t^3 /////////////////////// - -// cubic easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in value, d: duration -// t and d can be frames or seconds/milliseconds -Math.easeInCubic = function (t, b, c, d) { - return c*(t/=d)*t*t + b; -}; - -// cubic easing out - decelerating to zero velocity -Math.easeOutCubic = function (t, b, c, d) { - return c*((t=t/d-1)*t*t + 1) + b; -}; - -// cubic easing in/out - acceleration until halfway, then deceleration -Math.easeInOutCubic = function (t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t + b; - return c/2*((t-=2)*t*t + 2) + b; -}; - - - ///////////// QUARTIC EASING: t^4 ///////////////////// - -// quartic easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in value, d: duration -// t and d can be frames or seconds/milliseconds -Math.easeInQuart = function (t, b, c, d) { - return c*(t/=d)*t*t*t + b; -}; - -// quartic easing out - decelerating to zero velocity -Math.easeOutQuart = function (t, b, c, d) { - return -c * ((t=t/d-1)*t*t*t - 1) + b; -}; - -// quartic easing in/out - acceleration until halfway, then deceleration -Math.easeInOutQuart = function (t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t + b; - return -c/2 * ((t-=2)*t*t*t - 2) + b; -}; - - - ///////////// QUINTIC EASING: t^5 //////////////////// - -// quintic easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in value, d: duration -// t and d can be frames or seconds/milliseconds -Math.easeInQuint = function (t, b, c, d) { - return c*(t/=d)*t*t*t*t + b; -}; - -// quintic easing out - decelerating to zero velocity -Math.easeOutQuint = function (t, b, c, d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; -}; - -// quintic easing in/out - acceleration until halfway, then deceleration -Math.easeInOutQuint = function (t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; - return c/2*((t-=2)*t*t*t*t + 2) + b; -}; - - - - ///////////// SINUSOIDAL EASING: sin(t) /////////////// - -// sinusoidal easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in position, d: duration -Math.easeInSine = function (t, b, c, d) { - return -c * Math.cos(t/d * (Math.PI/2)) + c + b; -}; - -// sinusoidal easing out - decelerating to zero velocity -Math.easeOutSine = function (t, b, c, d) { - return c * Math.sin(t/d * (Math.PI/2)) + b; -}; - -// sinusoidal easing in/out - accelerating until halfway, then decelerating -Math.easeInOutSine = function (t, b, c, d) { - return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; -}; - - - ///////////// EXPONENTIAL EASING: 2^t ///////////////// - -// exponential easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in position, d: duration -Math.easeInExpo = function (t, b, c, d) { - return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; -}; - -// exponential easing out - decelerating to zero velocity -Math.easeOutExpo = function (t, b, c, d) { - return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; -}; - -// exponential easing in/out - accelerating until halfway, then decelerating -Math.easeInOutExpo = function (t, b, c, d) { - if (t==0) return b; - if (t==d) return b+c; - if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; - return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; -}; - - - /////////// CIRCULAR EASING: sqrt(1-t^2) ////////////// - -// circular easing in - accelerating from zero velocity -// t: current time, b: beginning value, c: change in position, d: duration -Math.easeInCirc = function (t, b, c, d) { - return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; -}; - -// circular easing out - decelerating to zero velocity -Math.easeOutCirc = function (t, b, c, d) { - return c * Math.sqrt(1 - (t=t/d-1)*t) + b; -}; - -// circular easing in/out - acceleration until halfway, then deceleration -Math.easeInOutCirc = function (t, b, c, d) { - if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; - return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; -}; - - - /////////// ELASTIC EASING: exponentially decaying sine wave ////////////// - -// t: current time, b: beginning value, c: change in value, d: duration, a: amplitude (optional), p: period (optional) -// t and d can be in frames or seconds/milliseconds - -Math.easeInElastic = function (t, b, c, d, a, p) { - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; -}; - -Math.easeOutElastic = function (t, b, c, d, a, p) { - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; -}; - -Math.easeInOutElastic = function (t, b, c, d, a, p) { - if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; -}; - - - /////////// BACK EASING: overshooting cubic easing: (s+1)*t^3 - s*t^2 ////////////// - -// back easing in - backtracking slightly, then reversing direction and moving to target -// t: current time, b: beginning value, c: change in value, d: duration, s: overshoot amount (optional) -// t and d can be in frames or seconds/milliseconds -// s controls the amount of overshoot: higher s means greater overshoot -// s has a default value of 1.70158, which produces an overshoot of 10 percent -// s==0 produces cubic easing with no overshoot -Math.easeInBack = function (t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*(t/=d)*t*((s+1)*t - s) + b; -}; - -// back easing out - moving towards target, overshooting it slightly, then reversing and coming back to target -Math.easeOutBack = function (t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; -}; - -// back easing in/out - backtracking slightly, then reversing direction and moving to target, -// then overshooting target, reversing, and finally coming back to target -Math.easeInOutBack = function (t, b, c, d, s) { - if (s == undefined) s = 1.70158; - if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; - return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; -}; - - - /////////// BOUNCE EASING: exponentially decaying parabolic bounce ////////////// - -// bounce easing in -// t: current time, b: beginning value, c: change in position, d: duration -Math.easeInBounce = function (t, b, c, d) { - return c - Math.easeOutBounce (d-t, 0, c, d) + b; -}; - -// bounce easing out -Math.easeOutBounce = function (t, b, c, d) { - if ((t/=d) < (1/2.75)) { - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)) { - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; - } else if (t < (2.5/2.75)) { - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; - } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; - } -}; - -// bounce easing in/out -Math.easeInOutBounce = function (t, b, c, d) { - if (t < d/2) return Math.easeInBounce (t*2, 0, c, d) * .5 + b; - return Math.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b; -}; - - -//trace (">> Penner easing equations loaded"); - - - - - - +/* + Easing Equations v1.5 + May 1, 2003 + (c) 2003 Robert Penner, all rights reserved. + This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html. + + These tweening functions provide different flavors of + math-based motion under a consistent API. + + Types of easing: + + Linear + Quadratic + Cubic + Quartic + Quintic + Sinusoidal + Exponential + Circular + Elastic + Back + Bounce + + Changes: + 1.5 - added bounce easing + 1.4 - added elastic and back easing + 1.3 - tweaked the exponential easing functions to make endpoints exact + 1.2 - inline optimizations (changing t and multiplying in one step)--thanks to Tatsuo Kato for the idea + + Discussed in Chapter 7 of + Robert Penner's Programming Macromedia Flash MX + (including graphs of the easing equations) + + http://www.robertpenner.com/profmx + http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20 +*/ + + +// simple linear tweening - no easing +// t: current time, b: beginning value, c: change in value, d: duration +Math.linearTween = function (t, b, c, d) { + return c*t/d + b; +}; + + + ///////////// QUADRATIC EASING: t^2 /////////////////// + +// quadratic easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in value, d: duration +// t and d can be in frames or seconds/milliseconds +Math.easeInQuad = function (t, b, c, d) { + return c*(t/=d)*t + b; +}; + +// quadratic easing out - decelerating to zero velocity +Math.easeOutQuad = function (t, b, c, d) { + return -c *(t/=d)*(t-2) + b; +}; + +// quadratic easing in/out - acceleration until halfway, then deceleration +Math.easeInOutQuad = function (t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; +}; + + + ///////////// CUBIC EASING: t^3 /////////////////////// + +// cubic easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in value, d: duration +// t and d can be frames or seconds/milliseconds +Math.easeInCubic = function (t, b, c, d) { + return c*(t/=d)*t*t + b; +}; + +// cubic easing out - decelerating to zero velocity +Math.easeOutCubic = function (t, b, c, d) { + return c*((t=t/d-1)*t*t + 1) + b; +}; + +// cubic easing in/out - acceleration until halfway, then deceleration +Math.easeInOutCubic = function (t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + return c/2*((t-=2)*t*t + 2) + b; +}; + + + ///////////// QUARTIC EASING: t^4 ///////////////////// + +// quartic easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in value, d: duration +// t and d can be frames or seconds/milliseconds +Math.easeInQuart = function (t, b, c, d) { + return c*(t/=d)*t*t*t + b; +}; + +// quartic easing out - decelerating to zero velocity +Math.easeOutQuart = function (t, b, c, d) { + return -c * ((t=t/d-1)*t*t*t - 1) + b; +}; + +// quartic easing in/out - acceleration until halfway, then deceleration +Math.easeInOutQuart = function (t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + return -c/2 * ((t-=2)*t*t*t - 2) + b; +}; + + + ///////////// QUINTIC EASING: t^5 //////////////////// + +// quintic easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in value, d: duration +// t and d can be frames or seconds/milliseconds +Math.easeInQuint = function (t, b, c, d) { + return c*(t/=d)*t*t*t*t + b; +}; + +// quintic easing out - decelerating to zero velocity +Math.easeOutQuint = function (t, b, c, d) { + return c*((t=t/d-1)*t*t*t*t + 1) + b; +}; + +// quintic easing in/out - acceleration until halfway, then deceleration +Math.easeInOutQuint = function (t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; +}; + + + + ///////////// SINUSOIDAL EASING: sin(t) /////////////// + +// sinusoidal easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in position, d: duration +Math.easeInSine = function (t, b, c, d) { + return -c * Math.cos(t/d * (Math.PI/2)) + c + b; +}; + +// sinusoidal easing out - decelerating to zero velocity +Math.easeOutSine = function (t, b, c, d) { + return c * Math.sin(t/d * (Math.PI/2)) + b; +}; + +// sinusoidal easing in/out - accelerating until halfway, then decelerating +Math.easeInOutSine = function (t, b, c, d) { + return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; +}; + + + ///////////// EXPONENTIAL EASING: 2^t ///////////////// + +// exponential easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in position, d: duration +Math.easeInExpo = function (t, b, c, d) { + return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; +}; + +// exponential easing out - decelerating to zero velocity +Math.easeOutExpo = function (t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; +}; + +// exponential easing in/out - accelerating until halfway, then decelerating +Math.easeInOutExpo = function (t, b, c, d) { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; + return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; +}; + + + /////////// CIRCULAR EASING: sqrt(1-t^2) ////////////// + +// circular easing in - accelerating from zero velocity +// t: current time, b: beginning value, c: change in position, d: duration +Math.easeInCirc = function (t, b, c, d) { + return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; +}; + +// circular easing out - decelerating to zero velocity +Math.easeOutCirc = function (t, b, c, d) { + return c * Math.sqrt(1 - (t=t/d-1)*t) + b; +}; + +// circular easing in/out - acceleration until halfway, then deceleration +Math.easeInOutCirc = function (t, b, c, d) { + if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; + return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; +}; + + + /////////// ELASTIC EASING: exponentially decaying sine wave ////////////// + +// t: current time, b: beginning value, c: change in value, d: duration, a: amplitude (optional), p: period (optional) +// t and d can be in frames or seconds/milliseconds + +Math.easeInElastic = function (t, b, c, d, a, p) { + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; +}; + +Math.easeOutElastic = function (t, b, c, d, a, p) { + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; +}; + +Math.easeInOutElastic = function (t, b, c, d, a, p) { + if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; +}; + + + /////////// BACK EASING: overshooting cubic easing: (s+1)*t^3 - s*t^2 ////////////// + +// back easing in - backtracking slightly, then reversing direction and moving to target +// t: current time, b: beginning value, c: change in value, d: duration, s: overshoot amount (optional) +// t and d can be in frames or seconds/milliseconds +// s controls the amount of overshoot: higher s means greater overshoot +// s has a default value of 1.70158, which produces an overshoot of 10 percent +// s==0 produces cubic easing with no overshoot +Math.easeInBack = function (t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*(t/=d)*t*((s+1)*t - s) + b; +}; + +// back easing out - moving towards target, overshooting it slightly, then reversing and coming back to target +Math.easeOutBack = function (t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; +}; + +// back easing in/out - backtracking slightly, then reversing direction and moving to target, +// then overshooting target, reversing, and finally coming back to target +Math.easeInOutBack = function (t, b, c, d, s) { + if (s == undefined) s = 1.70158; + if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; + return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; +}; + + + /////////// BOUNCE EASING: exponentially decaying parabolic bounce ////////////// + +// bounce easing in +// t: current time, b: beginning value, c: change in position, d: duration +Math.easeInBounce = function (t, b, c, d) { + return c - Math.easeOutBounce (d-t, 0, c, d) + b; +}; + +// bounce easing out +Math.easeOutBounce = function (t, b, c, d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } +}; + +// bounce easing in/out +Math.easeInOutBounce = function (t, b, c, d) { + if (t < d/2) return Math.easeInBounce (t*2, 0, c, d) * .5 + b; + return Math.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b; +}; + + +//trace (">> Penner easing equations loaded"); + + + + + + diff --git a/episode29/utils.js b/episode29/utils.js index 3c0f824..04715df 100644 --- a/episode29/utils.js +++ b/episode29/utils.js @@ -1,123 +1,123 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - }, - - multicurve: function(points, context) { - var p0, p1, midx, midy; - - context.moveTo(points[0].x, points[0].y); - - for(var i = 1; i < points.length - 2; i += 1) { - p0 = points[i]; - p1 = points[i + 1]; - midx = (p0.x + p1.x) / 2; - midy = (p0.y + p1.y) / 2; - context.quadraticCurveTo(p0.x, p0.y, midx, midy); - } - p0 = points[points.length - 2]; - p1 = points[points.length - 1]; - context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + }, + + multicurve: function(points, context) { + var p0, p1, midx, midy; + + context.moveTo(points[0].x, points[0].y); + + for(var i = 1; i < points.length - 2; i += 1) { + p0 = points[i]; + p1 = points[i + 1]; + midx = (p0.x + p1.x) / 2; + midy = (p0.y + p1.y) / 2; + context.quadraticCurveTo(p0.x, p0.y, midx, midy); + } + p0 = points[points.length - 2]; + p1 = points[points.length - 1]; + context.quadraticCurveTo(p0.x, p0.y, p1.x, p1.y); + } + } \ No newline at end of file diff --git a/episode3/index.html b/episode3/index.html index 0693f9f..aa8bb25 100644 --- a/episode3/index.html +++ b/episode3/index.html @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode3/trig02.js b/episode3/trig02.js index 5b4e8f8..5dcfb64 100644 --- a/episode3/trig02.js +++ b/episode3/trig02.js @@ -1,30 +1,30 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var centerY = height * .5, - centerX = width * .5, - baseAlpha = 0.5, - offset = 0.5, - speed = 0.1, - angle = 0; - - render(); - - function render() { - var alpha = baseAlpha + Math.sin(angle) * offset; - - context.fillStyle = "rgba(0, 0, 0, " + alpha + ")"; - - context.clearRect(0, 0, width, height); - context.beginPath(); - context.arc(centerX, centerY, 100, 0, Math.PI * 2, false); - context.fill(); - - angle += speed; - - requestAnimationFrame(render); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var centerY = height * .5, + centerX = width * .5, + baseAlpha = 0.5, + offset = 0.5, + speed = 0.1, + angle = 0; + + render(); + + function render() { + var alpha = baseAlpha + Math.sin(angle) * offset; + + context.fillStyle = "rgba(0, 0, 0, " + alpha + ")"; + + context.clearRect(0, 0, width, height); + context.beginPath(); + context.arc(centerX, centerY, 100, 0, Math.PI * 2, false); + context.fill(); + + angle += speed; + + requestAnimationFrame(render); + } }; \ No newline at end of file diff --git a/episode30/index.html b/episode30/index.html index b827fdb..0e26dca 100644 --- a/episode30/index.html +++ b/episode30/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode30/tweenBasic.js b/episode30/tweenBasic.js index cdaa484..d3f2c83 100644 --- a/episode30/tweenBasic.js +++ b/episode30/tweenBasic.js @@ -1,71 +1,71 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - ball = { - x: 100, - y: 100, - alpha: 1 - }; - - tween(ball, "alpha", 0, 1000, easeInOutQuad); - - function tween(obj, prop, target, duration, easingFunc) { - var start = obj[prop], - change = target - start, - startTime = new Date(); - - update(); - - function update() { - var time = new Date() - startTime; - if(time < duration) { - obj[prop] = easingFunc(time, start, change, duration); - requestAnimationFrame(update); - } - else { - time = duration; - obj[prop] = easingFunc(time, start, change, duration); - } - render(); - } - } - - - function render() { - context.clearRect(0, 0, width, height); - context.globalAlpha = ball.alpha; - context.beginPath(); - context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); - context.fill(); - } - - - // simple linear tweening - no easing - // t: current time, b: beginning value, c: change in value, d: duration - function linearTween(t, b, c, d) { - return c * t / d + b; - } - - ///////////// QUADRATIC EASING: t^2 /////////////////// - - // quadratic easing in - accelerating from zero velocity - // t: current time, b: beginning value, c: change in value, d: duration - // t and d can be in frames or seconds/milliseconds - function easeInQuad(t, b, c, d) { - return c*(t/=d)*t + b; - }; - - // quadratic easing out - decelerating to zero velocity - function easeOutQuad(t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }; - - // quadratic easing in/out - acceleration until halfway, then deceleration - function easeInOutQuad(t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }; + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + ball = { + x: 100, + y: 100, + alpha: 1 + }; + + tween(ball, "alpha", 0, 1000, easeInOutQuad); + + function tween(obj, prop, target, duration, easingFunc) { + var start = obj[prop], + change = target - start, + startTime = new Date(); + + update(); + + function update() { + var time = new Date() - startTime; + if(time < duration) { + obj[prop] = easingFunc(time, start, change, duration); + requestAnimationFrame(update); + } + else { + time = duration; + obj[prop] = easingFunc(time, start, change, duration); + } + render(); + } + } + + + function render() { + context.clearRect(0, 0, width, height); + context.globalAlpha = ball.alpha; + context.beginPath(); + context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); + context.fill(); + } + + + // simple linear tweening - no easing + // t: current time, b: beginning value, c: change in value, d: duration + function linearTween(t, b, c, d) { + return c * t / d + b; + } + + ///////////// QUADRATIC EASING: t^2 /////////////////// + + // quadratic easing in - accelerating from zero velocity + // t: current time, b: beginning value, c: change in value, d: duration + // t and d can be in frames or seconds/milliseconds + function easeInQuad(t, b, c, d) { + return c*(t/=d)*t + b; + }; + + // quadratic easing out - decelerating to zero velocity + function easeOutQuad(t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }; + + // quadratic easing in/out - acceleration until halfway, then deceleration + function easeInOutQuad(t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }; }; \ No newline at end of file diff --git a/episode30/tweenFull.js b/episode30/tweenFull.js index e7599f7..950d02f 100644 --- a/episode30/tweenFull.js +++ b/episode30/tweenFull.js @@ -1,85 +1,85 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - ball = { - x: 100, - y: 100, - alpha: 1 - }; - - tween(ball, {x: 900, y: 700, alpha: 0 }, 1000, easeInOutQuad, render, tweenBack); - - function tweenBack() { - tween(ball, {x: 100, y: 100, alpha: 1 }, 1000, easeInOutQuad, render, render); - } - - function tween(obj, props, duration, easingFunc, onProgress, onComplete) { - var starts = {}, - changes = {}, - startTime = new Date(); - - for(var prop in props) { - starts[prop] = obj[prop]; - changes[prop] = props[prop] - starts[prop]; - } - - update(); - - function update() { - var time = new Date() - startTime; - if(time < duration) { - for(var prop in props) { - obj[prop] = easingFunc(time, starts[prop], changes[prop], duration); - } - onProgress(); - requestAnimationFrame(update); - } - else { - time = duration; - for(var prop in props) { - obj[prop] = easingFunc(time, starts[prop], changes[prop], duration); - } - onComplete(); - } - } - } - - - function render() { - context.clearRect(0, 0, width, height); - context.globalAlpha = ball.alpha; - context.beginPath(); - context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); - context.fill(); - } - - - // simple linear tweening - no easing - // t: current time, b: beginning value, c: change in value, d: duration - function linearTween(t, b, c, d) { - return c * t / d + b; - } - - ///////////// QUADRATIC EASING: t^2 /////////////////// - - // quadratic easing in - accelerating from zero velocity - // t: current time, b: beginning value, c: change in value, d: duration - // t and d can be in frames or seconds/milliseconds - function easeInQuad(t, b, c, d) { - return c*(t/=d)*t + b; - }; - - // quadratic easing out - decelerating to zero velocity - function easeOutQuad(t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }; - - // quadratic easing in/out - acceleration until halfway, then deceleration - function easeInOutQuad(t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }; + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + ball = { + x: 100, + y: 100, + alpha: 1 + }; + + tween(ball, {x: 900, y: 700, alpha: 0 }, 1000, easeInOutQuad, render, tweenBack); + + function tweenBack() { + tween(ball, {x: 100, y: 100, alpha: 1 }, 1000, easeInOutQuad, render, render); + } + + function tween(obj, props, duration, easingFunc, onProgress, onComplete) { + var starts = {}, + changes = {}, + startTime = new Date(); + + for(var prop in props) { + starts[prop] = obj[prop]; + changes[prop] = props[prop] - starts[prop]; + } + + update(); + + function update() { + var time = new Date() - startTime; + if(time < duration) { + for(var prop in props) { + obj[prop] = easingFunc(time, starts[prop], changes[prop], duration); + } + onProgress(); + requestAnimationFrame(update); + } + else { + time = duration; + for(var prop in props) { + obj[prop] = easingFunc(time, starts[prop], changes[prop], duration); + } + onComplete(); + } + } + } + + + function render() { + context.clearRect(0, 0, width, height); + context.globalAlpha = ball.alpha; + context.beginPath(); + context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); + context.fill(); + } + + + // simple linear tweening - no easing + // t: current time, b: beginning value, c: change in value, d: duration + function linearTween(t, b, c, d) { + return c * t / d + b; + } + + ///////////// QUADRATIC EASING: t^2 /////////////////// + + // quadratic easing in - accelerating from zero velocity + // t: current time, b: beginning value, c: change in value, d: duration + // t and d can be in frames or seconds/milliseconds + function easeInQuad(t, b, c, d) { + return c*(t/=d)*t + b; + }; + + // quadratic easing out - decelerating to zero velocity + function easeOutQuad(t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }; + + // quadratic easing in/out - acceleration until halfway, then deceleration + function easeInOutQuad(t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }; }; \ No newline at end of file diff --git a/episode30/tweenx.js b/episode30/tweenx.js index b2c2642..80e46d6 100644 --- a/episode30/tweenx.js +++ b/episode30/tweenx.js @@ -1,69 +1,69 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - ball = { - x: 100, - y: 100 - }; - - tweenX(ball, 800, 1000, easeInOutQuad); - - function tweenX(obj, targetX, duration, easingFunc) { - var startX = obj.x, - changeX = targetX - startX, - startTime = new Date(); - - update(); - - function update() { - var time = new Date() - startTime; - if(time < duration) { - obj.x = easingFunc(time, startX, changeX, duration); - requestAnimationFrame(update); - } - else { - time = duration; - obj.x = easingFunc(time, startX, changeX, duration); - } - render(); - } - } - - - function render() { - context.clearRect(0, 0, width, height); - context.beginPath(); - context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); - context.fill(); - } - - - // simple linear tweening - no easing - // t: current time, b: beginning value, c: change in value, d: duration - function linearTween(t, b, c, d) { - return c * t / d + b; - } - - ///////////// QUADRATIC EASING: t^2 /////////////////// - - // quadratic easing in - accelerating from zero velocity - // t: current time, b: beginning value, c: change in value, d: duration - // t and d can be in frames or seconds/milliseconds - function easeInQuad(t, b, c, d) { - return c*(t/=d)*t + b; - }; - - // quadratic easing out - decelerating to zero velocity - function easeOutQuad(t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }; - - // quadratic easing in/out - acceleration until halfway, then deceleration - function easeInOutQuad(t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }; + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + ball = { + x: 100, + y: 100 + }; + + tweenX(ball, 800, 1000, easeInOutQuad); + + function tweenX(obj, targetX, duration, easingFunc) { + var startX = obj.x, + changeX = targetX - startX, + startTime = new Date(); + + update(); + + function update() { + var time = new Date() - startTime; + if(time < duration) { + obj.x = easingFunc(time, startX, changeX, duration); + requestAnimationFrame(update); + } + else { + time = duration; + obj.x = easingFunc(time, startX, changeX, duration); + } + render(); + } + } + + + function render() { + context.clearRect(0, 0, width, height); + context.beginPath(); + context.arc(ball.x, ball.y, 20, 0, Math.PI * 2, false); + context.fill(); + } + + + // simple linear tweening - no easing + // t: current time, b: beginning value, c: change in value, d: duration + function linearTween(t, b, c, d) { + return c * t / d + b; + } + + ///////////// QUADRATIC EASING: t^2 /////////////////// + + // quadratic easing in - accelerating from zero velocity + // t: current time, b: beginning value, c: change in value, d: duration + // t and d can be in frames or seconds/milliseconds + function easeInQuad(t, b, c, d) { + return c*(t/=d)*t + b; + }; + + // quadratic easing out - decelerating to zero velocity + function easeOutQuad(t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }; + + // quadratic easing in/out - acceleration until halfway, then deceleration + function easeInOutQuad(t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }; }; \ No newline at end of file diff --git a/episode32/index.html b/episode32/index.html index 5989d5a..b211694 100644 --- a/episode32/index.html +++ b/episode32/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode32/main.js b/episode32/main.js index fd14089..012edb5 100644 --- a/episode32/main.js +++ b/episode32/main.js @@ -1,55 +1,55 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var p0 = { - x: 100, - y: 100 - }, - p1 = { - x: 500, - y: 500 - }, - p2 = { - x: 600, - y: 50 - }, - p3 = { - x: 80, - y: 600 - }; - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.moveTo(p2.x, p2.y); - context.lineTo(p3.x, p3.y); - context.stroke(); - - var intersect = lineIntersect(p0, p1, p2, p3); - - context.beginPath(); - context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); - context.stroke(); - - - - function lineIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - return { - x: (B2 * C1 - B1 * C2) / denominator, - y: (A1 * C2 - A2 * C1) / denominator - } - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var p0 = { + x: 100, + y: 100 + }, + p1 = { + x: 500, + y: 500 + }, + p2 = { + x: 600, + y: 50 + }, + p3 = { + x: 80, + y: 600 + }; + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.moveTo(p2.x, p2.y); + context.lineTo(p3.x, p3.y); + context.stroke(); + + var intersect = lineIntersect(p0, p1, p2, p3); + + context.beginPath(); + context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); + context.stroke(); + + + + function lineIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + return { + x: (B2 * C1 - B1 * C2) / denominator, + y: (A1 * C2 - A2 * C1) / denominator + } + } + }; \ No newline at end of file diff --git a/episode32/main_interactive.js b/episode32/main_interactive.js index 2f67db2..25d9c66 100644 --- a/episode32/main_interactive.js +++ b/episode32/main_interactive.js @@ -1,108 +1,108 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var p0 = { - x: 100, - y: 100 - }, - p1 = { - x: 500, - y: 500 - }, - p2 = { - x: 600, - y: 50 - }, - p3 = { - x: 80, - y: 600 - }, - clickPoint; - - document.body.addEventListener("mousedown", onMouseDown); - - function onMouseDown(event) { - clickPoint = getClickPoint(event.clientX, event.clientY); - if(clickPoint) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - } - } - - function onMouseMove(event) { - clickPoint.x = event.clientX; - clickPoint.y = event.clientY; - render(); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - } - - function getClickPoint(x, y) { - var points = [p0, p1, p2, p3]; - for(var i = 0; i < points.length; i++) { - var p = points[i], - dx = p.x - x, - dy = p.y - y, - dist = Math.sqrt(dx * dx + dy * dy); - if(dist < 10) { - return p; - } - - } - } - - - render(); - - function render() { - context.clearRect(0, 0, width, height); - - drawPoint(p0); - drawPoint(p1); - drawPoint(p2); - drawPoint(p3); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.moveTo(p2.x, p2.y); - context.lineTo(p3.x, p3.y); - context.stroke(); - - var intersect = lineIntersect(p0, p1, p2, p3); - - context.beginPath(); - context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); - context.stroke(); - } - - function drawPoint(p) { - context.beginPath(); - context.arc(p.x, p.y, 10, 0, Math.PI * 2, false); - context.fill(); - } - - - function lineIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - return { - x: (B2 * C1 - B1 * C2) / denominator, - y: (A1 * C2 - A2 * C1) / denominator - } - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var p0 = { + x: 100, + y: 100 + }, + p1 = { + x: 500, + y: 500 + }, + p2 = { + x: 600, + y: 50 + }, + p3 = { + x: 80, + y: 600 + }, + clickPoint; + + document.body.addEventListener("mousedown", onMouseDown); + + function onMouseDown(event) { + clickPoint = getClickPoint(event.clientX, event.clientY); + if(clickPoint) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + } + } + + function onMouseMove(event) { + clickPoint.x = event.clientX; + clickPoint.y = event.clientY; + render(); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + } + + function getClickPoint(x, y) { + var points = [p0, p1, p2, p3]; + for(var i = 0; i < points.length; i++) { + var p = points[i], + dx = p.x - x, + dy = p.y - y, + dist = Math.sqrt(dx * dx + dy * dy); + if(dist < 10) { + return p; + } + + } + } + + + render(); + + function render() { + context.clearRect(0, 0, width, height); + + drawPoint(p0); + drawPoint(p1); + drawPoint(p2); + drawPoint(p3); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.moveTo(p2.x, p2.y); + context.lineTo(p3.x, p3.y); + context.stroke(); + + var intersect = lineIntersect(p0, p1, p2, p3); + + context.beginPath(); + context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); + context.stroke(); + } + + function drawPoint(p) { + context.beginPath(); + context.arc(p.x, p.y, 10, 0, Math.PI * 2, false); + context.fill(); + } + + + function lineIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + return { + x: (B2 * C1 - B1 * C2) / denominator, + y: (A1 * C2 - A2 * C1) / denominator + } + } + }; \ No newline at end of file diff --git a/episode33/index.html b/episode33/index.html index 0c87fbf..6a1d2b2 100644 --- a/episode33/index.html +++ b/episode33/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode33/main_interactive.js b/episode33/main_interactive.js index 4017e74..5007ff3 100644 --- a/episode33/main_interactive.js +++ b/episode33/main_interactive.js @@ -1,145 +1,145 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var p0 = { - x: 100, - y: 100 - }, - p1 = { - x: 500, - y: 500 - }, - p2 = { - x: 600, - y: 50 - }, - p3 = { - x: 80, - y: 600 - }, - clickPoint; - - document.body.addEventListener("mousedown", onMouseDown); - - function onMouseDown(event) { - clickPoint = getClickPoint(event.clientX, event.clientY); - if(clickPoint) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - } - } - - function onMouseMove(event) { - clickPoint.x = event.clientX; - clickPoint.y = event.clientY; - render(); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - } - - function getClickPoint(x, y) { - var points = [p0, p1, p2, p3]; - for(var i = 0; i < points.length; i++) { - var p = points[i], - dx = p.x - x, - dy = p.y - y, - dist = Math.sqrt(dx * dx + dy * dy); - if(dist < 10) { - return p; - } - - } - } - - - render(); - - function render() { - context.clearRect(0, 0, width, height); - - drawPoint(p0); - drawPoint(p1); - drawPoint(p2); - drawPoint(p3); - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.moveTo(p2.x, p2.y); - context.lineTo(p3.x, p3.y); - context.stroke(); - - var intersect = segmentIntersect(p0, p1, p2, p3); - if(intersect) { - context.beginPath(); - context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); - context.stroke(); - } - } - - function drawPoint(p) { - context.beginPath(); - context.arc(p.x, p.y, 10, 0, Math.PI * 2, false); - context.fill(); - } - - - function lineIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - if(denominator == 0) { - return null; - } - - return { - x: (B2 * C1 - B1 * C2) / denominator, - y: (A1 * C2 - A2 * C1) / denominator - } - } - - - function segmentIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - if(denominator == 0) { - return null; - } - - var intersectX = (B2 * C1 - B1 * C2) / denominator, - intersectY = (A1 * C2 - A2 * C1) / denominator, - rx0 = (intersectX - p0.x) / (p1.x - p0.x), - ry0 = (intersectY - p0.y) / (p1.y - p0.y), - rx1 = (intersectX - p2.x) / (p3.x - p2.x), - ry1 = (intersectY - p2.y) / (p3.y - p2.y); - - if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && - ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { - return { - x: intersectX, - y: intersectY - }; - } - else { - return null; - } - } + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var p0 = { + x: 100, + y: 100 + }, + p1 = { + x: 500, + y: 500 + }, + p2 = { + x: 600, + y: 50 + }, + p3 = { + x: 80, + y: 600 + }, + clickPoint; + + document.body.addEventListener("mousedown", onMouseDown); + + function onMouseDown(event) { + clickPoint = getClickPoint(event.clientX, event.clientY); + if(clickPoint) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + } + } + + function onMouseMove(event) { + clickPoint.x = event.clientX; + clickPoint.y = event.clientY; + render(); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + } + + function getClickPoint(x, y) { + var points = [p0, p1, p2, p3]; + for(var i = 0; i < points.length; i++) { + var p = points[i], + dx = p.x - x, + dy = p.y - y, + dist = Math.sqrt(dx * dx + dy * dy); + if(dist < 10) { + return p; + } + + } + } + + + render(); + + function render() { + context.clearRect(0, 0, width, height); + + drawPoint(p0); + drawPoint(p1); + drawPoint(p2); + drawPoint(p3); + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.moveTo(p2.x, p2.y); + context.lineTo(p3.x, p3.y); + context.stroke(); + + var intersect = segmentIntersect(p0, p1, p2, p3); + if(intersect) { + context.beginPath(); + context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); + context.stroke(); + } + } + + function drawPoint(p) { + context.beginPath(); + context.arc(p.x, p.y, 10, 0, Math.PI * 2, false); + context.fill(); + } + + + function lineIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + if(denominator == 0) { + return null; + } + + return { + x: (B2 * C1 - B1 * C2) / denominator, + y: (A1 * C2 - A2 * C1) / denominator + } + } + + + function segmentIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + if(denominator == 0) { + return null; + } + + var intersectX = (B2 * C1 - B1 * C2) / denominator, + intersectY = (A1 * C2 - A2 * C1) / denominator, + rx0 = (intersectX - p0.x) / (p1.x - p0.x), + ry0 = (intersectY - p0.y) / (p1.y - p0.y), + rx1 = (intersectX - p2.x) / (p3.x - p2.x), + ry1 = (intersectY - p2.y) / (p3.y - p2.y); + + if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && + ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { + return { + x: intersectX, + y: intersectY + }; + } + else { + return null; + } + } }; \ No newline at end of file diff --git a/episode33/parallel.js b/episode33/parallel.js index 7b95020..729d701 100644 --- a/episode33/parallel.js +++ b/episode33/parallel.js @@ -1,59 +1,59 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var p0 = { - x: 100, - y: 100 - }, - p1 = { - x: 500, - y: 100 - }, - p2 = { - x: 100, - y: 200 - }, - p3 = { - x: 500, - y: 200 - }; - - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.moveTo(p2.x, p2.y); - context.lineTo(p3.x, p3.y); - context.stroke(); - - var intersect = lineIntersect(p0, p1, p2, p3); - if(intersect) { - context.beginPath(); - context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); - context.stroke(); - } - - - function lineIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - if(denominator == 0) { - return null; - } - - return { - x: (B2 * C1 - B1 * C2) / denominator, - y: (A1 * C2 - A2 * C1) / denominator - } - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var p0 = { + x: 100, + y: 100 + }, + p1 = { + x: 500, + y: 100 + }, + p2 = { + x: 100, + y: 200 + }, + p3 = { + x: 500, + y: 200 + }; + + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.moveTo(p2.x, p2.y); + context.lineTo(p3.x, p3.y); + context.stroke(); + + var intersect = lineIntersect(p0, p1, p2, p3); + if(intersect) { + context.beginPath(); + context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); + context.stroke(); + } + + + function lineIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + if(denominator == 0) { + return null; + } + + return { + x: (B2 * C1 - B1 * C2) / denominator, + y: (A1 * C2 - A2 * C1) / denominator + } + } + }; \ No newline at end of file diff --git a/episode34/index.html b/episode34/index.html index a65ae57..6ee2159 100644 --- a/episode34/index.html +++ b/episode34/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode34/particles.js b/episode34/particles.js index 6dba81e..5c94f8c 100644 --- a/episode34/particles.js +++ b/episode34/particles.js @@ -1,108 +1,108 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var particle = { - x: width / 2, - y: height / 2, - vx: Math.random() * 10 - 5, - vy: Math.random() * 10 - 5 - }, - - lines = []; - - for(var i = 0; i < 10; i++) { - lines[i] = { - p0: { - x: Math.random() * width, - y: Math.random() * height - }, - p1: { - x: Math.random() * width, - y: Math.random() * height - } - } - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - drawLines(); - - var p0 = { - x: particle.x, - y: particle.y - }; - particle.x += particle.vx; - particle.y += particle.vy; - context.fillRect(particle.x - 2, particle.y - 2, 4, 4); - - var p1 = { - x: particle.x, - y: particle.y - }; - - - for(var i = 0; i < lines.length; i++) { - var p2 = lines[i].p0, - p3 = lines[i].p1; - - var intersect = segmentIntersect(p0, p1, p2, p3); - if(intersect) { - context.beginPath(); - context.strokeStyle = "red"; - context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); - context.stroke(); - return; - } - } - - - requestAnimationFrame(update); - } - - function drawLines() { - context.beginPath(); - for(var i = 0; i < lines.length; i++) { - context.moveTo(lines[i].p0.x, lines[i].p0.y); - context.lineTo(lines[i].p1.x, lines[i].p1.y); - } - context.stroke(); - } - - function segmentIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - if(denominator == 0) { - return null; - } - - var intersectX = (B2 * C1 - B1 * C2) / denominator, - intersectY = (A1 * C2 - A2 * C1) / denominator, - rx0 = (intersectX - p0.x) / (p1.x - p0.x), - ry0 = (intersectY - p0.y) / (p1.y - p0.y), - rx1 = (intersectX - p2.x) / (p3.x - p2.x), - ry1 = (intersectY - p2.y) / (p3.y - p2.y); - - if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && - ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { - return { - x: intersectX, - y: intersectY - }; - } - else { - return null; - } - } + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var particle = { + x: width / 2, + y: height / 2, + vx: Math.random() * 10 - 5, + vy: Math.random() * 10 - 5 + }, + + lines = []; + + for(var i = 0; i < 10; i++) { + lines[i] = { + p0: { + x: Math.random() * width, + y: Math.random() * height + }, + p1: { + x: Math.random() * width, + y: Math.random() * height + } + } + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + drawLines(); + + var p0 = { + x: particle.x, + y: particle.y + }; + particle.x += particle.vx; + particle.y += particle.vy; + context.fillRect(particle.x - 2, particle.y - 2, 4, 4); + + var p1 = { + x: particle.x, + y: particle.y + }; + + + for(var i = 0; i < lines.length; i++) { + var p2 = lines[i].p0, + p3 = lines[i].p1; + + var intersect = segmentIntersect(p0, p1, p2, p3); + if(intersect) { + context.beginPath(); + context.strokeStyle = "red"; + context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false); + context.stroke(); + return; + } + } + + + requestAnimationFrame(update); + } + + function drawLines() { + context.beginPath(); + for(var i = 0; i < lines.length; i++) { + context.moveTo(lines[i].p0.x, lines[i].p0.y); + context.lineTo(lines[i].p1.x, lines[i].p1.y); + } + context.stroke(); + } + + function segmentIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + if(denominator == 0) { + return null; + } + + var intersectX = (B2 * C1 - B1 * C2) / denominator, + intersectY = (A1 * C2 - A2 * C1) / denominator, + rx0 = (intersectX - p0.x) / (p1.x - p0.x), + ry0 = (intersectY - p0.y) / (p1.y - p0.y), + rx1 = (intersectX - p2.x) / (p3.x - p2.x), + ry1 = (intersectY - p2.y) / (p3.y - p2.y); + + if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && + ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { + return { + x: intersectX, + y: intersectY + }; + } + else { + return null; + } + } }; \ No newline at end of file diff --git a/episode34/shapes.js b/episode34/shapes.js index 3109bf4..c20f073 100644 --- a/episode34/shapes.js +++ b/episode34/shapes.js @@ -1,149 +1,149 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - - - var star0 = { - x: 200, - y: 200, - points: [ - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 } - ], - offset: [ - { x: 100, y: 0}, - { x: 40, y: 29}, - { x: 31, y: 95}, - { x: -15, y: 48}, - { x: -81, y: 59}, - { x: -50, y: 0}, - { x: -81, y: -59}, - { x: -15, y: -48}, - { x: 31, y: -95}, - { x: 40, y: -29} - ] - }; - var star1 = { - x: 600, - y: 500, - points: [ - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 }, - {x: 0, y: 0 } - ], - offset: [ - { x: 100, y: 0}, - { x: 40, y: 29}, - { x: 31, y: 95}, - { x: -15, y: 48}, - { x: -81, y: 59}, - { x: -50, y: 0}, - { x: -81, y: -59}, - { x: -15, y: -48}, - { x: 31, y: -95}, - { x: 40, y: -29} - ] - }; - - document.body.addEventListener("mousemove", function(event) { - context.clearRect(0, 0, width, height); - star0.x = event.clientX; - star0.y = event.clientY; - updateStar(star0); - updateStar(star1); - if(checkStarCollision(star0, star1)) { - context.fillStyle = "red"; - } - else { - context.fillStyle = "black"; - } - drawStar(star0); - drawStar(star1); - }); - - function checkStarCollision(starA, starB) { - for(var i = 0; i < starA.points.length; i++) { - var p0 = starA.points[i], - p1 = starA.points[(i + 1) % starA.points.length]; - - for(var j = 0; j < starB.points.length; j++) { - var p2 = starB.points[j], - p3 = starB.points[(j + 1) % starB.points.length]; - - if(segmentIntersect(p0, p1, p2, p3)) { - return true; - } - } - } - return false; - } - - - function updateStar(star) { - for(var i = 0; i < star.points.length; i++) { - star.points[i].x = star.x + star.offset[i].x; - star.points[i].y = star.y + star.offset[i].y; - } - } - - function drawStar(star) { - context.beginPath(); - context.moveTo(star.points[0].x, star.points[0].y); - for(var i = 1; i < star.points.length; i++) { - context.lineTo(star.points[i].x, star.points[i].y); - } - context.closePath(); - context.fill(); - } - - function segmentIntersect(p0, p1, p2, p3) { - var A1 = p1.y - p0.y, - B1 = p0.x - p1.x, - C1 = A1 * p0.x + B1 * p0.y, - A2 = p3.y - p2.y, - B2 = p2.x - p3.x, - C2 = A2 * p2.x + B2 * p2.y, - denominator = A1 * B2 - A2 * B1; - - if(denominator == 0) { - return null; - } - - var intersectX = (B2 * C1 - B1 * C2) / denominator, - intersectY = (A1 * C2 - A2 * C1) / denominator, - rx0 = (intersectX - p0.x) / (p1.x - p0.x), - ry0 = (intersectY - p0.y) / (p1.y - p0.y), - rx1 = (intersectX - p2.x) / (p3.x - p2.x), - ry1 = (intersectY - p2.y) / (p3.y - p2.y); - - if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && - ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { - return { - x: intersectX, - y: intersectY - }; - } - else { - return null; - } - } + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + + + var star0 = { + x: 200, + y: 200, + points: [ + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 } + ], + offset: [ + { x: 100, y: 0}, + { x: 40, y: 29}, + { x: 31, y: 95}, + { x: -15, y: 48}, + { x: -81, y: 59}, + { x: -50, y: 0}, + { x: -81, y: -59}, + { x: -15, y: -48}, + { x: 31, y: -95}, + { x: 40, y: -29} + ] + }; + var star1 = { + x: 600, + y: 500, + points: [ + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 }, + {x: 0, y: 0 } + ], + offset: [ + { x: 100, y: 0}, + { x: 40, y: 29}, + { x: 31, y: 95}, + { x: -15, y: 48}, + { x: -81, y: 59}, + { x: -50, y: 0}, + { x: -81, y: -59}, + { x: -15, y: -48}, + { x: 31, y: -95}, + { x: 40, y: -29} + ] + }; + + document.body.addEventListener("mousemove", function(event) { + context.clearRect(0, 0, width, height); + star0.x = event.clientX; + star0.y = event.clientY; + updateStar(star0); + updateStar(star1); + if(checkStarCollision(star0, star1)) { + context.fillStyle = "red"; + } + else { + context.fillStyle = "black"; + } + drawStar(star0); + drawStar(star1); + }); + + function checkStarCollision(starA, starB) { + for(var i = 0; i < starA.points.length; i++) { + var p0 = starA.points[i], + p1 = starA.points[(i + 1) % starA.points.length]; + + for(var j = 0; j < starB.points.length; j++) { + var p2 = starB.points[j], + p3 = starB.points[(j + 1) % starB.points.length]; + + if(segmentIntersect(p0, p1, p2, p3)) { + return true; + } + } + } + return false; + } + + + function updateStar(star) { + for(var i = 0; i < star.points.length; i++) { + star.points[i].x = star.x + star.offset[i].x; + star.points[i].y = star.y + star.offset[i].y; + } + } + + function drawStar(star) { + context.beginPath(); + context.moveTo(star.points[0].x, star.points[0].y); + for(var i = 1; i < star.points.length; i++) { + context.lineTo(star.points[i].x, star.points[i].y); + } + context.closePath(); + context.fill(); + } + + function segmentIntersect(p0, p1, p2, p3) { + var A1 = p1.y - p0.y, + B1 = p0.x - p1.x, + C1 = A1 * p0.x + B1 * p0.y, + A2 = p3.y - p2.y, + B2 = p2.x - p3.x, + C2 = A2 * p2.x + B2 * p2.y, + denominator = A1 * B2 - A2 * B1; + + if(denominator == 0) { + return null; + } + + var intersectX = (B2 * C1 - B1 * C2) / denominator, + intersectY = (A1 * C2 - A2 * C1) / denominator, + rx0 = (intersectX - p0.x) / (p1.x - p0.x), + ry0 = (intersectY - p0.y) / (p1.y - p0.y), + rx1 = (intersectX - p2.x) / (p3.x - p2.x), + ry1 = (intersectY - p2.y) / (p3.y - p2.y); + + if(((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && + ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) { + return { + x: intersectX, + y: intersectY + }; + } + else { + return null; + } + } }; \ No newline at end of file diff --git a/episode35/index.html b/episode35/index.html index 6a8460a..53e9646 100644 --- a/episode35/index.html +++ b/episode35/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode35/koch.js b/episode35/koch.js index 938491c..f4552b9 100644 --- a/episode35/koch.js +++ b/episode35/koch.js @@ -1,62 +1,62 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var p0 = { - x: 0, - y: -321 - }, - p1 = { - x: 278, - y: 160 - }, - p2 = { - x: -278, - y: 160 - }; - context.translate(width / 2, height / 2); - - koch(p0, p1, 5); - koch(p1, p2, 5); - koch(p2, p0, 5); - - function koch(p0, p1, limit) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y, - dist = Math.sqrt(dx * dx + dy * dy), - unit = dist / 3, - angle = Math.atan2(dy, dx), - pA = { - x: p0.x + dx / 3, - y: p0.y + dy / 3 - }, - pC = { - x: p1.x - dx / 3, - y: p1.y - dy / 3 - }, - pB = { - x: pA.x + Math.cos(angle - Math.PI / 3) * unit, - y: pA.y + Math.sin(angle - Math.PI / 3) * unit - }; - - if(limit > 0) { - koch(p0, pA, limit - 1); - koch(pA, pB, limit - 1); - koch(pB, pC, limit - 1); - koch(pC, p1, limit - 1); - } - else { - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.lineTo(pC.x, pC.y); - context.lineTo(p1.x, p1.y); - context.stroke(); - } - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var p0 = { + x: 0, + y: -321 + }, + p1 = { + x: 278, + y: 160 + }, + p2 = { + x: -278, + y: 160 + }; + context.translate(width / 2, height / 2); + + koch(p0, p1, 5); + koch(p1, p2, 5); + koch(p2, p0, 5); + + function koch(p0, p1, limit) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y, + dist = Math.sqrt(dx * dx + dy * dy), + unit = dist / 3, + angle = Math.atan2(dy, dx), + pA = { + x: p0.x + dx / 3, + y: p0.y + dy / 3 + }, + pC = { + x: p1.x - dx / 3, + y: p1.y - dy / 3 + }, + pB = { + x: pA.x + Math.cos(angle - Math.PI / 3) * unit, + y: pA.y + Math.sin(angle - Math.PI / 3) * unit + }; + + if(limit > 0) { + koch(p0, pA, limit - 1); + koch(pA, pB, limit - 1); + koch(pB, pC, limit - 1); + koch(pC, p1, limit - 1); + } + else { + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.lineTo(pC.x, pC.y); + context.lineTo(p1.x, p1.y); + context.stroke(); + } + } + }; \ No newline at end of file diff --git a/episode35/kochanimated.js b/episode35/kochanimated.js index 3dbe089..2f0c938 100644 --- a/episode35/kochanimated.js +++ b/episode35/kochanimated.js @@ -1,78 +1,78 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - - - var p0 = { - x: 0, - y: -321 - }, - p1 = { - x: 278, - y: 160 - }, - p2 = { - x: -278, - y: 160 - }; - - var a = 0, - t; - - draw(); - - function draw() { - t = 1 / 3 + Math.sin(a += 0.02) * 1/6; - context.clearRect(0, 0, width, height); - context.save(); - context.translate(width / 2, height / 2); - koch(p0, p1, 5); - koch(p1, p2, 5); - koch(p2, p0, 5); - context.restore(); - requestAnimationFrame(draw); - } - - function koch(p0, p1, limit) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y, - dist = Math.sqrt(dx * dx + dy * dy), - unit = dist * t, - angle = Math.atan2(dy, dx), - pA = { - x: p0.x + dx * t, - y: p0.y + dy * t - }, - pC = { - x: p1.x - dx * t, - y: p1.y - dy * t - }, - pB = { - x: pA.x + Math.cos(angle - Math.PI * t) * unit, - y: pA.y + Math.sin(angle - Math.PI * t) * unit - }; - - - if(limit > 0) { - koch(p0, pA, limit - 1); - koch(pA, pB, limit - 1); - koch(pB, pC, limit - 1); - koch(pC, p1, limit - 1); - } - else { - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(pA.x, pA.y); - context.lineTo(pB.x, pB.y); - context.lineTo(pC.x, pC.y); - context.lineTo(p1.x, p1.y); - context.stroke(); - } - } - - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + + + var p0 = { + x: 0, + y: -321 + }, + p1 = { + x: 278, + y: 160 + }, + p2 = { + x: -278, + y: 160 + }; + + var a = 0, + t; + + draw(); + + function draw() { + t = 1 / 3 + Math.sin(a += 0.02) * 1/6; + context.clearRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + koch(p0, p1, 5); + koch(p1, p2, 5); + koch(p2, p0, 5); + context.restore(); + requestAnimationFrame(draw); + } + + function koch(p0, p1, limit) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y, + dist = Math.sqrt(dx * dx + dy * dy), + unit = dist * t, + angle = Math.atan2(dy, dx), + pA = { + x: p0.x + dx * t, + y: p0.y + dy * t + }, + pC = { + x: p1.x - dx * t, + y: p1.y - dy * t + }, + pB = { + x: pA.x + Math.cos(angle - Math.PI * t) * unit, + y: pA.y + Math.sin(angle - Math.PI * t) * unit + }; + + + if(limit > 0) { + koch(p0, pA, limit - 1); + koch(pA, pB, limit - 1); + koch(pB, pC, limit - 1); + koch(pC, p1, limit - 1); + } + else { + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(pA.x, pA.y); + context.lineTo(pB.x, pB.y); + context.lineTo(pC.x, pC.y); + context.lineTo(p1.x, p1.y); + context.stroke(); + } + } + + }; \ No newline at end of file diff --git a/episode35/sierpinski.js b/episode35/sierpinski.js index 5dabe8f..581efa0 100644 --- a/episode35/sierpinski.js +++ b/episode35/sierpinski.js @@ -1,56 +1,56 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - context.translate(width / 2, height / 2); - var p0 = { - x: 0, - y: -321 - }, - p1 = { - x: 278, - y: 160 - }, - p2 = { - x: -278, - y: 160 - }; - - sierpinski(p0, p1, p2, 8); - - function sierpinski(p0, p1, p2, limit) { - if(limit > 0) { - var pA = { - x: (p0.x + p1.x) / 2, - y: (p0.y + p1.y) / 2 - }, - pB = { - x: (p1.x + p2.x) / 2, - y: (p1.y + p2.y) / 2 - }, - pC = { - x: (p2.x + p0.x) / 2, - y: (p2.y + p0.y) / 2 - }; - - sierpinski(p0, pA, pC, limit - 1); - sierpinski(pA, p1, pB, limit - 1); - sierpinski(pC, pB, p2, limit - 1); - } - else { - drawTriangle(p0, p1, p2); - } - } - - function drawTriangle(p0, p1, p2) { - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.fill(); - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + context.translate(width / 2, height / 2); + var p0 = { + x: 0, + y: -321 + }, + p1 = { + x: 278, + y: 160 + }, + p2 = { + x: -278, + y: 160 + }; + + sierpinski(p0, p1, p2, 8); + + function sierpinski(p0, p1, p2, limit) { + if(limit > 0) { + var pA = { + x: (p0.x + p1.x) / 2, + y: (p0.y + p1.y) / 2 + }, + pB = { + x: (p1.x + p2.x) / 2, + y: (p1.y + p2.y) / 2 + }, + pC = { + x: (p2.x + p0.x) / 2, + y: (p2.y + p0.y) / 2 + }; + + sierpinski(p0, pA, pC, limit - 1); + sierpinski(pA, p1, pB, limit - 1); + sierpinski(pC, pB, p2, limit - 1); + } + else { + drawTriangle(p0, p1, p2); + } + } + + function drawTriangle(p0, p1, p2) { + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.fill(); + } + }; \ No newline at end of file diff --git a/episode35/twist.js b/episode35/twist.js index d2be611..ee43ef0 100644 --- a/episode35/twist.js +++ b/episode35/twist.js @@ -1,71 +1,71 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - - - var p0 = { - x: 0, - y: -321 - }, - p1 = { - x: 278, - y: 160 - }, - p2 = { - x: -278, - y: 160 - }; - var a = 0, - b = 0, - r = 0, - tx, ty; - - draw(); - function draw() { - context.clearRect(0, 0, width, height); - context.save(); - context.translate(width / 2, height / 2); - context.rotate(r += 0.01); - tx = .5 + Math.sin(a += .045) * .25; - ty = .5 + Math.sin(b += .045) * .25; - sierpinski(p0, p1, p2, 7); - context.restore(); - requestAnimationFrame(draw); - } - - function sierpinski(p0, p1, p2, limit) { - if(limit > 0) { - var pA = { - x: p0.x + (p1.x - p0.x) * tx, - y: p0.y + (p1.y - p0.y) * ty - }, - pB = { - x: p1.x + (p2.x - p1.x) * tx, - y: p1.y + (p2.y - p1.y) * ty - }, - pC = { - x: p2.x + (p0.x - p2.x) * tx, - y: p2.y + (p0.y - p2.y) * ty - }; - sierpinski(p0, pA, pC, limit - 1); - sierpinski(pA, p1, pB, limit - 1); - sierpinski(pC, pB, p2, limit - 1); - } - else { - drawTriangle(p0, p1, p2); - } - } - - function drawTriangle(p0, p1, p2) { - context.beginPath(); - context.moveTo(p0.x, p0.y); - context.lineTo(p1.x, p1.y); - context.lineTo(p2.x, p2.y); - context.fill(); - } - + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + + + var p0 = { + x: 0, + y: -321 + }, + p1 = { + x: 278, + y: 160 + }, + p2 = { + x: -278, + y: 160 + }; + var a = 0, + b = 0, + r = 0, + tx, ty; + + draw(); + function draw() { + context.clearRect(0, 0, width, height); + context.save(); + context.translate(width / 2, height / 2); + context.rotate(r += 0.01); + tx = .5 + Math.sin(a += .045) * .25; + ty = .5 + Math.sin(b += .045) * .25; + sierpinski(p0, p1, p2, 7); + context.restore(); + requestAnimationFrame(draw); + } + + function sierpinski(p0, p1, p2, limit) { + if(limit > 0) { + var pA = { + x: p0.x + (p1.x - p0.x) * tx, + y: p0.y + (p1.y - p0.y) * ty + }, + pB = { + x: p1.x + (p2.x - p1.x) * tx, + y: p1.y + (p2.y - p1.y) * ty + }, + pC = { + x: p2.x + (p0.x - p2.x) * tx, + y: p2.y + (p0.y - p2.y) * ty + }; + sierpinski(p0, pA, pC, limit - 1); + sierpinski(pA, p1, pB, limit - 1); + sierpinski(pC, pB, p2, limit - 1); + } + else { + drawTriangle(p0, p1, p2); + } + } + + function drawTriangle(p0, p1, p2) { + context.beginPath(); + context.moveTo(p0.x, p0.y); + context.lineTo(p1.x, p1.y); + context.lineTo(p2.x, p2.y); + context.fill(); + } + }; \ No newline at end of file diff --git a/episode36/index.html b/episode36/index.html index 5989d5a..b211694 100644 --- a/episode36/index.html +++ b/episode36/index.html @@ -1,23 +1,23 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode36/main.js b/episode36/main.js index dd2b98c..b0b9c6d 100644 --- a/episode36/main.js +++ b/episode36/main.js @@ -1,70 +1,70 @@ - -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var points = [], - bounce = 0.9, - gravity = 0.5, - friction = 0.999; - - points.push({ - x: 100, - y: 100, - oldx: 95, - oldy: 95 - }); - - - - update(); - - function update() { - updatePoints(); - renderPoints(); - requestAnimationFrame(update); - } - - function updatePoints() { - for(var i = 0; i < points.length; i++) { - var p = points[i], - vx = (p.x - p.oldx) * friction; - vy = (p.y - p.oldy) * friction; - - p.oldx = p.x; - p.oldy = p.y; - p.x += vx; - p.y += vy; - p.y += gravity; - - if(p.x > width) { - p.x = width; - p.oldx = p.x + vx * bounce; - } - else if(p.x < 0) { - p.x = 0; - p.oldx = p.x + vx * bounce; - } - if(p.y > height) { - p.y = height; - p.oldy = p.y + vy * bounce; - } - else if(p.y < 0) { - p.y = 0; - p.oldy = p.y + vy * bounce; - } - } - } - - function renderPoints() { - context.clearRect(0, 0, width, height); - for(var i = 0; i < points.length; i++) { - var p = points[i]; - context.beginPath(); - context.arc(p.x, p.y, 5, 0, Math.PI * 2); - context.fill(); - } - } + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var points = [], + bounce = 0.9, + gravity = 0.5, + friction = 0.999; + + points.push({ + x: 100, + y: 100, + oldx: 95, + oldy: 95 + }); + + + + update(); + + function update() { + updatePoints(); + renderPoints(); + requestAnimationFrame(update); + } + + function updatePoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + vx = (p.x - p.oldx) * friction; + vy = (p.y - p.oldy) * friction; + + p.oldx = p.x; + p.oldy = p.y; + p.x += vx; + p.y += vy; + p.y += gravity; + + if(p.x > width) { + p.x = width; + p.oldx = p.x + vx * bounce; + } + else if(p.x < 0) { + p.x = 0; + p.oldx = p.x + vx * bounce; + } + if(p.y > height) { + p.y = height; + p.oldy = p.y + vy * bounce; + } + else if(p.y < 0) { + p.y = 0; + p.oldy = p.y + vy * bounce; + } + } + } + + function renderPoints() { + context.clearRect(0, 0, width, height); + for(var i = 0; i < points.length; i++) { + var p = points[i]; + context.beginPath(); + context.arc(p.x, p.y, 5, 0, Math.PI * 2); + context.fill(); + } + } }; \ No newline at end of file diff --git a/episode38/cat.jpg b/episode38/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..140642815ad6a508f9fc3f697d32a77287502cbf GIT binary patch literal 46674 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

(3DQ)sU9J01=cAwqpYq)7C9Lx)-iJU+ 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 width) { + p.x = width; + p.oldx = p.x + vx * bounce; + } + else if(p.x < 0) { + p.x = 0; + p.oldx = p.x + vx * bounce; + } + if(p.y > height) { + p.y = height; + p.oldy = p.y + vy * bounce; + } + else if(p.y < 0) { + p.y = 0; + p.oldy = p.y + vy * bounce; + } + } + } + + function updateSticks() { + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i], + dx = s.p1.x - s.p0.x, + dy = s.p1.y - s.p0.y, + distance = Math.sqrt(dx * dx + dy * dy), + difference = s.length - distance, + percent = difference / distance / 2, + offsetX = dx * percent, + offsetY = dy * percent; + + s.p0.x -= offsetX; + s.p0.y -= offsetY; + s.p1.x += offsetX; + s.p1.y += offsetY; + } + } + + function renderPoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i]; + context.beginPath(); + context.arc(p.x, p.y, 5, 0, Math.PI * 2); + context.fill(); + } + } + + function renderSticks() { + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i]; + if(!s.hidden) { + context.beginPath(); + context.strokeStyle = s.color ? s.color : "black"; + context.lineWidth = s.width ? s.width : 1; + context.moveTo(s.p0.x, s.p0.y); + context.lineTo(s.p1.x, s.p1.y); + context.stroke(); + } + } + } + + function renderForms() { + for(var i = 0; i < forms.length; i++) { + var f = forms[i]; + context.beginPath(); + context.fillStyle = f.color; + context.moveTo(f.path[0].x, f.path[0].y); + for(var j = 1; j < f.path.length; j++) { + context.lineTo(f.path[j].x, f.path[j].y); + } + context.fill(); + } + } + + function renderImages() { + for(var i = 0; i < images.length; i++) { + var img = images[i]; + if(img.img) { + context.save(); + context.translate(img.path[0].x, img.path[0].y); + + var w = distance(img.path[1], img.path[0]), + h = distance(img.path[3], img.path[0]), + dx = img.path[1].x - img.path[0].x, + dy = img.path[1].y - img.path[0].y, + angle = Math.atan2(dy, dx); + + context.rotate(angle); + context.drawImage(img.img, 0, 0, w, h); + context.restore(); + } + } + } + +}; \ No newline at end of file diff --git a/episode38/index.html b/episode38/index.html new file mode 100644 index 0000000..b211694 --- /dev/null +++ b/episode38/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/episode38/main.js b/episode38/main.js new file mode 100644 index 0000000..ae47f31 --- /dev/null +++ b/episode38/main.js @@ -0,0 +1,227 @@ + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var points = [], + sticks = [], + forms = [], + images = [], + bounce = 0.9, + gravity = 0.5, + friction = 0.999; + + points.push({ + x: 100, + y: 100, + oldx: 100 + Math.random() * 50 - 25, + oldy: 100 + Math.random() * 50 - 25 + }); + points.push({ + x: 200, + y: 100, + oldx: 200, + oldy: 100 + }); + points.push({ + x: 200, + y: 200, + oldx: 200, + oldy: 200 + }); + points.push({ + x: 100, + y: 200, + oldx: 100, + oldy: 200 + }); + + sticks.push({ + p0: points[0], + p1: points[1], + length: distance(points[0], points[1]), + color: "red", + width: 5 + }); + sticks.push({ + p0: points[1], + p1: points[2], + length: distance(points[1], points[2]) + }); + sticks.push({ + p0: points[2], + p1: points[3], + length: distance(points[2], points[3]) + }); + sticks.push({ + p0: points[3], + p1: points[0], + length: distance(points[3], points[0]) + }); + sticks.push({ + p0: points[0], + p1: points[2], + length: distance(points[0], points[2]), + hidden: true + }); + + forms.push({ + path: [ + points[0], + points[1], + points[2], + points[3] + ], + color: "green" + }); + + images.push({ + path: [ + points[0], + points[1], + points[2], + points[3] + ], + img: loadImage("cat.jpg") + }); + + function loadImage(url) { + var img = document.createElement("img"); + img.src = url; + return img; + } + + function distance(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + } + + update(); + + function update() { + updatePoints(); + for(var i = 0; i < 5; i++) { + updateSticks(); + constrainPoints(); + } + context.clearRect(0, 0, width, height); + // renderPoints(); + // renderSticks(); + renderForms(); + // renderImages(); + requestAnimationFrame(update); + } + + function updatePoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + vx = (p.x - p.oldx) * friction; + vy = (p.y - p.oldy) * friction; + + p.oldx = p.x; + p.oldy = p.y; + p.x += vx; + p.y += vy; + p.y += gravity; + } + } + + function constrainPoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + vx = (p.x - p.oldx) * friction; + vy = (p.y - p.oldy) * friction; + + if(p.x > width) { + p.x = width; + p.oldx = p.x + vx * bounce; + } + else if(p.x < 0) { + p.x = 0; + p.oldx = p.x + vx * bounce; + } + if(p.y > height) { + p.y = height; + p.oldy = p.y + vy * bounce; + } + else if(p.y < 0) { + p.y = 0; + p.oldy = p.y + vy * bounce; + } + } + } + + function updateSticks() { + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i], + dx = s.p1.x - s.p0.x, + dy = s.p1.y - s.p0.y, + distance = Math.sqrt(dx * dx + dy * dy), + difference = s.length - distance, + percent = difference / distance / 2, + offsetX = dx * percent, + offsetY = dy * percent; + + s.p0.x -= offsetX; + s.p0.y -= offsetY; + s.p1.x += offsetX; + s.p1.y += offsetY; + } + } + + function renderPoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i]; + context.beginPath(); + context.arc(p.x, p.y, 5, 0, Math.PI * 2); + context.fill(); + } + } + + function renderSticks() { + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i]; + if(!s.hidden) { + context.beginPath(); + context.strokeStyle = s.color ? s.color : "black"; + context.lineWidth = s.width ? s.width : 1; + context.moveTo(s.p0.x, s.p0.y); + context.lineTo(s.p1.x, s.p1.y); + context.stroke(); + } + } + } + + function renderForms() { + for(var i = 0; i < forms.length; i++) { + var f = forms[i]; + context.beginPath(); + context.fillStyle = f.color; + context.moveTo(f.path[0].x, f.path[0].y); + for(var j = 1; j < f.path.length; j++) { + context.lineTo(f.path[j].x, f.path[j].y); + } + context.fill(); + } + } + + function renderImages() { + for(var i = 0; i < images.length; i++) { + var image = images[i], + w = distance(image.path[0], image.path[1]), + h = distance(image.path[0], image.path[3]), + dx = image.path[1].x - image.path[0].x, + dy = image.path[1].y - image.path[0].y, + angle = Math.atan2(dy, dx); + + context.save(); + context.translate(image.path[0].x, image.path[0].y); + context.rotate(angle); + context.drawImage(image.img, 0, 0, w, h); + context.restore(); + } + } +}; \ No newline at end of file diff --git a/episode38/ragdoll.js b/episode38/ragdoll.js new file mode 100644 index 0000000..42b312b --- /dev/null +++ b/episode38/ragdoll.js @@ -0,0 +1,262 @@ + +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + var count = 0; + + var points = [], + sticks = []; + gravity = 0.25, + bounce = 0.9, + friction = 0.999; + + points.push({ + x: 90, + y: 100, + oldx: 90 + Math.random() * 20 - 10, + oldy: 100 + }); + points.push({ + x: 210, + y: 100, + oldx: 210, + oldy: 100 + }); + points.push({ + x: 200, + y: 300, + oldx: 200, + oldy: 300 + }); + points.push({ + x: 100, + y: 300, + oldx: 100, + oldy: 300 + }); + // arms + points.push({ + x: 10, + y: 170, + oldx: 10, + oldy: 170 + }); + points.push({ + x: 290, + y: 170, + oldx: 290, + oldy: 170 + }); + // legs + points.push({ + x: 70, + y: 400, + oldx: 70, + oldy: 400 + }); + points.push({ + x: 230, + y: 400, + oldx: 230, + oldy: 400 + }); + // hands + points.push({ + x: 10, + y: 230, + oldx: 10, + oldy: 230 + }); + points.push({ + x: 290, + y: 230, + oldx: 290, + oldy: 230 + }); + + sticks.push({ + p0: points[0], + p1: points[1], + length: distance(points[0], points[1]), + visible: true + }); + sticks.push({ + p0: points[1], + p1: points[2], + length: distance(points[1], points[2]), + visible: true + }); + sticks.push({ + p0: points[2], + p1: points[3], + length: distance(points[2], points[3]), + visible: true + }); + sticks.push({ + p0: points[3], + p1: points[0], + length: distance(points[3], points[0]), + visible: true + }); + sticks.push({ + p0: points[0], + p1: points[2], + length: distance(points[0], points[2]), + visible: false + }); + // arms + sticks.push({ + p0: points[0], + p1: points[4], + length: distance(points[0], points[4]), + visible: true + }); + // sticks.push({ + // p0: points[4], + // p1: points[1], + // length: distance(points[4], points[1]), + // visible: false + // }); + sticks.push({ + p0: points[1], + p1: points[5], + length: distance(points[1], points[5]), + visible: true + }); + // sticks.push({ + // p0: points[5], + // p1: points[0], + // length: distance(points[5], points[0]), + // visible: false + // }); + // legs + sticks.push({ + p0: points[3], + p1: points[6], + length: distance(points[3], points[6]), + visible: true + }); + sticks.push({ + p0: points[6], + p1: points[2], + length: distance(points[6], points[2]), + visible: false + }); + sticks.push({ + p0: points[2], + p1: points[7], + length: distance(points[2], points[7]), + visible: true + }); + sticks.push({ + p0: points[7], + p1: points[3], + length: distance(points[7], points[3]), + visible: false + }); + // arms + sticks.push({ + p0: points[4], + p1: points[8], + length: distance(points[4], points[8]), + visible: true + }); + sticks.push({ + p0: points[5], + p1: points[9], + length: distance(points[5], points[9]), + visible: true + }); + + + function distance(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + } + + + update(); + + function update() { + updatePoints(); + + for(var i = 0; i < 3; i++) { + updateSticks(); + constrainPoints(); + } + render(); + requestAnimationFrame(update); + } + + function updatePoints() { + for(var i = 0; i < points.length; i++) { + var p = points[i], + vx = (p.x - p.oldx) * friction; + vy = (p.y - p.oldy) * friction; + p.oldx = p.x; + p.oldy = p.y; + p.x += vx; + p.y += vy; + p.y += gravity; + } + } + + function constrainPoints() { + + for(var i = 0; i < points.length; i++) { + var p = points[i]; + if(p.x > width) { + p.x = width; + p.oldx = p.x + (p.x - p.oldx) * bounce; + } + else if(p.x < 0) { + p.x = 0; + p.oldx = p.x + (p.x - p.oldx) * bounce; + } + if(p.y > height) { + p.y = height; + p.oldy = p.y + (p.y - p.oldy) * bounce; + } + if(p.y < 0) { + p.y = 0; + p.oldy = p.y + (p.y - p.oldy) * bounce; + } + } + } + + function updateSticks() { + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i], + dx = s.p1.x - s.p0.x, + dy = s.p1.y - s.p0.y, + dist = Math.sqrt(dx * dx + dy * dy); + ratio = s.length / dist, + midx = s.p0.x + dx / 2, + midy = s.p0.y + dy / 2, + offsetx = dx / 2 * ratio, + offsety = dy / 2 * ratio; + + s.p0.x = midx - offsetx; + s.p0.y = midy - offsety; + s.p1.x = midx + offsetx; + s.p1.y = midy + offsety; + } + } + + function render() { + context.clearRect(0, 0, width, height); + context.beginPath(); + for(var i = 0; i < sticks.length; i++) { + var s = sticks[i]; + if(s.visible) { + context.moveTo(s.p0.x, s.p0.y); + context.lineTo(s.p1.x, s.p1.y); + } + } + context.stroke(); + } + +}; \ No newline at end of file diff --git a/episode4/bees.js b/episode4/bees.js index fe75757..1a8d557 100644 --- a/episode4/bees.js +++ b/episode4/bees.js @@ -1,53 +1,53 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - bees = [], - numBees = 50; - - var bee = { - create: function() { - var obj = Object.create(this); - obj.init.apply(obj, arguments); - return obj; - }, - - init: function(foo, bar) { - console.log(foo, bar); - this.angleX = Math.random() * Math.PI * 2; - this.angleY = Math.random() * Math.PI * 2; - this.speedX = Math.random() * .1 - .05; - this.speedY = Math.random() * .1 - .05; - this.radius = 100 + Math.random() * 100; - }, - - update: function() { - var x = Math.cos(this.angleX) * this.radius, - y = Math.sin(this.angleY) * this.radius; - this.angleX += this.speedX; - this.angleY += this.speedY; - - context.beginPath(); - context.arc(width / 2 + x, height / 2 + y, 2, 0, Math.PI * 2, false); - context.fill(); - } - } - - for(var i = 0; i < numBees; i += 1) { - bees.push(bee.create("foo", "bar")); - } - - - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - for(var i = 0; i < numBees; i += 1) { - bees[i].update(); - } - requestAnimationFrame(draw); - } - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + bees = [], + numBees = 50; + + var bee = { + create: function() { + var obj = Object.create(this); + obj.init.apply(obj, arguments); + return obj; + }, + + init: function(foo, bar) { + console.log(foo, bar); + this.angleX = Math.random() * Math.PI * 2; + this.angleY = Math.random() * Math.PI * 2; + this.speedX = Math.random() * .1 - .05; + this.speedY = Math.random() * .1 - .05; + this.radius = 100 + Math.random() * 100; + }, + + update: function() { + var x = Math.cos(this.angleX) * this.radius, + y = Math.sin(this.angleY) * this.radius; + this.angleX += this.speedX; + this.angleY += this.speedY; + + context.beginPath(); + context.arc(width / 2 + x, height / 2 + y, 2, 0, Math.PI * 2, false); + context.fill(); + } + } + + for(var i = 0; i < numBees; i += 1) { + bees.push(bee.create("foo", "bar")); + } + + + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + for(var i = 0; i < numBees; i += 1) { + bees[i].update(); + } + requestAnimationFrame(draw); + } + + } \ No newline at end of file diff --git a/episode4/circle.js b/episode4/circle.js index 538472c..1d63a86 100644 --- a/episode4/circle.js +++ b/episode4/circle.js @@ -1,25 +1,25 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - centerX = width / 2, - centerY = height / 2, - radius = 200, - angle = 0, - numObjects = 20, - slice = Math.PI * 2 / numObjects, - x, y; - - for(var i = 0; i < numObjects; i += 1) { - angle = i * slice; - x = centerX + Math.cos(angle) * radius; - y = centerY + Math.sin(angle) * radius; - context.beginPath(); - context.arc(x, y, 10, 0, Math.PI * 2, false); - context.fill(); - } - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + centerX = width / 2, + centerY = height / 2, + radius = 200, + angle = 0, + numObjects = 20, + slice = Math.PI * 2 / numObjects, + x, y; + + for(var i = 0; i < numObjects; i += 1) { + angle = i * slice; + x = centerX + Math.cos(angle) * radius; + y = centerY + Math.sin(angle) * radius; + context.beginPath(); + context.arc(x, y, 10, 0, Math.PI * 2, false); + context.fill(); + } + + }; \ No newline at end of file diff --git a/episode4/code.js b/episode4/code.js index f59e09f..1ee936a 100644 --- a/episode4/code.js +++ b/episode4/code.js @@ -1,24 +1,24 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - xres = 10, - yres = 11; - - context.fillStyle = "black"; - context.fillRect(0, 0, width, height); - context.fillStyle = "green"; - context.font = "12px Courier"; - context.translate(width / 2, height / 2); - // context.scale(1.5, 1.5); - // context.rotate(.1); - context.transform(1.5, .3, 0.1, 1.5, 0, 0); - - for(var y = -height / 2; y < height / 2; y += yres) { - for(var x = -width / 2; x < width / 2; x += xres) { - var char = Math.random() < .5 ? "0" : "1"; - context.fillText(char, x, y); - } - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + xres = 10, + yres = 11; + + context.fillStyle = "black"; + context.fillRect(0, 0, width, height); + context.fillStyle = "green"; + context.font = "12px Courier"; + context.translate(width / 2, height / 2); + // context.scale(1.5, 1.5); + // context.rotate(.1); + context.transform(1.5, .3, 0.1, 1.5, 0, 0); + + for(var y = -height / 2; y < height / 2; y += yres) { + for(var x = -width / 2; x < width / 2; x += xres) { + var char = Math.random() < .5 ? "0" : "1"; + context.fillText(char, x, y); + } + } }; \ No newline at end of file diff --git a/episode4/index.html b/episode4/index.html index 5673050..fbd073d 100644 --- a/episode4/index.html +++ b/episode4/index.html @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode5/arctangent.js b/episode5/arctangent.js index 5983af2..2c9ed95 100644 --- a/episode5/arctangent.js +++ b/episode5/arctangent.js @@ -1,44 +1,44 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - arrowX = width / 2, - arrowY = height / 2, - dx, dy, - angle = 0, - a = 0; - - render(); - - function render() { - arrowX = width / 2 + Math.cos(a) * height * .4; - arrowY = height / 2 + Math.sin(a) * height * .4; - a += .01; - context.clearRect(0, 0, width, height); - - context.save(); - context.translate(arrowX, arrowY); - context.rotate(angle); - - context.beginPath(); - context.moveTo(20, 0); - context.lineTo(-20, 0); - context.moveTo(20, 0); - context.lineTo(10, -10); - context.moveTo(20, 0); - context.lineTo(10, 10); - context.stroke(); - - context.restore(); - requestAnimationFrame(render); - } - - document.body.addEventListener("mousemove", function(event) { - dx = event.clientX - arrowX; - dy = event.clientY - arrowY; - angle = Math.atan2(dy, dx); - }); - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + arrowX = width / 2, + arrowY = height / 2, + dx, dy, + angle = 0, + a = 0; + + render(); + + function render() { + arrowX = width / 2 + Math.cos(a) * height * .4; + arrowY = height / 2 + Math.sin(a) * height * .4; + a += .01; + context.clearRect(0, 0, width, height); + + context.save(); + context.translate(arrowX, arrowY); + context.rotate(angle); + + context.beginPath(); + context.moveTo(20, 0); + context.lineTo(-20, 0); + context.moveTo(20, 0); + context.lineTo(10, -10); + context.moveTo(20, 0); + context.lineTo(10, 10); + context.stroke(); + + context.restore(); + requestAnimationFrame(render); + } + + document.body.addEventListener("mousemove", function(event) { + dx = event.clientX - arrowX; + dy = event.clientY - arrowY; + angle = Math.atan2(dy, dx); + }); + + }; \ No newline at end of file diff --git a/episode5/index.html b/episode5/index.html index 8dcf207..6252fb0 100644 --- a/episode5/index.html +++ b/episode5/index.html @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/episode7/vector.js b/episode7/vector.js index 609f6d5..4d66796 100644 --- a/episode7/vector.js +++ b/episode7/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode8/index.html b/episode8/index.html index f6702d7..532a094 100644 --- a/episode8/index.html +++ b/episode8/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode8/main.js b/episode8/main.js index f1ab22d..58e0e8f 100644 --- a/episode8/main.js +++ b/episode8/main.js @@ -1,28 +1,28 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = [], - numParticles = 100; - - for(var i = 0; i < numParticles; i += 1) { - particles.push(particle.create(width / 2, height / 2, Math.random() * 4 + 1, Math.random() * Math.PI * 2)); - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - for(var i = 0; i < numParticles; i += 1) { - var p = particles[i]; - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), 10, 0, Math.PI * 2, false); - context.fill(); - } - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = [], + numParticles = 100; + + for(var i = 0; i < numParticles; i += 1) { + particles.push(particle.create(width / 2, height / 2, Math.random() * 4 + 1, Math.random() * Math.PI * 2)); + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + for(var i = 0; i < numParticles; i += 1) { + var p = particles[i]; + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), 10, 0, Math.PI * 2, false); + context.fill(); + } + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode8/particle.js b/episode8/particle.js index b6e43f9..d2c89f4 100644 --- a/episode8/particle.js +++ b/episode8/particle.js @@ -1,17 +1,17 @@ -var particle = { - position: null, - velocity: null, - - create: function(x, y, speed, direction) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - return obj; - }, - - update: function() { - this.position.addTo(this.velocity); - } +var particle = { + position: null, + velocity: null, + + create: function(x, y, speed, direction) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + return obj; + }, + + update: function() { + this.position.addTo(this.velocity); + } }; \ No newline at end of file diff --git a/episode8/vector.js b/episode8/vector.js index 609f6d5..4d66796 100644 --- a/episode8/vector.js +++ b/episode8/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/episode9/fireworks.js b/episode9/fireworks.js index 0f52ea1..7db8e65 100644 --- a/episode9/fireworks.js +++ b/episode9/fireworks.js @@ -1,29 +1,29 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = [], - numParticles = 100; - - for(var i = 0; i < numParticles; i += 1) { - particles.push(particle.create(width / 2, height / 3, Math.random() * 5 + 2, Math.random() * Math.PI * 2, 0.1)); - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - for(var i = 0; i < numParticles; i += 1) { - var p = particles[i]; - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), 4, 0, Math.PI * 2, false); - context.fill(); - } - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = [], + numParticles = 100; + + for(var i = 0; i < numParticles; i += 1) { + particles.push(particle.create(width / 2, height / 3, Math.random() * 5 + 2, Math.random() * Math.PI * 2, 0.1)); + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + for(var i = 0; i < numParticles; i += 1) { + var p = particles[i]; + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), 4, 0, Math.PI * 2, false); + context.fill(); + } + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode9/index.html b/episode9/index.html index 5f54d38..14b7b02 100644 --- a/episode9/index.html +++ b/episode9/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/episode9/main.js b/episode9/main.js index 9b75232..bda0879 100644 --- a/episode9/main.js +++ b/episode9/main.js @@ -1,24 +1,24 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - p = particle.create(100, height, 10, -Math.PI / 2), - accel = vector.create(0.1, 0.1); - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - p.accelerate(accel); - - p.update(); - - context.beginPath(); - context.arc(p.position.getX(), p.position.getY(), 10, 0, Math.PI * 2, false); - context.fill(); - - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + p = particle.create(100, height, 10, -Math.PI / 2), + accel = vector.create(0.1, 0.1); + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + p.accelerate(accel); + + p.update(); + + context.beginPath(); + context.arc(p.position.getX(), p.position.getY(), 10, 0, Math.PI * 2, false); + context.fill(); + + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/episode9/particle.js b/episode9/particle.js index 3abf240..490b906 100644 --- a/episode9/particle.js +++ b/episode9/particle.js @@ -1,24 +1,24 @@ -var particle = { - position: null, - velocity: null, - gravity: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.position = vector.create(x, y); - obj.velocity = vector.create(0, 0); - obj.velocity.setLength(speed); - obj.velocity.setAngle(direction); - obj.gravity = vector.create(0, grav || 0); - return obj; - }, - - accelerate: function(accel) { - this.velocity.addTo(accel); - }, - - update: function() { - this.velocity.addTo(this.gravity); - this.position.addTo(this.velocity); - } +var particle = { + position: null, + velocity: null, + gravity: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.position = vector.create(x, y); + obj.velocity = vector.create(0, 0); + obj.velocity.setLength(speed); + obj.velocity.setAngle(direction); + obj.gravity = vector.create(0, grav || 0); + return obj; + }, + + accelerate: function(accel) { + this.velocity.addTo(accel); + }, + + update: function() { + this.velocity.addTo(this.gravity); + this.position.addTo(this.velocity); + } }; \ No newline at end of file diff --git a/episode9/vector.js b/episode9/vector.js index 609f6d5..4d66796 100644 --- a/episode9/vector.js +++ b/episode9/vector.js @@ -1,83 +1,83 @@ -var vector = { - _x: 1, - _y: 0, - - create: function(x, y) { - var obj = Object.create(this); - obj.setX(x); - obj.setY(y); - return obj; - }, - - setX: function(value) { - this._x = value; - }, - - getX: function() { - return this._x; - }, - - setY: function(value) { - this._y = value; - }, - - getY: function() { - return this._y; - }, - - setAngle: function(angle) { - var length = this.getLength(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getAngle: function() { - return Math.atan2(this._y, this._x); - }, - - setLength: function(length) { - var angle = this.getAngle(); - this._x = Math.cos(angle) * length; - this._y = Math.sin(angle) * length; - }, - - getLength: function() { - return Math.sqrt(this._x * this._x + this._y * this._y); - }, - - add: function(v2) { - return vector.create(this._x + v2.getX(), this._y + v2.getY()); - }, - - subtract: function(v2) { - return vector.create(this._x - v2.getX(), this._y - v2.getY()); - }, - - multiply: function(val) { - return vector.create(this._x * val, this._y * val); - }, - - divide: function(val) { - return vector.create(this._x / val, this._y / val); - }, - - addTo: function(v2) { - this._x += v2.getX(); - this._y += v2.getY(); - }, - - subtractFrom: function(v2) { - this._x -= v2.getX(); - this._y -= v2.getY(); - }, - - multiplyBy: function(val) { - this._x *= val; - this._y *= val; - }, - - divideBy: function(val) { - this._x /= val; - this._y /= val; - } +var vector = { + _x: 1, + _y: 0, + + create: function(x, y) { + var obj = Object.create(this); + obj.setX(x); + obj.setY(y); + return obj; + }, + + setX: function(value) { + this._x = value; + }, + + getX: function() { + return this._x; + }, + + setY: function(value) { + this._y = value; + }, + + getY: function() { + return this._y; + }, + + setAngle: function(angle) { + var length = this.getLength(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getAngle: function() { + return Math.atan2(this._y, this._x); + }, + + setLength: function(length) { + var angle = this.getAngle(); + this._x = Math.cos(angle) * length; + this._y = Math.sin(angle) * length; + }, + + getLength: function() { + return Math.sqrt(this._x * this._x + this._y * this._y); + }, + + add: function(v2) { + return vector.create(this._x + v2.getX(), this._y + v2.getY()); + }, + + subtract: function(v2) { + return vector.create(this._x - v2.getX(), this._y - v2.getY()); + }, + + multiply: function(val) { + return vector.create(this._x * val, this._y * val); + }, + + divide: function(val) { + return vector.create(this._x / val, this._y / val); + }, + + addTo: function(v2) { + this._x += v2.getX(); + this._y += v2.getY(); + }, + + subtractFrom: function(v2) { + this._x -= v2.getX(); + this._y -= v2.getY(); + }, + + multiplyBy: function(val) { + this._x *= val; + this._y *= val; + }, + + divideBy: function(val) { + this._x /= val; + this._y /= val; + } }; \ No newline at end of file diff --git a/mini1/index.html b/mini1/index.html index 719fb94..dfde07f 100644 --- a/mini1/index.html +++ b/mini1/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/mini1/main.js b/mini1/main.js index 79e5286..b1c8708 100644 --- a/mini1/main.js +++ b/mini1/main.js @@ -1,42 +1,42 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - - values = [7, 5, 21, 18, 33, 12, 27, 18, 9, 23, 14, 6, 31, 25, 17, 13, 29], - min = Math.min.apply(null, values), - max = Math.max.apply(null, values); - - function norm(value, min, max) { - return (value - min) / (max - min); - } - - context.beginPath(); - - for(var i = 0; i < values.length; i += 1) { - var normValue = norm(values[i], min, max), - x = width / (values.length - 1) * i, - y = height - height * normValue; - - if(i == 0) { - context.moveTo(x, y); - } - else { - context.lineTo(x, y); - } - } - - context.stroke(); - - // bonus material! you can also plot the points - - for(var i = 0; i < values.length; i += 1) { - var normValue = norm(values[i], min, max), - x = width / (values.length - 1) * i, - y = height - height * normValue; - context.beginPath(); - context.arc(x, y, 4, 0, Math.PI * 2, false); - context.fill(); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + + values = [7, 5, 21, 18, 33, 12, 27, 18, 9, 23, 14, 6, 31, 25, 17, 13, 29], + min = Math.min.apply(null, values), + max = Math.max.apply(null, values); + + function norm(value, min, max) { + return (value - min) / (max - min); + } + + context.beginPath(); + + for(var i = 0; i < values.length; i += 1) { + var normValue = norm(values[i], min, max), + x = width / (values.length - 1) * i, + y = height - height * normValue; + + if(i == 0) { + context.moveTo(x, y); + } + else { + context.lineTo(x, y); + } + } + + context.stroke(); + + // bonus material! you can also plot the points + + for(var i = 0; i < values.length; i += 1) { + var normValue = norm(values[i], min, max), + x = width / (values.length - 1) * i, + y = height - height * normValue; + context.beginPath(); + context.arc(x, y, 4, 0, Math.PI * 2, false); + context.fill(); + } }; \ No newline at end of file diff --git a/mini10/circle.js b/mini10/circle.js index 897247f..eea0db9 100644 --- a/mini10/circle.js +++ b/mini10/circle.js @@ -1,28 +1,28 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - centerX = width / 2, - centerY = height / 2, - maxRadius = 100; - - for (var i = 0; i < 10; i += 1) { - var radius = 20, - angle = Math.PI * 2 / 10 * i, - x = centerX + Math.cos(angle) * radius, - y = centerY + Math.sin(angle) * radius; - context.beginPath(); - context.arc(x, y, 5, 0, Math.PI * 2, false); - context.fill(); - } - for (var i = 0; i < 10; i += 1) { - var radius = 100, - angle = Math.PI * 2 / 10 * i, - x = centerX + Math.cos(angle) * radius, - y = centerY + Math.sin(angle) * radius; - context.beginPath(); - context.arc(x, y, 5, 0, Math.PI * 2, false); - context.fill(); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + centerX = width / 2, + centerY = height / 2, + maxRadius = 100; + + for (var i = 0; i < 10; i += 1) { + var radius = 20, + angle = Math.PI * 2 / 10 * i, + x = centerX + Math.cos(angle) * radius, + y = centerY + Math.sin(angle) * radius; + context.beginPath(); + context.arc(x, y, 5, 0, Math.PI * 2, false); + context.fill(); + } + for (var i = 0; i < 10; i += 1) { + var radius = 100, + angle = Math.PI * 2 / 10 * i, + x = centerX + Math.cos(angle) * radius, + y = centerY + Math.sin(angle) * radius; + context.beginPath(); + context.arc(x, y, 5, 0, Math.PI * 2, false); + context.fill(); + } }; \ No newline at end of file diff --git a/mini10/index.html b/mini10/index.html index 4ded490..25cb3be 100644 --- a/mini10/index.html +++ b/mini10/index.html @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/mini10/main.js b/mini10/main.js index 536954f..bb0af1c 100644 --- a/mini10/main.js +++ b/mini10/main.js @@ -1,19 +1,19 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - centerX = width / 2, - centerY = height / 2, - maxRadius = 100; - - for (var i = 0; i < 1000; i += 1) { - var radius = Math.sqrt(Math.random()) * maxRadius, - angle = utils.randomRange(0, Math.PI * 2), - x = centerX + Math.cos(angle) * radius, - y = centerY + Math.sin(angle) * radius; - context.beginPath(); - context.arc(x, y, 1, 0, Math.PI * 2, false); - context.fill(); - }; +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + centerX = width / 2, + centerY = height / 2, + maxRadius = 100; + + for (var i = 0; i < 1000; i += 1) { + var radius = Math.sqrt(Math.random()) * maxRadius, + angle = utils.randomRange(0, Math.PI * 2), + x = centerX + Math.cos(angle) * radius, + y = centerY + Math.sin(angle) * radius; + context.beginPath(); + context.arc(x, y, 1, 0, Math.PI * 2, false); + context.fill(); + }; }; \ No newline at end of file diff --git a/mini10/main2.js b/mini10/main2.js index 1b3639f..1e800c7 100644 --- a/mini10/main2.js +++ b/mini10/main2.js @@ -1,28 +1,28 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - particles = []; - - for (var i = 0; i < 200; i += 1) { - var p = particle.create(width / 2, height / 2, 0, 0); - p.vx = utils.randomRange(-1, 1); - p.vy = utils.randomRange(-1, 1); - particles.push(p); - }; - - update(); - - function update() { - context.clearRect(0, 0, width, height); - for(var i = 0; i < 200; i += 1) { - var p = particles[i]; - p.update(); - context.beginPath(); - context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); - context.fill(); - } - requestAnimationFrame(update); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + particles = []; + + for (var i = 0; i < 200; i += 1) { + var p = particle.create(width / 2, height / 2, 0, 0); + p.vx = utils.randomRange(-1, 1); + p.vy = utils.randomRange(-1, 1); + particles.push(p); + }; + + update(); + + function update() { + context.clearRect(0, 0, width, height); + for(var i = 0; i < 200; i += 1) { + var p = particles[i]; + p.update(); + context.beginPath(); + context.arc(p.x, p.y, 3, 0, Math.PI * 2, false); + context.fill(); + } + requestAnimationFrame(update); + } }; \ No newline at end of file diff --git a/mini10/particle.js b/mini10/particle.js index b6ef621..948e47a 100644 --- a/mini10/particle.js +++ b/mini10/particle.js @@ -1,138 +1,138 @@ -var particle = { - x: 0, - y: 0, - vx: 0, - vy: 0, - mass: 1, - radius: 0, - bounce: -1, - friction: 1, - gravity: 0, - springs: null, - gravitations: null, - - create: function(x, y, speed, direction, grav) { - var obj = Object.create(this); - obj.x = x; - obj.y = y; - obj.vx = Math.cos(direction) * speed; - obj.vy = Math.sin(direction) * speed; - obj.gravity = grav || 0; - obj.springs = []; - obj.gravitations = []; - return obj; - }, - - addGravitation: function(p) { - this.removeGravitation(p); - this.gravitations.push(p); - }, - - removeGravitation: function(p) { - for(var i = 0; i < this.gravitations.length; i += 1) { - if(p === this.gravitations[i]) { - this.gravitations.splice(i, 1); - return; - } - } - }, - - addSpring: function(point, k, length) { - this.removeSpring(point); - this.springs.push({ - point: point, - k: k, - length: length || 0 - }); - }, - - removeSpring: function(point) { - for(var i = 0; i < this.springs.length; i += 1) { - if(point === this.springs[i].point) { - this.springs.splice(i, 1); - return; - } - } - }, - - getSpeed: function() { - return Math.sqrt(this.vx * this.vx + this.vy * this.vy); - }, - - setSpeed: function(speed) { - var heading = this.getHeading(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - getHeading: function() { - return Math.atan2(this.vy, this.vx); - }, - - setHeading: function(heading) { - var speed = this.getSpeed(); - this.vx = Math.cos(heading) * speed; - this.vy = Math.sin(heading) * speed; - }, - - accelerate: function(ax, ay) { - this.vx += ax; - this.vy += ay; - }, - - update: function() { - this.handleSprings(); - this.handleGravitations(); - this.vx *= this.friction; - this.vy *= this.friction; - this.vy += this.gravity; - this.x += this.vx; - this.y += this.vy; - }, - - handleGravitations: function() { - for(var i = 0; i < this.gravitations.length; i += 1) { - this.gravitateTo(this.gravitations[i]); - } - }, - - handleSprings: function() { - for(var i = 0; i < this.springs.length; i += 1) { - var spring = this.springs[i]; - this.springTo(spring.point, spring.k, spring.length); - } - }, - - angleTo: function(p2) { - return Math.atan2(p2.y - this.y, p2.x - this.x); - }, - - distanceTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - gravitateTo: function(p2) { - var dx = p2.x - this.x, - dy = p2.y - this.y, - distSQ = dx * dx + dy * dy, - dist = Math.sqrt(distSQ), - force = p2.mass / distSQ, - ax = dx / dist * force, - ay = dy / dist * force; - - this.vx += ax; - this.vy += ay; - }, - - springTo: function(point, k, length) { - var dx = point.x - this.x, - dy = point.y - this.y, - distance = Math.sqrt(dx * dx + dy * dy), - springForce = (distance - length || 0) * k; - this.vx += dx / distance * springForce, - this.vy += dy / distance * springForce; - } +var particle = { + x: 0, + y: 0, + vx: 0, + vy: 0, + mass: 1, + radius: 0, + bounce: -1, + friction: 1, + gravity: 0, + springs: null, + gravitations: null, + + create: function(x, y, speed, direction, grav) { + var obj = Object.create(this); + obj.x = x; + obj.y = y; + obj.vx = Math.cos(direction) * speed; + obj.vy = Math.sin(direction) * speed; + obj.gravity = grav || 0; + obj.springs = []; + obj.gravitations = []; + return obj; + }, + + addGravitation: function(p) { + this.removeGravitation(p); + this.gravitations.push(p); + }, + + removeGravitation: function(p) { + for(var i = 0; i < this.gravitations.length; i += 1) { + if(p === this.gravitations[i]) { + this.gravitations.splice(i, 1); + return; + } + } + }, + + addSpring: function(point, k, length) { + this.removeSpring(point); + this.springs.push({ + point: point, + k: k, + length: length || 0 + }); + }, + + removeSpring: function(point) { + for(var i = 0; i < this.springs.length; i += 1) { + if(point === this.springs[i].point) { + this.springs.splice(i, 1); + return; + } + } + }, + + getSpeed: function() { + return Math.sqrt(this.vx * this.vx + this.vy * this.vy); + }, + + setSpeed: function(speed) { + var heading = this.getHeading(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + getHeading: function() { + return Math.atan2(this.vy, this.vx); + }, + + setHeading: function(heading) { + var speed = this.getSpeed(); + this.vx = Math.cos(heading) * speed; + this.vy = Math.sin(heading) * speed; + }, + + accelerate: function(ax, ay) { + this.vx += ax; + this.vy += ay; + }, + + update: function() { + this.handleSprings(); + this.handleGravitations(); + this.vx *= this.friction; + this.vy *= this.friction; + this.vy += this.gravity; + this.x += this.vx; + this.y += this.vy; + }, + + handleGravitations: function() { + for(var i = 0; i < this.gravitations.length; i += 1) { + this.gravitateTo(this.gravitations[i]); + } + }, + + handleSprings: function() { + for(var i = 0; i < this.springs.length; i += 1) { + var spring = this.springs[i]; + this.springTo(spring.point, spring.k, spring.length); + } + }, + + angleTo: function(p2) { + return Math.atan2(p2.y - this.y, p2.x - this.x); + }, + + distanceTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + gravitateTo: function(p2) { + var dx = p2.x - this.x, + dy = p2.y - this.y, + distSQ = dx * dx + dy * dy, + dist = Math.sqrt(distSQ), + force = p2.mass / distSQ, + ax = dx / dist * force, + ay = dy / dist * force; + + this.vx += ax; + this.vy += ay; + }, + + springTo: function(point, k, length) { + var dx = point.x - this.x, + dy = point.y - this.y, + distance = Math.sqrt(dx * dx + dy * dy), + springForce = (distance - length || 0) * k; + this.vx += dx / distance * springForce, + this.vy += dy / distance * springForce; + } }; \ No newline at end of file diff --git a/mini10/utils.js b/mini10/utils.js index 7c659e4..25aa5da 100644 --- a/mini10/utils.js +++ b/mini10/utils.js @@ -1,106 +1,106 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + } + } \ No newline at end of file diff --git a/mini11/bezier.js b/mini11/bezier.js index 441d912..4056883 100644 --- a/mini11/bezier.js +++ b/mini11/bezier.js @@ -1,90 +1,90 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - handle0 = { - x: 100, - y: 100, - radius: 15 - }, - handle1 = { - x: 400, - y: 400, - radius: 15 - }, - handle2 = { - x: 700, - y: 100, - radius: 15 - }, - handle3 = { - x: 1000, - y: 500, - radius: 15 - }, - handles = [handle0, handle1, handle2, handle3], - offset = {}, - isDragging = false, - dragHandle; - - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - - context.beginPath(); - context.moveTo(handle0.x, handle0.y); - context.bezierCurveTo(handle1.x, handle1.y, - handle2.x, handle2.y, - handle3.x, handle3.y); - context.stroke(); - - context.fillStyle = "gray"; - for(var i = 0; i < 4; i += 1) { - var handle = handles[i]; - if(isDragging && handle === dragHandle) { - context.shadowColor = "black"; - context.shadowOffsetX = 4; - context.shadowOffsetY = 4; - context.shadowBlur = 8; - } - context.beginPath(); - context.arc(handle.x, handle.y, handle.radius, 0, Math.PI * 2, false); - context.fill(); - - context.shadowColor = null; - context.shadowOffsetX = null; - context.shadowOffsetY = null; - context.shadowBlur = null; - } - } - - document.body.addEventListener("mousedown", function(event) { - for(var i = 0; i < 4; i += 1) { - var handle = handles[i]; - if(utils.circlePointCollision(event.clientX, event.clientY, handle)) { - isDragging = true; - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - dragHandle = handle; - offset.x = event.clientX - handle.x; - offset.y = event.clientY - handle.y; - draw(); - } - } - }); - - function onMouseMove(event) { - dragHandle.x = event.clientX - offset.x; - dragHandle.y = event.clientY - offset.y; - draw(); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - isDragging = false; - draw(); - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + handle0 = { + x: 100, + y: 100, + radius: 15 + }, + handle1 = { + x: 400, + y: 400, + radius: 15 + }, + handle2 = { + x: 700, + y: 100, + radius: 15 + }, + handle3 = { + x: 1000, + y: 500, + radius: 15 + }, + handles = [handle0, handle1, handle2, handle3], + offset = {}, + isDragging = false, + dragHandle; + + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + + context.beginPath(); + context.moveTo(handle0.x, handle0.y); + context.bezierCurveTo(handle1.x, handle1.y, + handle2.x, handle2.y, + handle3.x, handle3.y); + context.stroke(); + + context.fillStyle = "gray"; + for(var i = 0; i < 4; i += 1) { + var handle = handles[i]; + if(isDragging && handle === dragHandle) { + context.shadowColor = "black"; + context.shadowOffsetX = 4; + context.shadowOffsetY = 4; + context.shadowBlur = 8; + } + context.beginPath(); + context.arc(handle.x, handle.y, handle.radius, 0, Math.PI * 2, false); + context.fill(); + + context.shadowColor = null; + context.shadowOffsetX = null; + context.shadowOffsetY = null; + context.shadowBlur = null; + } + } + + document.body.addEventListener("mousedown", function(event) { + for(var i = 0; i < 4; i += 1) { + var handle = handles[i]; + if(utils.circlePointCollision(event.clientX, event.clientY, handle)) { + isDragging = true; + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + dragHandle = handle; + offset.x = event.clientX - handle.x; + offset.y = event.clientY - handle.y; + draw(); + } + } + }); + + function onMouseMove(event) { + dragHandle.x = event.clientX - offset.x; + dragHandle.y = event.clientY - offset.y; + draw(); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + isDragging = false; + draw(); + } }; \ No newline at end of file diff --git a/mini11/index.html b/mini11/index.html index e74c311..f47500b 100644 --- a/mini11/index.html +++ b/mini11/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/mini11/main.js b/mini11/main.js index 1c6b685..c01bba5 100644 --- a/mini11/main.js +++ b/mini11/main.js @@ -1,45 +1,45 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - handle = { - x: width / 2, - y: height / 2, - radius: 20 - }, - offset = {}; - - draw(); - - function draw() { - context.clearRect(0, 0, width, height); - - context.fillStyle = "gray"; - context.beginPath(); - context.arc(handle.x, handle.y, handle.radius, 0, Math.PI * 2, false); - context.fill(); - } - - document.body.addEventListener("mousedown", function(event) { - if(utils.circlePointCollision(event.clientX, event.clientY, handle)) { - document.body.addEventListener("mousemove", onMouseMove); - document.body.addEventListener("mouseup", onMouseUp); - offset.x = event.clientX - handle.x; - offset.y = event.clientY - handle.y; - } - }); - - function onMouseMove(event) { - handle.x = event.clientX;// - offset.x; - handle.y = event.clientY;// - offset.y; - draw(); - } - - function onMouseUp(event) { - document.body.removeEventListener("mousemove", onMouseMove); - document.body.removeEventListener("mouseup", onMouseUp); - } - - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + handle = { + x: width / 2, + y: height / 2, + radius: 20 + }, + offset = {}; + + draw(); + + function draw() { + context.clearRect(0, 0, width, height); + + context.fillStyle = "gray"; + context.beginPath(); + context.arc(handle.x, handle.y, handle.radius, 0, Math.PI * 2, false); + context.fill(); + } + + document.body.addEventListener("mousedown", function(event) { + if(utils.circlePointCollision(event.clientX, event.clientY, handle)) { + document.body.addEventListener("mousemove", onMouseMove); + document.body.addEventListener("mouseup", onMouseUp); + offset.x = event.clientX - handle.x; + offset.y = event.clientY - handle.y; + } + }); + + function onMouseMove(event) { + handle.x = event.clientX;// - offset.x; + handle.y = event.clientY;// - offset.y; + draw(); + } + + function onMouseUp(event) { + document.body.removeEventListener("mousemove", onMouseMove); + document.body.removeEventListener("mouseup", onMouseUp); + } + + }; \ No newline at end of file diff --git a/mini11/utils.js b/mini11/utils.js index 7c659e4..25aa5da 100644 --- a/mini11/utils.js +++ b/mini11/utils.js @@ -1,106 +1,106 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - }, - - quadraticBezier: function(p0, p1, p2, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 2) * p0.x + - (1 - t) * 2 * t * p1.x + - t * t * p2.x; - pFinal.y = Math.pow(1 - t, 2) * p0.y + - (1 - t) * 2 * t * p1.y + - t * t * p2.y; - return pFinal; - }, - - cubicBezier: function(p0, p1, p2, p3, t, pFinal) { - pFinal = pFinal || {}; - pFinal.x = Math.pow(1 - t, 3) * p0.x + - Math.pow(1 - t, 2) * 3 * t * p1.x + - (1 - t) * 3 * t * t * p2.x + - t * t * t * p3.x; - pFinal.y = Math.pow(1 - t, 3) * p0.y + - Math.pow(1 - t, 2) * 3 * t * p1.y + - (1 - t) * 3 * t * t * p2.y + - t * t * t * p3.y; - return pFinal; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + }, + + quadraticBezier: function(p0, p1, p2, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 2) * p0.x + + (1 - t) * 2 * t * p1.x + + t * t * p2.x; + pFinal.y = Math.pow(1 - t, 2) * p0.y + + (1 - t) * 2 * t * p1.y + + t * t * p2.y; + return pFinal; + }, + + cubicBezier: function(p0, p1, p2, p3, t, pFinal) { + pFinal = pFinal || {}; + pFinal.x = Math.pow(1 - t, 3) * p0.x + + Math.pow(1 - t, 2) * 3 * t * p1.x + + (1 - t) * 3 * t * t * p2.x + + t * t * t * p3.x; + pFinal.y = Math.pow(1 - t, 3) * p0.y + + Math.pow(1 - t, 2) * 3 * t * p1.y + + (1 - t) * 3 * t * t * p2.y + + t * t * t * p3.y; + return pFinal; + } + } \ No newline at end of file diff --git a/mini2/index.html b/mini2/index.html index 719fb94..dfde07f 100644 --- a/mini2/index.html +++ b/mini2/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/mini2/main.js b/mini2/main.js index 798d2b9..64f7a03 100644 --- a/mini2/main.js +++ b/mini2/main.js @@ -1,42 +1,42 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - minX = 50, - maxX = width - 50, - minY = 100, - maxY = height - 100, - minAlpha = 0, - maxAlpha = 1, - minRadius = 10, - maxRadius = 400, - t = 0; - - - function lerp(norm, min, max) { - return (max - min) * norm + min; - } - - update(); - - function update() { - context.clearRect(0, 0, width, height); - - context.globalAlpha = lerp(t, maxAlpha, minAlpha); - context.beginPath(); - context.arc(lerp(t, minX, maxX), - lerp(t, minY, maxY), - lerp(t, minRadius, maxRadius), - 0, Math.PI * 2, false); - context.fill(); - - t += .005; - if(t > 1) { - t = 0; - } - - requestAnimationFrame(update); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + minX = 50, + maxX = width - 50, + minY = 100, + maxY = height - 100, + minAlpha = 0, + maxAlpha = 1, + minRadius = 10, + maxRadius = 400, + t = 0; + + + function lerp(norm, min, max) { + return (max - min) * norm + min; + } + + update(); + + function update() { + context.clearRect(0, 0, width, height); + + context.globalAlpha = lerp(t, maxAlpha, minAlpha); + context.beginPath(); + context.arc(lerp(t, minX, maxX), + lerp(t, minY, maxY), + lerp(t, minRadius, maxRadius), + 0, Math.PI * 2, false); + context.fill(); + + t += .005; + if(t > 1) { + t = 0; + } + + requestAnimationFrame(update); + } + }; \ No newline at end of file diff --git a/mini3/index.html b/mini3/index.html index 719fb94..dfde07f 100644 --- a/mini3/index.html +++ b/mini3/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/mini3/main.js b/mini3/main.js index 5df9c40..b564d06 100644 --- a/mini3/main.js +++ b/mini3/main.js @@ -1,30 +1,30 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - function norm(value, min, max) { - return (value - min) / (max - min); - } - - function lerp(norm, min, max) { - return (max - min) * norm + min; - } - - function map(value, sourceMin, sourceMax, destMin, destMax) { - return lerp(norm(value, sourceMin, sourceMax), destMin, destMax); - } - - document.body.addEventListener("mousemove", function(event) { - var radius = map(event.clientY, - 0, height, - 20, 340); - - context.clearRect(0, 0, width, height); - context.beginPath(); - context.arc(width / 2, height / 2, radius, 0, Math.PI * 2, false); - context.fill(); - }); - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + function norm(value, min, max) { + return (value - min) / (max - min); + } + + function lerp(norm, min, max) { + return (max - min) * norm + min; + } + + function map(value, sourceMin, sourceMax, destMin, destMax) { + return lerp(norm(value, sourceMin, sourceMax), destMin, destMax); + } + + document.body.addEventListener("mousemove", function(event) { + var radius = map(event.clientY, + 0, height, + 20, 340); + + context.clearRect(0, 0, width, height); + context.beginPath(); + context.arc(width / 2, height / 2, radius, 0, Math.PI * 2, false); + context.fill(); + }); + }; \ No newline at end of file diff --git a/mini4/index.html b/mini4/index.html index 719fb94..dfde07f 100644 --- a/mini4/index.html +++ b/mini4/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/mini4/main.js b/mini4/main.js index 32ad592..ec5d04d 100644 --- a/mini4/main.js +++ b/mini4/main.js @@ -1,31 +1,31 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - rect = { - x: width / 2 - 200, - y: height / 2 - 150, - width: 400, - height: 300 - }; - - function clamp(value, min, max) { - return Math.min(Math.max(value, min), max); - } - - document.body.addEventListener("mousemove", function(event) { - var x = clamp(event.clientX, rect.x + 10, rect.x + rect.width - 10), - y = clamp(event.clientY, rect.y + 10, rect.y + rect.height - 10); - - context.clearRect(0, 0, width, height); - context.fillStyle = "#cccccc"; - context.fillRect(rect.x, rect.y, rect.width, rect.height); - - context.fillStyle = "#000000"; - context.beginPath(); - context.arc(x, y, 10, 0, Math.PI * 2, false); - context.fill(); - }); - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + rect = { + x: width / 2 - 200, + y: height / 2 - 150, + width: 400, + height: 300 + }; + + function clamp(value, min, max) { + return Math.min(Math.max(value, min), max); + } + + document.body.addEventListener("mousemove", function(event) { + var x = clamp(event.clientX, rect.x + 10, rect.x + rect.width - 10), + y = clamp(event.clientY, rect.y + 10, rect.y + rect.height - 10); + + context.clearRect(0, 0, width, height); + context.fillStyle = "#cccccc"; + context.fillRect(rect.x, rect.y, rect.width, rect.height); + + context.fillStyle = "#000000"; + context.beginPath(); + context.arc(x, y, 10, 0, Math.PI * 2, false); + context.fill(); + }); + }; \ No newline at end of file diff --git a/mini6/index.html b/mini6/index.html index 719fb94..dfde07f 100644 --- a/mini6/index.html +++ b/mini6/index.html @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/mini6/main.js b/mini6/main.js index 778165f..8bb6f11 100644 --- a/mini6/main.js +++ b/mini6/main.js @@ -1,30 +1,30 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - centerX = width / 2, - centerY = height / 2; - - function distanceXY(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - } - - document.body.addEventListener("mousemove", function(event) { - context.clearRect(0, 0, width, height); - - var dist = distanceXY(centerX, centerY, event.clientX, event.clientY); - if(dist < 100) { - context.fillStyle = "#ff6666"; - } - else { - context.fillStyle = "#cccccc"; - } - - context.beginPath(); - context.arc(centerX, centerY, 100, 0, Math.PI * 360, false); - context.fill(); - }); +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + centerX = width / 2, + centerY = height / 2; + + function distanceXY(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + } + + document.body.addEventListener("mousemove", function(event) { + context.clearRect(0, 0, width, height); + + var dist = distanceXY(centerX, centerY, event.clientX, event.clientY); + if(dist < 100) { + context.fillStyle = "#ff6666"; + } + else { + context.fillStyle = "#cccccc"; + } + + context.beginPath(); + context.arc(centerX, centerY, 100, 0, Math.PI * 360, false); + context.fill(); + }); }; \ No newline at end of file diff --git a/mini7/index.html b/mini7/index.html index e74c311..f47500b 100644 --- a/mini7/index.html +++ b/mini7/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/mini7/main.js b/mini7/main.js index e378341..44abafb 100644 --- a/mini7/main.js +++ b/mini7/main.js @@ -1,21 +1,21 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - var angle = Math.PI / 4; - - context.translate(width / 2, height / 2); - context.rotate(angle); - - context.beginPath(); - context.arc(0, 0, 20, 0, Math.PI * 2, 0); - context.fill(); - - context.lineWidth = 10; - context.beginPath(); - context.moveTo(0, 0); - context.lineTo(50, 0); - context.stroke(); +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + var angle = Math.PI / 4; + + context.translate(width / 2, height / 2); + context.rotate(angle); + + context.beginPath(); + context.arc(0, 0, 20, 0, Math.PI * 2, 0); + context.fill(); + + context.lineWidth = 10; + context.beginPath(); + context.moveTo(0, 0); + context.lineTo(50, 0); + context.stroke(); }; \ No newline at end of file diff --git a/mini7/utils.js b/mini7/utils.js index 5372d1f..fecc898 100644 --- a/mini7/utils.js +++ b/mini7/utils.js @@ -1,65 +1,65 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + } + } \ No newline at end of file diff --git a/mini8/index.html b/mini8/index.html index e74c311..f47500b 100644 --- a/mini8/index.html +++ b/mini8/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/mini8/main.js b/mini8/main.js index 0696243..bbca9f3 100644 --- a/mini8/main.js +++ b/mini8/main.js @@ -1,36 +1,36 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - gridSize = 40; - - drawGrid(); - - document.body.addEventListener("mousemove", function(event) { - context.clearRect(0, 0, width, height); - drawGrid(); - - var x = utils.roundNearest(event.clientX, gridSize), - y = utils.roundNearest(event.clientY, gridSize); - - context.beginPath(); - context.arc(x, y, 20, 0, Math.PI * 2, false); - context.fill(); - }); - - function drawGrid() { - context.beginPath(); - context.strokeStyle = "#ccc"; - for(var x = 0; x <= width; x += gridSize) { - context.moveTo(x, 0); - context.lineTo(x, height); - } - for(var y = 0; y <= height; y += gridSize) { - context.moveTo(0, y); - context.lineTo(width, y); - } - context.stroke(); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + gridSize = 40; + + drawGrid(); + + document.body.addEventListener("mousemove", function(event) { + context.clearRect(0, 0, width, height); + drawGrid(); + + var x = utils.roundNearest(event.clientX, gridSize), + y = utils.roundNearest(event.clientY, gridSize); + + context.beginPath(); + context.arc(x, y, 20, 0, Math.PI * 2, false); + context.fill(); + }); + + function drawGrid() { + context.beginPath(); + context.strokeStyle = "#ccc"; + for(var x = 0; x <= width; x += gridSize) { + context.moveTo(x, 0); + context.lineTo(x, height); + } + for(var y = 0; y <= height; y += gridSize) { + context.moveTo(0, y); + context.lineTo(width, y); + } + context.stroke(); + } + }; \ No newline at end of file diff --git a/mini8/test1.js b/mini8/test1.js index e8f3ee3..bfdca97 100644 --- a/mini8/test1.js +++ b/mini8/test1.js @@ -1,7 +1,7 @@ -window.onload = function() { - - console.log(utils.roundToPlaces(Math.PI, 1)); - console.log(utils.roundToPlaces(Math.PI, 3)); - console.log(utils.roundToPlaces(Math.PI, 5)); - +window.onload = function() { + + console.log(utils.roundToPlaces(Math.PI, 1)); + console.log(utils.roundToPlaces(Math.PI, 3)); + console.log(utils.roundToPlaces(Math.PI, 5)); + }; \ No newline at end of file diff --git a/mini8/test2.js b/mini8/test2.js index db9e1c2..18b743c 100644 --- a/mini8/test2.js +++ b/mini8/test2.js @@ -1,7 +1,7 @@ -window.onload = function() { - - console.log(utils.roundToPlaces(123456789, -1)); - console.log(utils.roundToPlaces(123456789, -2)); - console.log(utils.roundToPlaces(123456789, -3)); - +window.onload = function() { + + console.log(utils.roundToPlaces(123456789, -1)); + console.log(utils.roundToPlaces(123456789, -2)); + console.log(utils.roundToPlaces(123456789, -3)); + }; \ No newline at end of file diff --git a/mini8/utils.js b/mini8/utils.js index f31970f..1a22d0f 100644 --- a/mini8/utils.js +++ b/mini8/utils.js @@ -1,74 +1,74 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - roundToPlaces: function(value, places) { - var mult = Math.pow(10, places); - return Math.round(value * mult) / mult; - }, - - roundNearest: function(value, nearest) { - return Math.round(value / nearest) * nearest; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + roundToPlaces: function(value, places) { + var mult = Math.pow(10, places); + return Math.round(value * mult) / mult; + }, + + roundNearest: function(value, nearest) { + return Math.round(value / nearest) * nearest; + } + } \ No newline at end of file diff --git a/mini9/highres.js b/mini9/highres.js index 746b944..ae1826d 100644 --- a/mini9/highres.js +++ b/mini9/highres.js @@ -1,45 +1,45 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - results = [], - running = true; - - document.body.addEventListener("click", function() { - running = !running; - }); - - for(var i = 0; i < width; i += 1) { - results[i] = 0; - } - - update(); - - function update() { - - for(var n = 0; n < 1000; n += 1) { - addResult(); - } - for(var i = 0; i < width; i += 1) { - var h = -results[i]; - context.fillRect(i, height, 1, h ); - } - if(running) { - requestAnimationFrame(update); - } - } - - function addResult() { - var iterations = 2, - total = 0; - - for(var i = 0; i < iterations; i += 1) { - total += utils.randomRange(0, width); - } - result = Math.floor(total / iterations); - - results[result] += 1; - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + results = [], + running = true; + + document.body.addEventListener("click", function() { + running = !running; + }); + + for(var i = 0; i < width; i += 1) { + results[i] = 0; + } + + update(); + + function update() { + + for(var n = 0; n < 1000; n += 1) { + addResult(); + } + for(var i = 0; i < width; i += 1) { + var h = -results[i]; + context.fillRect(i, height, 1, h ); + } + if(running) { + requestAnimationFrame(update); + } + } + + function addResult() { + var iterations = 2, + total = 0; + + for(var i = 0; i < iterations; i += 1) { + total += utils.randomRange(0, width); + } + result = Math.floor(total / iterations); + + results[result] += 1; + } + }; \ No newline at end of file diff --git a/mini9/index.html b/mini9/index.html index ec278a5..30c3a9a 100644 --- a/mini9/index.html +++ b/mini9/index.html @@ -1,21 +1,21 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/mini9/main.js b/mini9/main.js index 51b87a1..d085334 100644 --- a/mini9/main.js +++ b/mini9/main.js @@ -1,35 +1,35 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - results = []; - - for(var i = 0; i < 100; i += 1) { - results[i] = 0; - } - - update(); - - function update() { - addResult(); - draw(); - requestAnimationFrame(update); - } - - function addResult() { - var r0 = utils.randomRange(0, 100), - r1 = utils.randomRange(0, 100), - result = Math.floor((r0 + r1) / 2); - - results[result] += 1; - } - - function draw() { - var w = width / 100; - for(var i = 0; i < 100; i += 1) { - var h = results[i] * -10; - context.fillRect(w * i, height, w, h); - } - } +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + results = []; + + for(var i = 0; i < 100; i += 1) { + results[i] = 0; + } + + update(); + + function update() { + addResult(); + draw(); + requestAnimationFrame(update); + } + + function addResult() { + var r0 = utils.randomRange(0, 100), + r1 = utils.randomRange(0, 100), + result = Math.floor((r0 + r1) / 2); + + results[result] += 1; + } + + function draw() { + var w = width / 100; + for(var i = 0; i < 100; i += 1) { + var h = results[i] * -10; + context.fillRect(w * i, height, w, h); + } + } }; \ No newline at end of file diff --git a/mini9/main2.js b/mini9/main2.js index c448558..7000f9b 100644 --- a/mini9/main2.js +++ b/mini9/main2.js @@ -1,38 +1,38 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight, - results = []; - - for(var i = 0; i < 100; i += 1) { - results[i] = 0; - } - - update(); - - function update() { - addResult(); - draw(); - requestAnimationFrame(update); - } - - function addResult() { - var iterations = 3, - total = 0; - for(var i = 0; i < iterations; i += 1) { - total += utils.randomRange(0, 100); - } - result = Math.floor(total / iterations); - results[result] += 1; - } - - function draw() { - var w = width / 100; - for(var i = 0; i < 100; i += 1) { - var h = results[i] * -10; - context.fillRect(w * i, height, w, h); - } - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight, + results = []; + + for(var i = 0; i < 100; i += 1) { + results[i] = 0; + } + + update(); + + function update() { + addResult(); + draw(); + requestAnimationFrame(update); + } + + function addResult() { + var iterations = 3, + total = 0; + for(var i = 0; i < iterations; i += 1) { + total += utils.randomRange(0, 100); + } + result = Math.floor(total / iterations); + results[result] += 1; + } + + function draw() { + var w = width / 100; + for(var i = 0; i < 100; i += 1) { + var h = results[i] * -10; + context.fillRect(w * i, height, w, h); + } + } + }; \ No newline at end of file diff --git a/mini9/main3.js b/mini9/main3.js index e220e64..e54bcb0 100644 --- a/mini9/main3.js +++ b/mini9/main3.js @@ -1,14 +1,14 @@ -window.onload = function() { - var canvas = document.getElementById("canvas"), - context = canvas.getContext("2d"), - width = canvas.width = window.innerWidth, - height = canvas.height = window.innerHeight; - - for(var i = 0; i < 100000; i += 1) { - var x = utils.randomDist(0, width, 5), - y = utils.randomDist(0, height, 5); - - context.fillRect(x, y, 1, 1); - } - +window.onload = function() { + var canvas = document.getElementById("canvas"), + context = canvas.getContext("2d"), + width = canvas.width = window.innerWidth, + height = canvas.height = window.innerHeight; + + for(var i = 0; i < 100000; i += 1) { + var x = utils.randomDist(0, width, 5), + y = utils.randomDist(0, height, 5); + + context.fillRect(x, y, 1, 1); + } + }; \ No newline at end of file diff --git a/mini9/utils.js b/mini9/utils.js index 4d85a81..5fab762 100644 --- a/mini9/utils.js +++ b/mini9/utils.js @@ -1,82 +1,82 @@ -var utils = { - norm: function(value, min, max) { - return (value - min) / (max - min); - }, - - lerp: function(norm, min, max) { - return (max - min) * norm + min; - }, - - map: function(value, sourceMin, sourceMax, destMin, destMax) { - return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); - }, - - clamp: function(value, min, max) { - return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); - }, - - distance: function(p0, p1) { - var dx = p1.x - p0.x, - dy = p1.y - p0.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - distanceXY: function(x0, y0, x1, y1) { - var dx = x1 - x0, - dy = y1 - y0; - return Math.sqrt(dx * dx + dy * dy); - }, - - circleCollision: function(c0, c1) { - return utils.distance(c0, c1) <= c0.radius + c1.radius; - }, - - circlePointCollision: function(x, y, circle) { - return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; - }, - - pointInRect: function(x, y, rect) { - return utils.inRange(x, rect.x, rect.x + rect.width) && - utils.inRange(y, rect.y, rect.y + rect.height); - }, - - inRange: function(value, min, max) { - return value >= Math.min(min, max) && value <= Math.max(min, max); - }, - - rangeIntersect: function(min0, max0, min1, max1) { - return Math.max(min0, max0) >= Math.min(min1, max1) && - Math.min(min0, max0) <= Math.max(min1, max1); - }, - - rectIntersect: function(r0, r1) { - return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && - utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); - }, - - degreesToRads: function(degrees) { - return degrees / 180 * Math.PI; - }, - - radsToDegrees: function(radians) { - return radians * 180 / Math.PI; - }, - - randomRange: function(min, max) { - return min + Math.random() * (max - min); - }, - - randomInt: function(min, max) { - return Math.floor(min + Math.random() * (max - min + 1)); - }, - - randomDist: function(min, max, iterations) { - var total = 0; - - for(var i = 0; i < iterations; i += 1) { - total += utils.randomRange(min, max); - } - return total / iterations; - } - +var utils = { + norm: function(value, min, max) { + return (value - min) / (max - min); + }, + + lerp: function(norm, min, max) { + return (max - min) * norm + min; + }, + + map: function(value, sourceMin, sourceMax, destMin, destMax) { + return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax); + }, + + clamp: function(value, min, max) { + return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max)); + }, + + distance: function(p0, p1) { + var dx = p1.x - p0.x, + dy = p1.y - p0.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + distanceXY: function(x0, y0, x1, y1) { + var dx = x1 - x0, + dy = y1 - y0; + return Math.sqrt(dx * dx + dy * dy); + }, + + circleCollision: function(c0, c1) { + return utils.distance(c0, c1) <= c0.radius + c1.radius; + }, + + circlePointCollision: function(x, y, circle) { + return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius; + }, + + pointInRect: function(x, y, rect) { + return utils.inRange(x, rect.x, rect.x + rect.width) && + utils.inRange(y, rect.y, rect.y + rect.height); + }, + + inRange: function(value, min, max) { + return value >= Math.min(min, max) && value <= Math.max(min, max); + }, + + rangeIntersect: function(min0, max0, min1, max1) { + return Math.max(min0, max0) >= Math.min(min1, max1) && + Math.min(min0, max0) <= Math.max(min1, max1); + }, + + rectIntersect: function(r0, r1) { + return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) && + utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height); + }, + + degreesToRads: function(degrees) { + return degrees / 180 * Math.PI; + }, + + radsToDegrees: function(radians) { + return radians * 180 / Math.PI; + }, + + randomRange: function(min, max) { + return min + Math.random() * (max - min); + }, + + randomInt: function(min, max) { + return Math.floor(min + Math.random() * (max - min + 1)); + }, + + randomDist: function(min, max, iterations) { + var total = 0; + + for(var i = 0; i < iterations; i += 1) { + total += utils.randomRange(min, max); + } + return total / iterations; + } + } \ No newline at end of file