gibbon.js
Version:
Actor/Component system for use with pixi.js.
110 lines (79 loc) • 2.49 kB
text/typescript
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;
}
}
}
}