From 117bc020e7fa73c3e73229cdd3bf162d572a923b Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Sat, 16 Dec 2023 23:14:58 +0200 Subject: [PATCH] Added gradients and smiley function --- src/API.ts | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/src/API.ts b/src/API.ts index 0a4df1f..f5bba41 100644 --- a/src/API.ts +++ b/src/API.ts @@ -2219,6 +2219,80 @@ export class UserAPI { return canvas.height; } + public background = (color: string|number, ...gb:number[]): void => { + /** + * Set background color of the canvas. + * @param color - The color to set. String or 3 numbers representing RGB values. + */ + const canvas: HTMLCanvasElement = this.app.interface.drawings as HTMLCanvasElement; + const ctx = canvas.getContext("2d")!; + if(typeof color === "number") color = `rgb(${color},${gb[0]},${gb[1]})`; + ctx.fillStyle = color; + ctx.fillRect(0, 0, canvas.width, canvas.height); + } + + public linearGradient = (x1: number, y1: number, x2: number, y2: number, ...stops: (number|string)[]) => { + /** + * Set linear gradient on the canvas. + * @param x1 - The x-coordinate of the start point + * @param y1 - The y-coordinate of the start point + * @param x2 - The x-coordinate of the end point + * @param y2 - The y-coordinate of the end point + * @param stops - The stops to set. Pairs of numbers representing the position and color of the stop. + */ + const canvas: HTMLCanvasElement = this.app.interface.drawings as HTMLCanvasElement; + const ctx = canvas.getContext("2d")!; + const gradient = ctx.createLinearGradient(x1, y1, x2, y2); + // Parse pairs of values from stops + for(let i=0; i { + /** + * Set radial gradient on the canvas. + * @param x1 - The x-coordinate of the start circle + * @param y1 - The y-coordinate of the start circle + * @param r1 - The radius of the start circle + * @param x2 - The x-coordinate of the end circle + * @param y2 - The y-coordinate of the end circle + * @param r2 - The radius of the end circle + * @param stops - The stops to set. Pairs of numbers representing the position and color of the stop. + */ + const canvas: HTMLCanvasElement = this.app.interface.drawings as HTMLCanvasElement; + const ctx = canvas.getContext("2d")!; + const gradient = ctx.createRadialGradient(x1, y1, r1, x2, y2, r2); + for(let i=0; i { + /** + * Set conic gradient on the canvas. + * @param x - The x-coordinate of the center of the gradient + * @param y - The y-coordinate of the center of the gradient + * @param angle - The angle of the gradient, in radians + * @param stops - The stops to set. Pairs of numbers representing the position and color of the stop. + */ + const canvas: HTMLCanvasElement = this.app.interface.drawings as HTMLCanvasElement; + const ctx = canvas.getContext("2d")!; + const gradient = ctx.createConicGradient(x, y, angle); + for(let i=0; i { /** * Draws on the canvas. @@ -2331,6 +2405,73 @@ export class UserAPI { ctx.restore(); } + public smiley = ( + x: number, + y: number, + radius: number, + fillStyle: string, + eyeSize: number = 1.0, + happiness: number = 0.0, + rotation: number = 0 + ): void => { + const canvas: HTMLCanvasElement = this.app.interface.drawings as HTMLCanvasElement; + const ctx = canvas.getContext("2d")!; + // Map the rotation value to an angle within the range of -PI to PI + const rotationAngle = rotation/100 * Math.PI; + ctx.save(); + ctx.translate(x, y); + ctx.rotate(rotationAngle); + + // Draw face + ctx.beginPath(); + ctx.arc(0, 0, radius, 0, 2 * Math.PI); + ctx.fillStyle = fillStyle; + ctx.fill(); + ctx.lineWidth = radius / 20; + ctx.strokeStyle = "black"; + ctx.stroke(); + + // Draw eyes + const eyeY = -radius / 5; + const eyeXOffset = radius / 2.5; + const eyeRadiusX = radius / 8; + const eyeRadiusY = eyeSize * radius / 10; + + ctx.beginPath(); + ctx.ellipse(-eyeXOffset, eyeY, eyeRadiusX, eyeRadiusY, 0, 0, 2 * Math.PI); + ctx.fillStyle = "black"; + ctx.fill(); + + ctx.beginPath(); + ctx.ellipse(eyeXOffset, eyeY, eyeRadiusX, eyeRadiusY, 0, 0, 2 * Math.PI); + ctx.fillStyle = "black"; + ctx.fill(); + + // Draw mouth with happiness number -1.0 to 1.0. 0.0 Should be a straight line. + const mouthY = radius / 2; + const mouthLength = radius * 0.9; + const smileFactor = 0.25; // Adjust for the smile curvature + + let controlPointX = 0; + let controlPointY = 0; + + if (happiness >= 0) { + controlPointY = mouthY + happiness * smileFactor * radius / 2; + } else { + controlPointY = mouthY + happiness * smileFactor * radius / 2; + } + + ctx.beginPath(); + ctx.moveTo(-mouthLength / 2, mouthY); + ctx.quadraticCurveTo(controlPointX, controlPointY, mouthLength / 2, mouthY); + ctx.lineWidth = 10; + ctx.strokeStyle = "black"; + ctx.stroke(); + ctx.restore(); + + } + + // ============================================================= // OSC Functions // =============================================================