* @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
*/
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
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;
+ }
}
/**
// 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);
}
};