@thi.ng/color
Version:
Array-based color types, CSS parsing, conversions, transformations, declarative theme generation, gradients, presets
158 lines (157 loc) • 4.13 kB
JavaScript
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
};