Created
March 22, 2013 16:39
-
-
Save milcktoast/5222800 to your computer and use it in GitHub Desktop.
Car along a quadratic curve.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="canvas"></div> | |
| <div id="info"> | |
| <div id="angle"></div> | |
| </div> | |
| <script type="text/javascript" src="https://raw.github.com/toji/gl-matrix/master/dist/gl-matrix.js"></script> | |
| <script type="text/javascript" src="https://raw.github.com/dannygarcia/fil/master/fil.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var cvs = new fil.Canvas(); | |
| var pen = new fil.Pen(); | |
| var frame = new fil.Frame(); | |
| var infoAngle = document.getElementById("angle"); | |
| var el = document.getElementById("canvas"); | |
| cvs.init({ | |
| container : el, | |
| ratio : false | |
| }); | |
| var ctx = cvs.context(); | |
| var WIDTH = cvs.width; | |
| var WIDTH_HALF = WIDTH / 2; | |
| var HEIGHT = cvs.height; | |
| var cursor = vec2.create(); | |
| var needsUpdate = true; | |
| var QuadraticCurve = function (x, y, width) { | |
| var halfWidth = width / 2; | |
| this.a = vec2.fromValues(x, y); | |
| this.b = vec2.fromValues(x + width, y + halfWidth); | |
| this.c = vec2.fromValues(x, y + width); | |
| }; | |
| QuadraticCurve.prototype = { | |
| baseVal : function (t, index) { | |
| var mt = 1 - t; | |
| var a = this.a[index]; | |
| var b = this.b[index]; | |
| var c = this.c[index]; | |
| return mt * mt * a + 2 * mt * t * b + t * t * c; | |
| }, | |
| derivativeVal : function (t, index) { | |
| var a = this.a[index]; | |
| var b = this.b[index]; | |
| var c = this.c[index]; | |
| return a * (2 * t - 2) + b * (2 - 4 * t) + 2 * c * t; | |
| }, | |
| derivativeRoot : function (index) { | |
| var t = -1; | |
| var a = this.a[index]; | |
| var b = this.b[index]; | |
| var c = this.c[index]; | |
| var denominator = a -2 * b + c; | |
| if(denominator !== 0) { | |
| t = (a - b) / denominator; | |
| } | |
| return t; | |
| }, | |
| pointAt : function (v, t) { | |
| v[0] = this.baseVal(t, 0); | |
| v[1] = this.baseVal(t, 1); | |
| }, | |
| angleAt : (function () { | |
| var slope = vec2.create(); | |
| return function (t) { | |
| slope[0] = this.derivativeVal(t, 0); | |
| slope[1] = this.derivativeVal(t, 1); | |
| vec2.normalize(slope, slope); | |
| var angle = Math.atan2(slope[1], slope[0]); | |
| return angle * 180 / Math.PI; | |
| }; | |
| }()), | |
| render : function () { | |
| var a = this.a, b = this.b, c = this.c; | |
| pen.line(a, b, "array"); | |
| pen.line(b, c, "array"); | |
| ctx.beginPath(); | |
| ctx.moveTo(a[0], a[1]); | |
| ctx.quadraticCurveTo(b[0], b[1], c[0], c[1]); | |
| ctx.stroke(); | |
| } | |
| }; | |
| // Pen does not require initialization, but it does require a canvas context. | |
| pen.context(ctx); | |
| pen.fill("white"); | |
| window.onmousemove = function (e) { | |
| cursor[0] = e.pageX; | |
| cursor[1] = e.pageY; | |
| needsUpdate = true; | |
| }; | |
| var Car = function (opts) { | |
| this.sprite = new Image(); | |
| this.sprite.src = opts.sprite; | |
| this.track = opts.track; | |
| this.spriteLen = opts.spriteLen; | |
| this.angleStep = opts.angleStep; | |
| this.size = opts.size; | |
| this.frame = vec2.create(); | |
| this.pos = vec2.create(); | |
| this.lastPos = vec2.create(); | |
| this.dir = vec2.create(); | |
| }; | |
| Car.prototype = { | |
| setFrame : function (angle) { | |
| var frame = -Math.round(angle / this.angleStep) + 14; | |
| this.frame[0] = frame; | |
| infoAngle.textContent = frame + " - " + angle; | |
| }, | |
| update : function (f) { | |
| var t = cursor[1] / HEIGHT; | |
| // Calc point on track, set pos | |
| this.track.pointAt(this.pos, t); | |
| // Calc angle, set frame | |
| var angle = this.track.angleAt(t); | |
| this.setFrame(angle); | |
| }, | |
| render : function (f) { | |
| var s = this.size; | |
| var hs = s / 2; | |
| var f = this.frame; | |
| var p = this.pos; | |
| this.track.render(); | |
| ctx.drawImage(this.sprite, s * f[0], s * f[1], s, s, p[0] - hs, p[1] - hs, s, s); | |
| } | |
| }; | |
| var car = new Car({ | |
| sprite: "http://i.imgur.com/VDRs9eY.png", | |
| spriteLen : 16, | |
| angleStep : 22.5, | |
| size : 64, | |
| track: new QuadraticCurve(WIDTH / 4, 100, 128) | |
| }); | |
| frame.start(); | |
| frame.step = function (f) { | |
| if (needsUpdate) { | |
| ctx.fillRect(0, 0, WIDTH, HEIGHT); | |
| car.update(f); | |
| car.render(f); | |
| needsUpdate = false; | |
| } | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| * { | |
| margin: 0; | |
| padding: 0; | |
| height: 100%; | |
| width: 100%; | |
| } | |
| body { | |
| font-family: monospace; | |
| font-size: 10px; | |
| } | |
| #canvas { | |
| width: 100%; | |
| height: 100%; | |
| } | |
| #info { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| padding: 4px; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment