X-Git-Url: https://git.r.bdr.sh/rbdr/heart/blobdiff_plain/0e4a069f3faaa736089b9857dd249aacd863fa44..f895bdac3edf5d607331628798fd6d1b6d8d6f0e:/js/lib/heart_renderer.js diff --git a/js/lib/heart_renderer.js b/js/lib/heart_renderer.js index f6ece86..fd4adf6 100644 --- a/js/lib/heart_renderer.js +++ b/js/lib/heart_renderer.js @@ -25,11 +25,9 @@ * @instance * @name canvas * @type HTMLCanvasElement - * @default A brand new full width and height canvas + * @default A brand new canvas */ this.canvas = window.document.createElement('canvas'); - this.canvas.style.height = '100%'; - this.canvas.style.width = '100%'; /** * The maximum fps that will be used @@ -42,6 +40,17 @@ */ this.fps = 60; + /** + * The size of the heart as a percentage of the canvas smallest dimension + * + * @memberof HeartRenderer + * @instance + * @name heartSize + * @type Number + * @default 50 + */ + this.heartSize = 50; + this._animating = false; // The status of the animation. this._previousFrameTime = Date.now(); // The timestamp of the last frame for fps control this._currentColor = { // The current color that will be painted @@ -64,6 +73,23 @@ render(element) { element.appendChild(this.canvas); + this.resize(); + } + + /** + * Resizes the canvas + * + * @memberof HeartRenderer + * @function render + * @instance + * @param {HTMLElement} element the element where we will attach our canvas + */ + resize() { + + if (this.canvas.parentElement) { + this.canvas.width = this.canvas.parentElement.offsetWidth; + this.canvas.height = this.canvas.parentElement.offsetHeight; + } } /** @@ -127,12 +153,55 @@ // The actual animation processing function. _animateStep(context, delta) { + this._updateColor(delta); + this._drawHeart(context, delta); + } + + // Updates the current color + _updateColor(delta) { + this._currentColor.red = Math.round(this._currentColor.red + delta * kRedSpeed) % kColorIteratorLimit; this._currentColor.green = Math.round(this._currentColor.green + delta * kGreenSpeed) % kColorIteratorLimit; this._currentColor.blue = Math.round(this._currentColor.blue + delta * kBlueSpeed) % kColorIteratorLimit; + } + + // Draws a heart + _drawHeart(context, delta) { + + const canvasHeight = this.canvas.height; + const canvasWidth = this.canvas.width; + const referenceDimension = canvasWidth < canvasHeight ? canvasWidth : canvasHeight; + + const heartSize = Math.round(referenceDimension * this.heartSize * .01); + const radius = heartSize / 2; + const canvasCenterX = Math.round(canvasWidth / 2); + const canvasCenterY = Math.round(canvasHeight / 2); + const centerX = -radius; + const centerY = -radius; + + + // translate and rotate, adjusting for weight of the heart. + context.translate(canvasCenterX, canvasCenterY + radius / 4); + context.rotate(-45 * Math.PI / 180); + + // Fill the ventricles of the heart context.fillStyle = `rgb(${this._currentColor.red}, ${this._currentColor.green}, ${this._currentColor.blue})`; - context.fillRect(0, 0, this.canvas.scrollWidth, this.canvas.scrollHeight); + context.fillRect(centerX, centerY, heartSize, heartSize); + + // Left atrium + context.beginPath(); + context.arc(centerX + radius, centerY, radius, 0, 2 * Math.PI, false); + context.fill(); + context.closePath(); + + // Right atrium + context.beginPath(); + context.arc(centerX + heartSize, centerY + radius, radius, 0, 2 * Math.PI, false); + context.fill(); + context.closePath(); + + context.setTransform(1, 0, 0, 1, 0, 0); } };