UNPKG

@thi.ng/color

Version:

Array-based color types, CSS parsing, conversions, transformations, declarative theme generation, gradients, presets

158 lines (157 loc) 4.13 kB
import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { isNumber } from "@thi.ng/checks/is-number"; import { isString } from "@thi.ng/checks/is-string"; import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; import { SYSTEM } from "@thi.ng/random/system"; import { mapStridedBuffer } from "@thi.ng/vectors/buffer"; import { declareIndex } from "@thi.ng/vectors/accessors"; import { eqDelta4 } from "@thi.ng/vectors/eqdelta"; import { parseCss } from "../css/parse-css.js"; import { __scale8bit } from "../internal/scale.js"; import { srgbIntAbgr32, srgbIntArgb32 } from "../srgb/srgb-int.js"; import { srgb } from "../srgb/srgb.js"; import { intArgb32Srgb } from "./int-srgb.js"; class Int32 { constructor(buf, offset = 0, stride = 1) { this.offset = offset; this.stride = stride; this.buf = buf || [0]; } buf; value; eqDelta(o, eps) { return eqDelta4( // channel order irrelevant here... intArgb32Srgb([], this[0]), intArgb32Srgb([], o[0]), eps ); } get length() { return 1; } get range() { return [[0], [4294967295]]; } get alpha() { return (this[0] >>> 24) / 255; } set alpha(x) { this[0] = this[0] & 16777215 | __scale8bit(x, 24); } get xyz() { const val = this[0]; return [ (val >> 16 & 255) / 255, (val >> 8 & 255) / 255, (val & 255) / 255 ]; } *[Symbol.iterator]() { yield this[0]; } deref() { return [this[0]]; } randomize(rnd = SYSTEM) { const x = this[0]; this[0] = x & 4278190080 | rnd.int() & 16777215; return this; } clamp() { return this; } set(src) { this[0] = src[0]; return this; } toJSON() { return [this[0]]; } } class ARGB extends Int32 { get mode() { return "argb32"; } get r() { return (this[0] >> 16 & 255) / 255; } set r(x) { this[0] = this[0] & 4278255615 | __scale8bit(x, 16); } get g() { return (this[0] >> 8 & 255) / 255; } set g(x) { this[0] = this[0] & 4294902015 | __scale8bit(x, 8); } get b() { return (this[0] & 255) / 255; } set b(x) { this[0] = this[0] & 4294967040 | __scale8bit(x); } copy() { return new ARGB([this[0]]); } copyView() { return new ARGB(this.buf, this.offset, this.stride); } empty() { return new ARGB(); } } declareIndex(ARGB.prototype, "value", 0); class ABGR extends Int32 { get mode() { return "abgr32"; } get r() { return (this[0] & 255) / 255; } set r(x) { this[0] = this[0] & 4294967040 | __scale8bit(x); } get g() { return (this[0] >> 8 & 255) / 255; } set g(x) { this[0] = this[0] & 4294902015 | __scale8bit(x, 8); } get b() { return (this[0] >> 16 & 255) / 255; } set b(x) { this[0] = this[0] & 4278255615 | __scale8bit(x, 16); } copy() { return new ABGR([this[0]]); } copyView() { return new ABGR(this.buf, this.offset, this.stride); } empty() { return new ABGR(); } } declareIndex(ABGR.prototype, "value", 0); const __defInt = (ctor, fromSrgb) => { const factory = (src, ...args) => src == null ? new ctor() : isNumber(src) ? args.length && args.every(isNumber) ? new ctor([srgbIntArgb32([src, ...args])]) : new ctor([src], ...args) : isString(src) ? factory(parseCss(src)) : isArrayLike(src) ? isString(src.mode) ? new ctor([fromSrgb(srgb(src))], ...args) : new ctor(src, ...args) : implementsFunction(src, "deref") ? new ctor([fromSrgb(srgb(src))], ...args) : illegalArgs(`can't create a ARGB32 color from: ${src}`); factory.class = ctor; factory.range = [[0], [4294967295]]; factory.random = (rnd = SYSTEM, buf, idx, stride) => new ctor(buf, idx, stride).set([ rnd.int() & 16777215 | 4278190080 ]); factory.mapBuffer = (buf, num = buf.length, start = 0, cstride = 1, estride = 1) => mapStridedBuffer(ctor, buf, num, start, cstride, estride); return factory; }; const argb32 = __defInt(ARGB, srgbIntArgb32); const abgr32 = __defInt(ABGR, srgbIntAbgr32); export { ABGR, ARGB, Int32, abgr32, argb32 };