UNPKG

gibbon.js

Version:

Actor/Component system for use with pixi.js.

110 lines (79 loc) 2.49 kB
import { htmlStr, rgbaStr } from '../utils/color-utils'; export class Gradient { public readonly colors: number[]; /** * @property {number[]} stops - percent stops of each color. * first step should start at 0, last should be 1. */ public readonly stops: number[]; constructor(colors: number[], stops: number[]) { this.colors = colors; this.stops = stops; } /** * Create a linear gradient object for the context which may include alpha. */ public toAlphaLinear(ctx: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number) { const grad = ctx.createLinearGradient(x0, y0, x1, y1); this.addAlphaStops(grad); return grad; } /** * Create a radial gradient object for the context that includes alpha channel. */ public toAlphaRadial(ctx: CanvasRenderingContext2D, r0: number, r1: number, x: number = 0, y: number = 0) { const grad = ctx.createRadialGradient(x, y, r0, x, y, r1); this.addAlphaStops(grad); return grad; } /** * Create a linear gradient object for the context. alpha is ignored. */ public toLinear(ctx: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number) { const grad = ctx.createLinearGradient(x0, y0, x1, y1); this.addStops(grad); return grad; } /** * Create a radial gradient object for the context. alpha is ignored. */ public toRadial(ctx: CanvasRenderingContext2D, r0: number, r1: number, x: number = 0, y: number = 0) { const grad = ctx.createRadialGradient(x, y, r0, x, y, r1); this.addStops(grad); return grad; } /** * Add gradient stops which include an alpha component. */ public addAlphaStops(grad: CanvasGradient) { for (let i = 0; i < this.stops.length; i++) { grad.addColorStop(this.stops[i], rgbaStr(this.colors[i])); } } /** * Add the Gradient color steps to the CanvasGradient with no alpha. * @param {CanvasGradient} grad */ public addStops(grad: CanvasGradient) { for (let i = 0; i < this.stops.length; i++) { grad.addColorStop(this.stops[i], htmlStr(this.colors[i])); } } /** * Ensure stops are nondecreasing between 0 and 1. */ public repair() { const a = this.stops; let prev = 0; for (let i = a.length - 1; i >= 0; i--) { const cur = a[i]; if (cur < prev) { a[i] = prev; } else if (cur > 1) { a[i] = prev = 1; } else { prev = cur; } } } }