Skip to content

Commit

Permalink
Complete spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
dy committed Sep 15, 2023
1 parent 35354f1 commit 3c5140e
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 51 deletions.
91 changes: 52 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function parse(cstr) {
}

//hex
else if (/^#[A-Fa-f0-9]+$/.test(cstr)) {
else if (cstr[0] === '#') {
var base = cstr.slice(1)
var size = base.length
var isShort = size <= 4
Expand Down Expand Up @@ -83,45 +83,58 @@ function parse(cstr) {
space = 'rgb'
}

//color space
else if (m = /^((?:rgba?|hs[lvb]a?|hwba?|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms|oklch|oklab))\s*\(([^\)]*)\)/.exec(cstr)) {
// color space
else if (m = /^((?:rgba?|hs[lvb]a?|hwba?|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms|oklch|oklab|color))\s*\(([^\)]*)\)/.exec(cstr)) {
var name = m[1]
var isRGB = name === 'rgb'
var base = name.replace(/a$/, '')
space = base
var size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3
parts = m[2].trim()
.split(/\s*[,\/]\s*|\s+/)
.map(function (x, i) {
//<percentage>
if (x[x.length - 1] === '%') {
//alpha
if (i === 3) return parseFloat(x) / 100
//rgb
if (base === 'rgb') return parseFloat(x) * 255 / 100
// lch/oklch
if (/^(ok)?l/.test(base)) {
if (!i) return parseFloat(x) / 100
return parseFloat(x) * 0.4 / 100
}
return parseFloat(x)
}
//hue
if (base[i] === 'h') {
//<base-hue>
if (baseHues[x] !== undefined) return baseHues[x]
//<deg>
if (/deg$/.test(x)) return parseFloat(x)
//<turn>
if (/turn$/.test(x)) return parseFloat(x) * 360
}
if (x === 'none') return 0
return parseFloat(x)
})

if (name === base) parts.push(1)
alpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]
parts = parts.slice(0, size)
space = name.replace(/a$/, '')
var dims = space === 'cmyk' ? 4 : space === 'gray' ? 1 : 3
parts = m[2].trim().split(/\s*[,\/]\s*|\s+/)

// color(srgb-linear x x x) -> srgb-linear(x x x)
if (space === 'color') space = parts.shift()

parts = parts.map(function (x, i) {
//<percentage>
if (x[x.length - 1] === '%') {
x = parseFloat(x) / 100
// alpha -> 0..1
if (i === 3) return x
// rgb -> 0..255
if (space === 'rgb') return x * 255
// hsl, hwb H -> 0..100
if (space[0] === 'h') return x * 100
// lch, lab L -> 0..100
if (space[0] === 'l' && !i) return x * 100
// lab A B -> -125..125
if (space === 'lab') return x * 125
// lch C -> 0..150, H -> 0..360
if (space === 'lch') return i < 2 ? x * 150 : x * 360
// oklch/oklab L -> 0..1
if (space[0] === 'o' && !i) return x
// oklab A B -> -0.4..0.4
if (space === 'oklab') return x * 0.4
// oklch C -> 0..0.4, H -> 0..360
if (space === 'oklch') return i < 2 ? x * 0.4 : x * 360
// color(xxx) -> 0..1
return x
}

//hue
if (space[i] === 'h' || (i === 2 && space[space.length - 1] === 'h')) {
//<base-hue>
if (baseHues[x] !== undefined) return baseHues[x]
//<deg>
if (x.endsWith('deg')) return parseFloat(x)
//<turn>
if (x.endsWith('turn')) return parseFloat(x) * 360
if (x.endsWith('grad')) return parseFloat(x) * 360 / 400
if (x.endsWith('rad')) return parseFloat(x) * 180 / Math.PI
}
if (x === 'none') return 0
return parseFloat(x)
});

alpha = parts.length > dims ? parts.pop() : 1
}

//named channels case
Expand Down
14 changes: 7 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ parse('hsla(12 10% 50% / .3)')
* [x] `hwb(H, W, B)`
* [x] `cmyk(C, M, Y, K)`
* [x] `xyz(X, Y, Z)`
* [x] `lab(L, A, B)`
* [x] `lab(L a b[ / A])`
* [x] `lch(L, C, H)`
* [x] `lch(L C H[ / A])`
* [x] `luv(L, U, V)`
* [x] `luv(L U V[ / A])`
* [x] `oklab(L a b[ / A])`
* [ ] `oklch(L C H[ / A])`
* [ ] `color(space c1 c2 c3[ / A])`
* [x] `lab(L, A, B)`
* [x] `lab(L a b[ / A])` - see [limits](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lab)
* [x] `lch(L, C, H)`
* [x] `lch(L C H[ / A])` - see [limits](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lch)
* [x] `oklab(L a b[ / A])` - see [limits](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklab)
* [x] `oklch(L C H[ / A])` - see [limits](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch)
* [x] `color(space c1 c2 c3[ / A])`
* [x] `R:10 G:20 B:30`
* [x] `(R10 / G20 / B30)`
* [x] `C100/M80/Y0/K35`
Expand Down
57 changes: 52 additions & 5 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,53 @@ t('luv(0.25 0.25 0.25 / 0.5)', function (t) {
});
t.end()
});

t('color(...)', function (t) {
// --srgb: color(srgb 1 1 1);
t.deepEqual(parse('color(srgb-linear 1 1 1)'), {
space: 'srgb-linear',
values: [1, 1, 1],
alpha: 1
});
// --srgb-linear: color(srgb-linear 100% 100% 100% / 50%);
t.deepEqual(parse('color(srgb-linear 100% 100% 100% / 50%)'), {
space: 'srgb-linear',
values: [1, 1, 1],
alpha: 0.5
});
// --display-p3: color(display-p3 1 1 1);
t.deepEqual(parse('color(display-p3 1 1 1)'), {
space: 'display-p3',
values: [1, 1, 1],
alpha: 1
});
// --rec2020: color(rec2020 0 0 0);
t.deepEqual(parse('color(rec2020 0 0 0)'), {
space: 'rec2020',
values: [0, 0, 0],
alpha: 1
});
// --a98-rgb: color(a98-rgb 1 1 1 / 25%);
t.deepEqual(parse('color(a98-rgb 1 1 1 / 25%)'), {
space: 'a98-rgb',
values: [1, 1, 1],
alpha: 0.25
});
// --prophoto: color(prophoto-rgb 0% 0% 0%);
t.deepEqual(parse('color(prophoto-rgb 0% 0% 0%)'), {
space: 'prophoto-rgb',
values: [0, 0, 0],
alpha: 1
});
// --xyz: color(xyz 1 1 1);
t.deepEqual(parse('color(xyz 1 1 1)'), {
space: 'xyz',
values: [1, 1, 1],
alpha: 1
});
t.end()
});

t('oklab', function (t) {
t.deepEqual(parse('oklab(40.1% 0.1143 0.045)'), {
space: 'oklab',
Expand All @@ -409,21 +456,21 @@ t('oklab', function (t) {
});
t.end()
});
t.skip('oklch', function (t) {
t('oklch', function (t) {
t.deepEqual(parse('oklch(40.1% 0.1143 0.045)'), {
space: 'oklch',
values: [0.401, 0.1143, 0.045],
alpha: 1
});
t.deepEqual(parse('oklch(59.69% 10% 49.77 / 0.5)'), {
space: 'oklch',
values: [0.5969, 0.1007, -0.1191],
values: [0.5969, 0.04000000000000001, 49.77],
alpha: 0.5
});
t.deepEqual(parse('oklch(40.1% 0.156 49.77% / .5)'), {
t.deepEqual(parse('oklch(40.1% 0.156 49.1% / .5)'), {
space: 'oklch',
values: [0.123, 0.4, -0.4],
alpha: 2
values: [0.401, 0.156, 176.76],
alpha: .5
});
t.deepEqual(parse('oklch(none none none / none)'), {
space: 'oklch',
Expand Down

0 comments on commit 3c5140e

Please sign in to comment.