X-Git-Url: https://git.r.bdr.sh/rbdr/heart/blobdiff_plain/910278aad4a0b47dc40112839a18bc8e590302e5..d0f30873ebe2907b241a936a3e70487dedaf0701:/js/lib/heart_renderer.js diff --git a/js/lib/heart_renderer.js b/js/lib/heart_renderer.js index f6ece86..78ca182 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,19 @@ */ 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._following = null; // The status of mouse follow. + this._center = null; 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 @@ -50,6 +61,8 @@ green: 50 }; + this.startFollowingMouse(); + Object.assign(this, config); } @@ -64,6 +77,55 @@ render(element) { element.appendChild(this.canvas); + this.resize(); + } + + /** + * Resizes the canvas + * + * @memberof HeartRenderer + * @function render + * @instance + */ + resize() { + + if (this.canvas.parentElement) { + this.canvas.width = this.canvas.parentElement.offsetWidth; + this.canvas.height = this.canvas.parentElement.offsetHeight; + } + } + + /** + * Follows the mouse + * + * @memberof HeartRenderer + * @function startFollowingMouse + * @instance + */ + startFollowingMouse() { + + if (!this._following) { + console.log('Start Following Mouse'); + this._following = this._setCenterFromMouse.bind(this); + this.canvas.addEventListener('mousemove', this._following); + } + } + + /** + * Stop following the mouse + * + * @memberof HeartRenderer + * @function stopFollowingMouse + * @instance + */ + stopFollowingMouse() { + + if (this._following) { + console.log('Stop Following Mouse'); + this.canvas.removeEventListener('mouseover', this._following); + this._following = null; + this._center = null; + } } /** @@ -127,12 +189,65 @@ // 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; + let canvasCenterX = this._center ? this._center.x : Math.round(canvasWidth / 2); + let canvasCenterY = this._center ? this._center.y : 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); + } + + // Sets the center from mouse + _setCenterFromMouse (event) { + this._center = this._center || {}; + + console.log('tracking'); + + this._center.x = event.offsetX; + this._center.y = event.offsetY; } };