@material/material-color-utilities
Advanced tools
Comparing version
@@ -30,49 +30,49 @@ /** | ||
const answer = Blend.harmonize(RED, BLUE); | ||
expect(answer).matchesColor(0xffFB0054); | ||
expect(answer).matchesColor(0xffFB0057); | ||
}); | ||
it('redToGreen', () => { | ||
const answer = Blend.harmonize(RED, GREEN); | ||
expect(answer).matchesColor(0xffDA5400); | ||
expect(answer).matchesColor(0xffD85600); | ||
}); | ||
it('redToYellow', () => { | ||
const answer = Blend.harmonize(RED, YELLOW); | ||
expect(answer).matchesColor(0xffDA5400); | ||
expect(answer).matchesColor(0xffD85600); | ||
}); | ||
it('blueToGreen', () => { | ||
const answer = Blend.harmonize(BLUE, GREEN); | ||
expect(answer).matchesColor(0xff0047A7); | ||
expect(answer).matchesColor(0xff0047A3); | ||
}); | ||
it('blueToRed', () => { | ||
const answer = Blend.harmonize(BLUE, RED); | ||
expect(answer).matchesColor(0xff5600DE); | ||
expect(answer).matchesColor(0xff5700DC); | ||
}); | ||
it('blueToYellow', () => { | ||
const answer = Blend.harmonize(BLUE, YELLOW); | ||
expect(answer).matchesColor(0xff0047A7); | ||
expect(answer).matchesColor(0xff0047A3); | ||
}); | ||
it('greenToBlue', () => { | ||
const answer = Blend.harmonize(GREEN, BLUE); | ||
expect(answer).matchesColor(0xff00FC91); | ||
expect(answer).matchesColor(0xff00FC94); | ||
}); | ||
it('greenToRed', () => { | ||
const answer = Blend.harmonize(GREEN, RED); | ||
expect(answer).matchesColor(0xffADF000); | ||
expect(answer).matchesColor(0xffB1F000); | ||
}); | ||
it('greenToYellow', () => { | ||
const answer = Blend.harmonize(GREEN, YELLOW); | ||
expect(answer).matchesColor(0xffADF000); | ||
expect(answer).matchesColor(0xffB1F000); | ||
}); | ||
it('yellowToBlue', () => { | ||
const answer = Blend.harmonize(YELLOW, BLUE); | ||
expect(answer).matchesColor(0xffEBFFB2); | ||
expect(answer).matchesColor(0xffEBFFBA); | ||
}); | ||
it('yellowToGreen', () => { | ||
const answer = Blend.harmonize(YELLOW, GREEN); | ||
expect(answer).matchesColor(0xffEBFFB2); | ||
expect(answer).matchesColor(0xffEBFFBA); | ||
}); | ||
it('yellowToRed', () => { | ||
const answer = Blend.harmonize(YELLOW, RED); | ||
expect(answer).matchesColor(0xffFFF6DC); | ||
expect(answer).matchesColor(0xffFFF6E3); | ||
}); | ||
}); | ||
//# sourceMappingURL=blend_test.js.map |
@@ -54,13 +54,2 @@ /** | ||
static cam16Ucs(from: number, to: number, amount: number): number; | ||
/** | ||
* Sign of direction change needed to travel from one angle to | ||
* another. | ||
* | ||
* @param from The angle travel starts from, in degrees. | ||
* @param to The angle travel ends at, in degrees. | ||
* @return -1 if decreasing from leads to the shortest travel | ||
* distance, 1 if increasing from leads to the shortest travel | ||
* distance. | ||
*/ | ||
private static rotationDirection; | ||
} |
@@ -48,3 +48,3 @@ /** | ||
const outputHue = mathUtils.sanitizeDegreesDouble(fromHct.hue + | ||
rotationDegrees * Blend.rotationDirection(fromHct.hue, toHct.hue)); | ||
rotationDegrees * mathUtils.rotationDirection(fromHct.hue, toHct.hue)); | ||
return Hct.from(outputHue, fromHct.chroma, fromHct.tone).toInt(); | ||
@@ -92,30 +92,3 @@ } | ||
} | ||
/** | ||
* Sign of direction change needed to travel from one angle to | ||
* another. | ||
* | ||
* @param from The angle travel starts from, in degrees. | ||
* @param to The angle travel ends at, in degrees. | ||
* @return -1 if decreasing from leads to the shortest travel | ||
* distance, 1 if increasing from leads to the shortest travel | ||
* distance. | ||
*/ | ||
static rotationDirection(from, to) { | ||
const a = to - from; | ||
const b = to - from + 360.0; | ||
const c = to - from - 360.0; | ||
const aAbs = Math.abs(a); | ||
const bAbs = Math.abs(b); | ||
const cAbs = Math.abs(c); | ||
if (aAbs <= bAbs && aAbs <= cAbs) { | ||
return a >= 0.0 ? 1.0 : -1.0; | ||
} | ||
else if (bAbs <= aAbs && bAbs <= cAbs) { | ||
return b >= 0.0 ? 1.0 : -1.0; | ||
} | ||
else { | ||
return c >= 0.0 ? 1.0 : -1.0; | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=blend.js.map |
@@ -18,2 +18,3 @@ /** | ||
import 'jasmine'; | ||
import * as colorUtils from '../utils/color_utils'; | ||
import { Cam16 } from './cam16'; | ||
@@ -30,44 +31,44 @@ import { Hct } from './hct'; | ||
const cam = Cam16.fromInt(RED); | ||
expect(cam.hue).toBeCloseTo(27.408, 0.001); | ||
expect(cam.chroma).toBeCloseTo(113.357, 0.001); | ||
expect(cam.j).toBeCloseTo(46.445, 0.001); | ||
expect(cam.m).toBeCloseTo(89.494, 0.001); | ||
expect(cam.s).toBeCloseTo(91.889, 0.001); | ||
expect(cam.q).toBeCloseTo(105.988, 0.001); | ||
expect(cam.hue).toBeCloseTo(27.408, 3); | ||
expect(cam.chroma).toBeCloseTo(113.358, 3); | ||
expect(cam.j).toBeCloseTo(46.445, 3); | ||
expect(cam.m).toBeCloseTo(89.494, 3); | ||
expect(cam.s).toBeCloseTo(91.890, 3); | ||
expect(cam.q).toBeCloseTo(105.989, 3); | ||
}); | ||
it('green', () => { | ||
const cam = Cam16.fromInt(GREEN); | ||
expect(cam.hue).toBeCloseTo(142.139, 0.001); | ||
expect(cam.chroma).toBeCloseTo(108.410, 0.001); | ||
expect(cam.j).toBeCloseTo(79.331, 0.001); | ||
expect(cam.m).toBeCloseTo(85.587, 0.001); | ||
expect(cam.s).toBeCloseTo(78.604, 0.001); | ||
expect(cam.q).toBeCloseTo(138.520, 0.001); | ||
expect(cam.hue).toBeCloseTo(142.140, 3); | ||
expect(cam.chroma).toBeCloseTo(108.410, 3); | ||
expect(cam.j).toBeCloseTo(79.332, 3); | ||
expect(cam.m).toBeCloseTo(85.588, 3); | ||
expect(cam.s).toBeCloseTo(78.605, 3); | ||
expect(cam.q).toBeCloseTo(138.520, 3); | ||
}); | ||
it('blue', () => { | ||
const cam = Cam16.fromInt(BLUE); | ||
expect(cam.hue).toBeCloseTo(282.788, 0.001); | ||
expect(cam.chroma).toBeCloseTo(87.230, 0.001); | ||
expect(cam.j).toBeCloseTo(25.465, 0.001); | ||
expect(cam.m).toBeCloseTo(68.867, 0.001); | ||
expect(cam.s).toBeCloseTo(93.674, 0.001); | ||
expect(cam.q).toBeCloseTo(78.481, 0.001); | ||
expect(cam.hue).toBeCloseTo(282.788, 3); | ||
expect(cam.chroma).toBeCloseTo(87.231, 3); | ||
expect(cam.j).toBeCloseTo(25.466, 3); | ||
expect(cam.m).toBeCloseTo(68.867, 3); | ||
expect(cam.s).toBeCloseTo(93.675, 3); | ||
expect(cam.q).toBeCloseTo(78.481, 3); | ||
}); | ||
it('white', () => { | ||
const cam = Cam16.fromInt(WHITE); | ||
expect(cam.hue).toBeCloseTo(209.492, 0.001); | ||
expect(cam.chroma).toBeCloseTo(2.869, 0.001); | ||
expect(cam.j).toBeCloseTo(100.0, 0.001); | ||
expect(cam.m).toBeCloseTo(2.265, 0.001); | ||
expect(cam.s).toBeCloseTo(12.068, 0.001); | ||
expect(cam.q).toBeCloseTo(155.521, 0.001); | ||
expect(cam.hue).toBeCloseTo(209.492, 3); | ||
expect(cam.chroma).toBeCloseTo(2.869, 3); | ||
expect(cam.j).toBeCloseTo(100.0, 3); | ||
expect(cam.m).toBeCloseTo(2.265, 3); | ||
expect(cam.s).toBeCloseTo(12.068, 3); | ||
expect(cam.q).toBeCloseTo(155.521, 3); | ||
}); | ||
it('black', () => { | ||
const cam = Cam16.fromInt(BLACK); | ||
expect(cam.hue).toBeCloseTo(0.0, 0.001); | ||
expect(cam.chroma).toBeCloseTo(0.0, 0.001); | ||
expect(cam.j).toBeCloseTo(0.0, 0.001); | ||
expect(cam.m).toBeCloseTo(0.0, 0.001); | ||
expect(cam.s).toBeCloseTo(0.0, 0.001); | ||
expect(cam.q).toBeCloseTo(0.0, 0.001); | ||
expect(cam.hue).toBeCloseTo(0.0, 3); | ||
expect(cam.chroma).toBeCloseTo(0.0, 3); | ||
expect(cam.j).toBeCloseTo(0.0, 3); | ||
expect(cam.m).toBeCloseTo(0.0, 3); | ||
expect(cam.s).toBeCloseTo(0.0, 3); | ||
expect(cam.q).toBeCloseTo(0.0, 3); | ||
}); | ||
@@ -107,5 +108,5 @@ }); | ||
const hct = Hct.from(282.788, 87.230, 90.0); | ||
expect(hct.hue).toBeCloseTo(280.729, 2); | ||
expect(hct.chroma).toBeCloseTo(19.247, 2); | ||
expect(hct.tone).toBeCloseTo(89.961, 2); | ||
expect(hct.hue).toBeCloseTo(282.239, 2); | ||
expect(hct.chroma).toBeCloseTo(19.144, 2); | ||
expect(hct.tone).toBeCloseTo(90.035, 2); | ||
}); | ||
@@ -116,16 +117,44 @@ }); | ||
const vc = ViewingConditions.DEFAULT; | ||
expect(vc.n).toBeCloseTo(0.184, 0.001); | ||
expect(vc.aw).toBeCloseTo(29.980, 0.001); | ||
expect(vc.nbb).toBeCloseTo(1.016, 0.001); | ||
expect(vc.ncb).toBeCloseTo(1.016, 0.001); | ||
expect(vc.c).toBeCloseTo(0.69, 0.001); | ||
expect(vc.nc).toBeCloseTo(1.0, 0.001); | ||
expect(vc.rgbD[0]).toBeCloseTo(1.021, 0.001); | ||
expect(vc.rgbD[1]).toBeCloseTo(0.986, 0.001); | ||
expect(vc.rgbD[2]).toBeCloseTo(0.933, 0.001); | ||
expect(vc.fl).toBeCloseTo(0.388, 0.001); | ||
expect(vc.fLRoot).toBeCloseTo(0.789, 0.001); | ||
expect(vc.z).toBeCloseTo(1.909, 0.001); | ||
expect(vc.n).toBeCloseTo(0.184, 3); | ||
expect(vc.aw).toBeCloseTo(29.981, 3); | ||
expect(vc.nbb).toBeCloseTo(1.017, 3); | ||
expect(vc.ncb).toBeCloseTo(1.017, 3); | ||
expect(vc.c).toBeCloseTo(0.69, 3); | ||
expect(vc.nc).toBeCloseTo(1.0, 3); | ||
expect(vc.rgbD[0]).toBeCloseTo(1.021, 3); | ||
expect(vc.rgbD[1]).toBeCloseTo(0.986, 3); | ||
expect(vc.rgbD[2]).toBeCloseTo(0.934, 3); | ||
expect(vc.fl).toBeCloseTo(0.388, 3); | ||
expect(vc.fLRoot).toBeCloseTo(0.789, 3); | ||
expect(vc.z).toBeCloseTo(1.909, 3); | ||
}); | ||
}); | ||
function colorIsOnBoundary(argb) { | ||
return colorUtils.redFromArgb(argb) === 0 || | ||
colorUtils.redFromArgb(argb) === 255 || | ||
colorUtils.greenFromArgb(argb) === 0 || | ||
colorUtils.greenFromArgb(argb) === 255 || | ||
colorUtils.blueFromArgb(argb) === 0 || | ||
colorUtils.blueFromArgb(argb) === 255; | ||
} | ||
describe('CamSolver', () => { | ||
it('returns a sufficiently close color', () => { | ||
for (let hue = 15; hue < 360; hue += 30) { | ||
for (let chroma = 0; chroma <= 100; chroma += 10) { | ||
for (let tone = 20; tone <= 80; tone += 10) { | ||
const hctColor = Hct.from(hue, chroma, tone); | ||
if (chroma > 0) { | ||
expect(Math.abs(hctColor.hue - hue)).toBeLessThanOrEqual(4.0); | ||
} | ||
expect(hctColor.chroma).toBeGreaterThanOrEqual(0); | ||
expect(hctColor.chroma).toBeLessThanOrEqual(chroma + 2.5); | ||
if (hctColor.chroma < chroma - 2.5) { | ||
expect(colorIsOnBoundary(hctColor.toInt())).toBe(true); | ||
} | ||
expect(Math.abs(hctColor.tone - tone)).toBeLessThanOrEqual(0.5); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
//# sourceMappingURL=hct_test.js.map |
@@ -23,5 +23,3 @@ /** | ||
export declare class Hct { | ||
private internalHue; | ||
private internalChroma; | ||
private internalTone; | ||
private argb; | ||
/** | ||
@@ -35,2 +33,5 @@ * @param hue 0 <= hue < 360; invalid values are corrected. | ||
*/ | ||
internalHue: number; | ||
internalChroma: number; | ||
internalTone: number; | ||
static from(hue: number, chroma: number, tone: number): Hct; | ||
@@ -37,0 +38,0 @@ /** |
@@ -33,5 +33,4 @@ /** | ||
import * as utils from '../utils/color_utils'; | ||
import * as math from '../utils/math_utils'; | ||
import { Cam16 } from './cam16'; | ||
import { ViewingConditions } from './viewing_conditions'; | ||
import { HctSolver } from './hct_solver'; | ||
/** | ||
@@ -43,18 +42,12 @@ * HCT, hue, chroma, and tone. A color system that provides a perceptually | ||
export class Hct { | ||
constructor(internalHue, internalChroma, internalTone) { | ||
this.internalHue = internalHue; | ||
this.internalChroma = internalChroma; | ||
this.internalTone = internalTone; | ||
this.setInternalState(this.toInt()); | ||
constructor(argb) { | ||
this.argb = argb; | ||
const cam = Cam16.fromInt(argb); | ||
this.internalHue = cam.hue; | ||
this.internalChroma = cam.chroma; | ||
this.internalTone = utils.lstarFromArgb(argb); | ||
this.argb = argb; | ||
} | ||
/** | ||
* @param hue 0 <= hue < 360; invalid values are corrected. | ||
* @param chroma 0 <= chroma < ?; Informally, colorfulness. The color | ||
* returned may be lower than the requested chroma. Chroma has a different | ||
* maximum for any given hue and tone. | ||
* @param tone 0 <= tone <= 100; invalid values are corrected. | ||
* @return HCT representation of a color in default viewing conditions. | ||
*/ | ||
static from(hue, chroma, tone) { | ||
return new Hct(hue, chroma, tone); | ||
return new Hct(HctSolver.solveToInt(hue, chroma, tone)); | ||
} | ||
@@ -66,8 +59,6 @@ /** | ||
static fromInt(argb) { | ||
const cam = Cam16.fromInt(argb); | ||
const tone = utils.lstarFromArgb(argb); | ||
return new Hct(cam.hue, cam.chroma, tone); | ||
return new Hct(argb); | ||
} | ||
toInt() { | ||
return getInt(this.internalHue, this.internalChroma, this.internalTone); | ||
return this.argb; | ||
} | ||
@@ -87,3 +78,3 @@ /** | ||
set hue(newHue) { | ||
this.setInternalState(getInt(math.sanitizeDegreesDouble(newHue), this.internalChroma, this.internalTone)); | ||
this.setInternalState(HctSolver.solveToInt(newHue, this.internalChroma, this.internalTone)); | ||
} | ||
@@ -99,3 +90,3 @@ get chroma() { | ||
set chroma(newChroma) { | ||
this.setInternalState(getInt(this.internalHue, newChroma, this.internalTone)); | ||
this.setInternalState(HctSolver.solveToInt(this.internalHue, newChroma, this.internalTone)); | ||
} | ||
@@ -112,126 +103,12 @@ /** Lightness. Ranges from 0 to 100. */ | ||
set tone(newTone) { | ||
this.setInternalState(getInt(this.internalHue, this.internalChroma, newTone)); | ||
this.setInternalState(HctSolver.solveToInt(this.internalHue, this.internalChroma, newTone)); | ||
} | ||
setInternalState(argb) { | ||
const cam = Cam16.fromInt(argb); | ||
const tone = utils.lstarFromArgb(argb); | ||
this.internalHue = cam.hue; | ||
this.internalChroma = cam.chroma; | ||
this.internalTone = tone; | ||
this.internalTone = utils.lstarFromArgb(argb); | ||
this.argb = argb; | ||
} | ||
} | ||
/** | ||
* When the delta between the floor & ceiling of a binary search for maximum | ||
* chroma at a hue and tone is less than this, the binary search terminates. | ||
*/ | ||
const CHROMA_SEARCH_ENDPOINT = 0.4; | ||
/** | ||
* The maximum color distance, in CAM16-UCS, between a requested color and the | ||
* color returned. | ||
*/ | ||
const DE_MAX = 1.0; | ||
/** The maximum difference between the requested L* and the L* returned. */ | ||
const DL_MAX = 0.2; | ||
/** | ||
* When the delta between the floor & ceiling of a binary search for J, | ||
* lightness in CAM16, is less than this, the binary search terminates. | ||
*/ | ||
const LIGHTNESS_SEARCH_ENDPOINT = 0.01; | ||
/** | ||
* @param hue a number, in degrees, representing ex. red, orange, yellow, etc. | ||
* Ranges from 0 <= hue < 360. | ||
* @param chroma Informally, colorfulness. Ranges from 0 to roughly 150. | ||
* Like all perceptually accurate color systems, chroma has a different | ||
* maximum for any given hue and tone, so the color returned may be lower | ||
* than the requested chroma. | ||
* @param tone Lightness. Ranges from 0 to 100. | ||
* @return ARGB representation of a color in default viewing conditions | ||
*/ | ||
function getInt(hue, chroma, tone) { | ||
return getIntInViewingConditions(math.sanitizeDegreesDouble(hue), chroma, math.clampDouble(0.0, 100.0, tone), ViewingConditions.DEFAULT); | ||
} | ||
/** | ||
* @param hue CAM16 hue. | ||
* @param chroma CAM16 chroma. | ||
* @param tone L*a*b* lightness. | ||
* @param viewingConditions Information about the environment where the color | ||
* was observed. | ||
*/ | ||
function getIntInViewingConditions(hue, chroma, tone, viewingConditions) { | ||
if (chroma < 1.0 || Math.round(tone) <= 0.0 || Math.round(tone) >= 100.0) { | ||
return utils.argbFromLstar(tone); | ||
} | ||
hue = math.sanitizeDegreesDouble(hue); | ||
let high = chroma; | ||
let mid = chroma; | ||
let low = 0.0; | ||
let isFirstLoop = true; | ||
let answer = null; | ||
while (Math.abs(low - high) >= CHROMA_SEARCH_ENDPOINT) { | ||
const possibleAnswer = findCamByJ(hue, mid, tone); | ||
if (isFirstLoop) { | ||
if (possibleAnswer != null) { | ||
return possibleAnswer.viewed(viewingConditions); | ||
} | ||
else { | ||
isFirstLoop = false; | ||
mid = low + (high - low) / 2.0; | ||
continue; | ||
} | ||
} | ||
if (possibleAnswer === null) { | ||
high = mid; | ||
} | ||
else { | ||
answer = possibleAnswer; | ||
low = mid; | ||
} | ||
mid = low + (high - low) / 2.0; | ||
} | ||
if (answer === null) { | ||
return utils.argbFromLstar(tone); | ||
} | ||
return answer.viewed(viewingConditions); | ||
} | ||
/** | ||
* @param hue CAM16 hue | ||
* @param chroma CAM16 chroma | ||
* @param tone L*a*b* lightness | ||
* @return CAM16 instance within error tolerance of the provided dimensions, | ||
* or null. | ||
*/ | ||
function findCamByJ(hue, chroma, tone) { | ||
let low = 0.0; | ||
let high = 100.0; | ||
let mid = 0.0; | ||
let bestdL = 1000.0; | ||
let bestdE = 1000.0; | ||
let bestCam = null; | ||
while (Math.abs(low - high) > LIGHTNESS_SEARCH_ENDPOINT) { | ||
mid = low + (high - low) / 2; | ||
const camBeforeClip = Cam16.fromJch(mid, chroma, hue); | ||
const clipped = camBeforeClip.toInt(); | ||
const clippedLstar = utils.lstarFromArgb(clipped); | ||
const dL = Math.abs(tone - clippedLstar); | ||
if (dL < DL_MAX) { | ||
const camClipped = Cam16.fromInt(clipped); | ||
const dE = camClipped.distance(Cam16.fromJch(camClipped.j, camClipped.chroma, hue)); | ||
if (dE <= DE_MAX && dE <= bestdE) { | ||
bestdL = dL; | ||
bestdE = dE; | ||
bestCam = camClipped; | ||
} | ||
} | ||
if (bestdL === 0 && bestdE === 0) { | ||
break; | ||
} | ||
if (clippedLstar < tone) { | ||
low = mid; | ||
} | ||
else { | ||
high = mid; | ||
} | ||
} | ||
return bestCam; | ||
} | ||
//# sourceMappingURL=hct.js.map |
@@ -34,3 +34,7 @@ /** | ||
static of(argb: number): CorePalette; | ||
/** | ||
* @param argb ARGB representation of a color | ||
*/ | ||
static contentOf(argb: number): CorePalette; | ||
private constructor(); | ||
} |
@@ -25,10 +25,20 @@ /** | ||
export class CorePalette { | ||
constructor(argb) { | ||
constructor(argb, isContent) { | ||
const hct = Hct.fromInt(argb); | ||
const hue = hct.hue; | ||
this.a1 = TonalPalette.fromHueAndChroma(hue, Math.max(48, hct.chroma)); | ||
this.a2 = TonalPalette.fromHueAndChroma(hue, 16); | ||
this.a3 = TonalPalette.fromHueAndChroma(hue + 60, 24); | ||
this.n1 = TonalPalette.fromHueAndChroma(hue, 4); | ||
this.n2 = TonalPalette.fromHueAndChroma(hue, 8); | ||
const chroma = hct.chroma; | ||
if (isContent) { | ||
this.a1 = TonalPalette.fromHueAndChroma(hue, chroma); | ||
this.a2 = TonalPalette.fromHueAndChroma(hue, chroma / 3); | ||
this.a3 = TonalPalette.fromHueAndChroma(hue + 60, chroma / 2); | ||
this.n1 = TonalPalette.fromHueAndChroma(hue, Math.min(chroma / 12, 4)); | ||
this.n2 = TonalPalette.fromHueAndChroma(hue, Math.min(chroma / 6, 8)); | ||
} | ||
else { | ||
this.a1 = TonalPalette.fromHueAndChroma(hue, Math.max(48, chroma)); | ||
this.a2 = TonalPalette.fromHueAndChroma(hue, 16); | ||
this.a3 = TonalPalette.fromHueAndChroma(hue + 60, 24); | ||
this.n1 = TonalPalette.fromHueAndChroma(hue, 4); | ||
this.n2 = TonalPalette.fromHueAndChroma(hue, 8); | ||
} | ||
this.error = TonalPalette.fromHueAndChroma(25, 84); | ||
@@ -40,5 +50,11 @@ } | ||
static of(argb) { | ||
return new CorePalette(argb); | ||
return new CorePalette(argb, false); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color | ||
*/ | ||
static contentOf(argb) { | ||
return new CorePalette(argb, true); | ||
} | ||
} | ||
//# sourceMappingURL=core_palette.js.map |
@@ -24,12 +24,12 @@ /** | ||
expect(blue.tone(100)).toBe(0xffffffff); | ||
expect(blue.tone(95)).toBe(0xfff0efff); | ||
expect(blue.tone(90)).toBe(0xffdfe0ff); | ||
expect(blue.tone(80)).toBe(0xffbdc2ff); | ||
expect(blue.tone(70)).toBe(0xff9ca4ff); | ||
expect(blue.tone(60)).toBe(0xff7a85ff); | ||
expect(blue.tone(50)).toBe(0xff5964ff); | ||
expect(blue.tone(40)).toBe(0xff333cff); | ||
expect(blue.tone(30)).toBe(0xff0000f0); | ||
expect(blue.tone(20)).toBe(0xff0000ad); | ||
expect(blue.tone(10)).toBe(0xff00006f); | ||
expect(blue.tone(95)).toBe(0xfff1efff); | ||
expect(blue.tone(90)).toBe(0xffe0e0ff); | ||
expect(blue.tone(80)).toBe(0xffbec2ff); | ||
expect(blue.tone(70)).toBe(0xff9da3ff); | ||
expect(blue.tone(60)).toBe(0xff7c84ff); | ||
expect(blue.tone(50)).toBe(0xff5a64ff); | ||
expect(blue.tone(40)).toBe(0xff343dff); | ||
expect(blue.tone(30)).toBe(0xff0000ef); | ||
expect(blue.tone(20)).toBe(0xff0001ac); | ||
expect(blue.tone(10)).toBe(0xff00006e); | ||
expect(blue.tone(0)).toBe(0xff000000); | ||
@@ -42,15 +42,54 @@ }); | ||
expect(core.a1.tone(100)).toBe(0xffffffff); | ||
expect(core.a1.tone(95)).toBe(0xfff0efff); | ||
expect(core.a1.tone(90)).toBe(0xffdfe0ff); | ||
expect(core.a1.tone(80)).toBe(0xffbdc2ff); | ||
expect(core.a1.tone(70)).toBe(0xff9ca4ff); | ||
expect(core.a1.tone(60)).toBe(0xff7a85ff); | ||
expect(core.a1.tone(50)).toBe(0xff5964ff); | ||
expect(core.a1.tone(40)).toBe(0xff333cff); | ||
expect(core.a1.tone(30)).toBe(0xff0000f0); | ||
expect(core.a1.tone(20)).toBe(0xff0000ad); | ||
expect(core.a1.tone(10)).toBe(0xff00006f); | ||
expect(core.a1.tone(95)).toBe(0xfff1efff); | ||
expect(core.a1.tone(90)).toBe(0xffe0e0ff); | ||
expect(core.a1.tone(80)).toBe(0xffbec2ff); | ||
expect(core.a1.tone(70)).toBe(0xff9da3ff); | ||
expect(core.a1.tone(60)).toBe(0xff7c84ff); | ||
expect(core.a1.tone(50)).toBe(0xff5a64ff); | ||
expect(core.a1.tone(40)).toBe(0xff343dff); | ||
expect(core.a1.tone(30)).toBe(0xff0000ef); | ||
expect(core.a1.tone(20)).toBe(0xff0001ac); | ||
expect(core.a1.tone(10)).toBe(0xff00006e); | ||
expect(core.a1.tone(0)).toBe(0xff000000); | ||
expect(core.a2.tone(100)).toBe(0xffffffff); | ||
expect(core.a2.tone(95)).toBe(0xfff1efff); | ||
expect(core.a2.tone(90)).toBe(0xffe1e0f9); | ||
expect(core.a2.tone(80)).toBe(0xffc5c4dd); | ||
expect(core.a2.tone(70)).toBe(0xffa9a9c1); | ||
expect(core.a2.tone(60)).toBe(0xff8f8fa6); | ||
expect(core.a2.tone(50)).toBe(0xff75758b); | ||
expect(core.a2.tone(40)).toBe(0xff5c5d72); | ||
expect(core.a2.tone(30)).toBe(0xff444559); | ||
expect(core.a2.tone(20)).toBe(0xff2e2f42); | ||
expect(core.a2.tone(10)).toBe(0xff191a2c); | ||
expect(core.a2.tone(0)).toBe(0xff000000); | ||
}); | ||
it('contentOfBlue', () => { | ||
const core = CorePalette.contentOf(0xff0000ff); | ||
expect(core.a1.tone(100)).toBe(0xffffffff); | ||
expect(core.a1.tone(95)).toBe(0xfff1efff); | ||
expect(core.a1.tone(90)).toBe(0xffe0e0ff); | ||
expect(core.a1.tone(80)).toBe(0xffbec2ff); | ||
expect(core.a1.tone(70)).toBe(0xff9da3ff); | ||
expect(core.a1.tone(60)).toBe(0xff7c84ff); | ||
expect(core.a1.tone(50)).toBe(0xff5a64ff); | ||
expect(core.a1.tone(40)).toBe(0xff343dff); | ||
expect(core.a1.tone(30)).toBe(0xff0000ef); | ||
expect(core.a1.tone(20)).toBe(0xff0001ac); | ||
expect(core.a1.tone(10)).toBe(0xff00006e); | ||
expect(core.a1.tone(0)).toBe(0xff000000); | ||
expect(core.a2.tone(100)).toBe(0xffffffff); | ||
expect(core.a2.tone(95)).toBe(0xfff1efff); | ||
expect(core.a2.tone(90)).toBe(0xffe0e0ff); | ||
expect(core.a2.tone(80)).toBe(0xffc1c3f4); | ||
expect(core.a2.tone(70)).toBe(0xffa5a7d7); | ||
expect(core.a2.tone(60)).toBe(0xff8b8dbb); | ||
expect(core.a2.tone(50)).toBe(0xff7173a0); | ||
expect(core.a2.tone(40)).toBe(0xff585b86); | ||
expect(core.a2.tone(30)).toBe(0xff40436d); | ||
expect(core.a2.tone(20)).toBe(0xff2a2d55); | ||
expect(core.a2.tone(10)).toBe(0xff14173f); | ||
expect(core.a2.tone(0)).toBe(0xff000000); | ||
}); | ||
}); | ||
//# sourceMappingURL=palettes_test.js.map |
@@ -17,2 +17,3 @@ /** | ||
*/ | ||
import { CorePalette } from '../palettes/core_palette'; | ||
/** | ||
@@ -58,3 +59,48 @@ * Represents an Android 12 color scheme, a mapping of color roles to colors. | ||
static dark(argb: number): SchemeAndroid; | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Light Android color scheme, based on the color's hue. | ||
*/ | ||
static lightContent(argb: number): SchemeAndroid; | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Android color scheme, based on the color's hue. | ||
*/ | ||
static darkContent(argb: number): SchemeAndroid; | ||
/** | ||
* Light scheme from core palette | ||
*/ | ||
static lightFromCorePalette(core: CorePalette): SchemeAndroid; | ||
/** | ||
* Dark scheme from core palette | ||
*/ | ||
static darkFromCorePalette(core: CorePalette): SchemeAndroid; | ||
private constructor(); | ||
toJSON(): { | ||
colorAccentPrimary: number; | ||
colorAccentPrimaryVariant: number; | ||
colorAccentSecondary: number; | ||
colorAccentSecondaryVariant: number; | ||
colorAccentTertiary: number; | ||
colorAccentTertiaryVariant: number; | ||
textColorPrimary: number; | ||
textColorSecondary: number; | ||
textColorTertiary: number; | ||
textColorPrimaryInverse: number; | ||
textColorSecondaryInverse: number; | ||
textColorTertiaryInverse: number; | ||
colorBackground: number; | ||
colorBackgroundFloating: number; | ||
colorSurface: number; | ||
colorSurfaceVariant: number; | ||
colorSurfaceHighlight: number; | ||
surfaceHeader: number; | ||
underSurface: number; | ||
offState: number; | ||
accentSurface: number; | ||
textPrimaryOnAccent: number; | ||
textSecondaryOnAccent: number; | ||
volumeBackground: number; | ||
scrim: number; | ||
}; | ||
} |
@@ -106,2 +106,32 @@ /** | ||
const core = CorePalette.of(argb); | ||
return SchemeAndroid.lightFromCorePalette(core); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material color scheme, based on the color's hue. | ||
*/ | ||
static dark(argb) { | ||
const core = CorePalette.of(argb); | ||
return SchemeAndroid.darkFromCorePalette(core); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Light Android color scheme, based on the color's hue. | ||
*/ | ||
static lightContent(argb) { | ||
const core = CorePalette.contentOf(argb); | ||
return SchemeAndroid.lightFromCorePalette(core); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Android color scheme, based on the color's hue. | ||
*/ | ||
static darkContent(argb) { | ||
const core = CorePalette.contentOf(argb); | ||
return SchemeAndroid.darkFromCorePalette(core); | ||
} | ||
/** | ||
* Light scheme from core palette | ||
*/ | ||
static lightFromCorePalette(core) { | ||
return new SchemeAndroid({ | ||
@@ -136,7 +166,5 @@ colorAccentPrimary: core.a1.tone(90), | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material color scheme, based on the color's hue. | ||
* Dark scheme from core palette | ||
*/ | ||
static dark(argb) { | ||
const core = CorePalette.of(argb); | ||
static darkFromCorePalette(core) { | ||
return new SchemeAndroid({ | ||
@@ -170,3 +198,6 @@ colorAccentPrimary: core.a1.tone(90), | ||
} | ||
toJSON() { | ||
return Object.assign({}, this.props); | ||
} | ||
} | ||
//# sourceMappingURL=scheme_android.js.map |
@@ -27,7 +27,7 @@ /** | ||
const scheme = Scheme.light(0xff0000ff); | ||
expect(scheme.primary).matchesColor(0xff333CFF); | ||
expect(scheme.primary).matchesColor(0xff343DFF); | ||
}); | ||
it('blue dark scheme', () => { | ||
const scheme = Scheme.dark(0xff0000ff); | ||
expect(scheme.primary).matchesColor(0xffBDC2FF); | ||
expect(scheme.primary).matchesColor(0xffBEC2FF); | ||
}); | ||
@@ -38,4 +38,4 @@ it('3rd party light scheme', () => { | ||
expect(scheme.secondary).matchesColor(0xff625B71); | ||
expect(scheme.tertiary).matchesColor(0xff7D5260); | ||
expect(scheme.surface).matchesColor(0xfffffbfe); | ||
expect(scheme.tertiary).matchesColor(0xff7E5260); | ||
expect(scheme.surface).matchesColor(0xfffffbff); | ||
expect(scheme.onSurface).matchesColor(0xff1c1b1e); | ||
@@ -45,8 +45,136 @@ }); | ||
const scheme = Scheme.dark(0xff6750A4); | ||
expect(scheme.primary).matchesColor(0xffd0bcff); | ||
expect(scheme.primary).matchesColor(0xffcfbcff); | ||
expect(scheme.secondary).matchesColor(0xffcbc2db); | ||
expect(scheme.tertiary).matchesColor(0xffefb8c8); | ||
expect(scheme.surface).matchesColor(0xff1c1b1e); | ||
expect(scheme.onSurface).matchesColor(0xffe6e1e5); | ||
expect(scheme.onSurface).matchesColor(0xffe6e1e6); | ||
}); | ||
it('light scheme from high chroma color', () => { | ||
const scheme = Scheme.light(0xfffa2bec); | ||
expect(scheme.primary).matchesColor(0xffab00a2); | ||
expect(scheme.onPrimary).matchesColor(0xffffffff); | ||
expect(scheme.primaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.onPrimaryContainer).matchesColor(0xff390035); | ||
expect(scheme.secondary).matchesColor(0xff6e5868); | ||
expect(scheme.onSecondary).matchesColor(0xffffffff); | ||
expect(scheme.secondaryContainer).matchesColor(0xfff8daee); | ||
expect(scheme.onSecondaryContainer).matchesColor(0xff271624); | ||
expect(scheme.tertiary).matchesColor(0xff815343); | ||
expect(scheme.onTertiary).matchesColor(0xffffffff); | ||
expect(scheme.tertiaryContainer).matchesColor(0xffffdbd0); | ||
expect(scheme.onTertiaryContainer).matchesColor(0xff321207); | ||
expect(scheme.error).matchesColor(0xffba1a1a); | ||
expect(scheme.onError).matchesColor(0xffffffff); | ||
expect(scheme.errorContainer).matchesColor(0xffffdad6); | ||
expect(scheme.onErrorContainer).matchesColor(0xff410002); | ||
expect(scheme.background).matchesColor(0xfffffbff); | ||
expect(scheme.onBackground).matchesColor(0xff1f1a1d); | ||
expect(scheme.surface).matchesColor(0xfffffbff); | ||
expect(scheme.onSurface).matchesColor(0xff1f1a1d); | ||
expect(scheme.surfaceVariant).matchesColor(0xffeedee7); | ||
expect(scheme.onSurfaceVariant).matchesColor(0xff4e444b); | ||
expect(scheme.outline).matchesColor(0xff80747b); | ||
expect(scheme.outlineVariant).matchesColor(0xffd2c2cb); | ||
expect(scheme.shadow).matchesColor(0xff000000); | ||
expect(scheme.scrim).matchesColor(0xff000000); | ||
expect(scheme.inverseSurface).matchesColor(0xff342f32); | ||
expect(scheme.inverseOnSurface).matchesColor(0xfff8eef2); | ||
expect(scheme.inversePrimary).matchesColor(0xffffabee); | ||
}); | ||
it('dark scheme from high chroma color', () => { | ||
const scheme = Scheme.dark(0xfffa2bec); | ||
expect(scheme.primary).matchesColor(0xffffabee); | ||
expect(scheme.onPrimary).matchesColor(0xff5c0057); | ||
expect(scheme.primaryContainer).matchesColor(0xff83007b); | ||
expect(scheme.onPrimaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.secondary).matchesColor(0xffdbbed1); | ||
expect(scheme.onSecondary).matchesColor(0xff3e2a39); | ||
expect(scheme.secondaryContainer).matchesColor(0xff554050); | ||
expect(scheme.onSecondaryContainer).matchesColor(0xfff8daee); | ||
expect(scheme.tertiary).matchesColor(0xfff5b9a5); | ||
expect(scheme.onTertiary).matchesColor(0xff4c2619); | ||
expect(scheme.tertiaryContainer).matchesColor(0xff663c2d); | ||
expect(scheme.onTertiaryContainer).matchesColor(0xffffdbd0); | ||
expect(scheme.error).matchesColor(0xffffb4ab); | ||
expect(scheme.onError).matchesColor(0xff690005); | ||
expect(scheme.errorContainer).matchesColor(0xff93000a); | ||
expect(scheme.onErrorContainer).matchesColor(0xffffb4ab); | ||
expect(scheme.background).matchesColor(0xff1f1a1d); | ||
expect(scheme.onBackground).matchesColor(0xffeae0e4); | ||
expect(scheme.surface).matchesColor(0xff1f1a1d); | ||
expect(scheme.onSurface).matchesColor(0xffeae0e4); | ||
expect(scheme.surfaceVariant).matchesColor(0xff4e444b); | ||
expect(scheme.onSurfaceVariant).matchesColor(0xffd2c2cb); | ||
expect(scheme.outline).matchesColor(0xff9a8d95); | ||
expect(scheme.outlineVariant).matchesColor(0xff4e444b); | ||
expect(scheme.shadow).matchesColor(0xff000000); | ||
expect(scheme.scrim).matchesColor(0xff000000); | ||
expect(scheme.inverseSurface).matchesColor(0xffeae0e4); | ||
expect(scheme.inverseOnSurface).matchesColor(0xff342f32); | ||
expect(scheme.inversePrimary).matchesColor(0xffab00a2); | ||
}); | ||
it('light content scheme from high chroma color', () => { | ||
const scheme = Scheme.lightContent(0xfffa2bec); | ||
expect(scheme.primary).matchesColor(0xffab00a2); | ||
expect(scheme.onPrimary).matchesColor(0xffffffff); | ||
expect(scheme.primaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.onPrimaryContainer).matchesColor(0xff390035); | ||
expect(scheme.secondary).matchesColor(0xff7f4e75); | ||
expect(scheme.onSecondary).matchesColor(0xffffffff); | ||
expect(scheme.secondaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.onSecondaryContainer).matchesColor(0xff330b2f); | ||
expect(scheme.tertiary).matchesColor(0xff9c4323); | ||
expect(scheme.onTertiary).matchesColor(0xffffffff); | ||
expect(scheme.tertiaryContainer).matchesColor(0xffffdbd0); | ||
expect(scheme.onTertiaryContainer).matchesColor(0xff390c00); | ||
expect(scheme.error).matchesColor(0xffba1a1a); | ||
expect(scheme.onError).matchesColor(0xffffffff); | ||
expect(scheme.errorContainer).matchesColor(0xffffdad6); | ||
expect(scheme.onErrorContainer).matchesColor(0xff410002); | ||
expect(scheme.background).matchesColor(0xfffffbff); | ||
expect(scheme.onBackground).matchesColor(0xff1f1a1d); | ||
expect(scheme.surface).matchesColor(0xfffffbff); | ||
expect(scheme.onSurface).matchesColor(0xff1f1a1d); | ||
expect(scheme.surfaceVariant).matchesColor(0xffeedee7); | ||
expect(scheme.onSurfaceVariant).matchesColor(0xff4e444b); | ||
expect(scheme.outline).matchesColor(0xff80747b); | ||
expect(scheme.outlineVariant).matchesColor(0xffd2c2cb); | ||
expect(scheme.shadow).matchesColor(0xff000000); | ||
expect(scheme.scrim).matchesColor(0xff000000); | ||
expect(scheme.inverseSurface).matchesColor(0xff342f32); | ||
expect(scheme.inverseOnSurface).matchesColor(0xfff8eef2); | ||
expect(scheme.inversePrimary).matchesColor(0xffffabee); | ||
}); | ||
it('dark content scheme from high chroma color', () => { | ||
const scheme = Scheme.darkContent(0xfffa2bec); | ||
expect(scheme.primary).matchesColor(0xffffabee); | ||
expect(scheme.onPrimary).matchesColor(0xff5c0057); | ||
expect(scheme.primaryContainer).matchesColor(0xff83007b); | ||
expect(scheme.onPrimaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.secondary).matchesColor(0xfff0b4e1); | ||
expect(scheme.onSecondary).matchesColor(0xff4b2145); | ||
expect(scheme.secondaryContainer).matchesColor(0xff64375c); | ||
expect(scheme.onSecondaryContainer).matchesColor(0xffffd7f3); | ||
expect(scheme.tertiary).matchesColor(0xffffb59c); | ||
expect(scheme.onTertiary).matchesColor(0xff5c1900); | ||
expect(scheme.tertiaryContainer).matchesColor(0xff7d2c0d); | ||
expect(scheme.onTertiaryContainer).matchesColor(0xffffdbd0); | ||
expect(scheme.error).matchesColor(0xffffb4ab); | ||
expect(scheme.onError).matchesColor(0xff690005); | ||
expect(scheme.errorContainer).matchesColor(0xff93000a); | ||
expect(scheme.onErrorContainer).matchesColor(0xffffb4ab); | ||
expect(scheme.background).matchesColor(0xff1f1a1d); | ||
expect(scheme.onBackground).matchesColor(0xffeae0e4); | ||
expect(scheme.surface).matchesColor(0xff1f1a1d); | ||
expect(scheme.onSurface).matchesColor(0xffeae0e4); | ||
expect(scheme.surfaceVariant).matchesColor(0xff4e444b); | ||
expect(scheme.onSurfaceVariant).matchesColor(0xffd2c2cb); | ||
expect(scheme.outline).matchesColor(0xff9a8d95); | ||
expect(scheme.outlineVariant).matchesColor(0xff4e444b); | ||
expect(scheme.shadow).matchesColor(0xff000000); | ||
expect(scheme.scrim).matchesColor(0xff000000); | ||
expect(scheme.inverseSurface).matchesColor(0xffeae0e4); | ||
expect(scheme.inverseOnSurface).matchesColor(0xff342f32); | ||
expect(scheme.inversePrimary).matchesColor(0xffab00a2); | ||
}); | ||
}); | ||
@@ -56,14 +184,14 @@ describe('android scheme', () => { | ||
const scheme = SchemeAndroid.light(0xff0000ff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffdfe0ff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffe0e0ff); | ||
}); | ||
it('blue dark scheme', () => { | ||
const scheme = SchemeAndroid.dark(0xff0000ff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffdfe0ff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffe0e0ff); | ||
}); | ||
it('3rd party light scheme', () => { | ||
const scheme = SchemeAndroid.light(0xff6750A4); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffeaddff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffe9ddff); | ||
expect(scheme.colorAccentSecondary).matchesColor(0xffe8def8); | ||
expect(scheme.colorAccentTertiary).matchesColor(0xffffd8e4); | ||
expect(scheme.colorSurface).matchesColor(0xfffdf8fc); | ||
expect(scheme.colorAccentTertiary).matchesColor(0xffffd9e3); | ||
expect(scheme.colorSurface).matchesColor(0xfffdf8fd); | ||
expect(scheme.textColorPrimary).matchesColor(0xff1c1b1e); | ||
@@ -73,5 +201,5 @@ }); | ||
const scheme = SchemeAndroid.dark(0xff6750A4); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffeaddff); | ||
expect(scheme.colorAccentPrimary).matchesColor(0xffe9ddff); | ||
expect(scheme.colorAccentSecondary).matchesColor(0xffe8def8); | ||
expect(scheme.colorAccentTertiary).matchesColor(0xffffd8e4); | ||
expect(scheme.colorAccentTertiary).matchesColor(0xffffd9e3); | ||
expect(scheme.colorSurface).matchesColor(0xff313033); | ||
@@ -78,0 +206,0 @@ expect(scheme.textColorPrimary).matchesColor(0xfff4eff4); |
@@ -17,2 +17,3 @@ /** | ||
*/ | ||
import { CorePalette } from '../palettes/core_palette'; | ||
/** | ||
@@ -24,8 +25,8 @@ * Represents a Material color scheme, a mapping of color roles to colors. | ||
get primary(): number; | ||
get onPrimary(): number; | ||
get primaryContainer(): number; | ||
get onPrimary(): number; | ||
get onPrimaryContainer(): number; | ||
get secondary(): number; | ||
get onSecondary(): number; | ||
get secondaryContainer(): number; | ||
get onSecondary(): number; | ||
get onSecondaryContainer(): number; | ||
@@ -47,3 +48,5 @@ get tertiary(): number; | ||
get outline(): number; | ||
get outlineVariant(): number; | ||
get shadow(): number; | ||
get scrim(): number; | ||
get inverseSurface(): number; | ||
@@ -62,19 +65,37 @@ get inverseOnSurface(): number; | ||
static dark(argb: number): Scheme; | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Light Material content color scheme, based on the color's hue. | ||
*/ | ||
static lightContent(argb: number): Scheme; | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material content color scheme, based on the color's hue. | ||
*/ | ||
static darkContent(argb: number): Scheme; | ||
/** | ||
* Light scheme from core palette | ||
*/ | ||
static lightFromCorePalette(core: CorePalette): Scheme; | ||
/** | ||
* Dark scheme from core palette | ||
*/ | ||
static darkFromCorePalette(core: CorePalette): Scheme; | ||
private constructor(); | ||
toJSON(): { | ||
primary: number; | ||
onPrimary: number; | ||
primaryContainer: number; | ||
onPrimary: number; | ||
onPrimaryContainer: number; | ||
secondary: number; | ||
onSecondary: number; | ||
secondaryContainer: number; | ||
onSecondary: number; | ||
onSecondaryContainer: number; | ||
tertiary: number; | ||
onTertiary: number; | ||
tertiaryContainer: number; | ||
onTertiary: number; | ||
onTertiaryContainer: number; | ||
error: number; | ||
onError: number; | ||
errorContainer: number; | ||
onError: number; | ||
onErrorContainer: number; | ||
@@ -88,3 +109,5 @@ background: number; | ||
outline: number; | ||
outlineVariant: number; | ||
shadow: number; | ||
scrim: number; | ||
inverseSurface: number; | ||
@@ -91,0 +114,0 @@ inverseOnSurface: number; |
@@ -17,2 +17,3 @@ /** | ||
*/ | ||
// This file is automatically generated. Do not modify it. | ||
import { CorePalette } from '../palettes/core_palette'; | ||
@@ -29,8 +30,8 @@ /** | ||
} | ||
get onPrimary() { | ||
return this.props.onPrimary; | ||
} | ||
get primaryContainer() { | ||
return this.props.primaryContainer; | ||
} | ||
get onPrimary() { | ||
return this.props.onPrimary; | ||
} | ||
get onPrimaryContainer() { | ||
@@ -42,8 +43,8 @@ return this.props.onPrimaryContainer; | ||
} | ||
get onSecondary() { | ||
return this.props.onSecondary; | ||
} | ||
get secondaryContainer() { | ||
return this.props.secondaryContainer; | ||
} | ||
get onSecondary() { | ||
return this.props.onSecondary; | ||
} | ||
get onSecondaryContainer() { | ||
@@ -97,5 +98,11 @@ return this.props.onSecondaryContainer; | ||
} | ||
get outlineVariant() { | ||
return this.props.outlineVariant; | ||
} | ||
get shadow() { | ||
return this.props.shadow; | ||
} | ||
get scrim() { | ||
return this.props.scrim; | ||
} | ||
get inverseSurface() { | ||
@@ -115,3 +122,29 @@ return this.props.inverseSurface; | ||
static light(argb) { | ||
const core = CorePalette.of(argb); | ||
return Scheme.lightFromCorePalette(CorePalette.of(argb)); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material color scheme, based on the color's hue. | ||
*/ | ||
static dark(argb) { | ||
return Scheme.darkFromCorePalette(CorePalette.of(argb)); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Light Material content color scheme, based on the color's hue. | ||
*/ | ||
static lightContent(argb) { | ||
return Scheme.lightFromCorePalette(CorePalette.contentOf(argb)); | ||
} | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material content color scheme, based on the color's hue. | ||
*/ | ||
static darkContent(argb) { | ||
return Scheme.darkFromCorePalette(CorePalette.contentOf(argb)); | ||
} | ||
/** | ||
* Light scheme from core palette | ||
*/ | ||
static lightFromCorePalette(core) { | ||
return new Scheme({ | ||
@@ -141,3 +174,5 @@ primary: core.a1.tone(40), | ||
outline: core.n2.tone(50), | ||
outlineVariant: core.n2.tone(80), | ||
shadow: core.n1.tone(0), | ||
scrim: core.n1.tone(0), | ||
inverseSurface: core.n1.tone(20), | ||
@@ -149,7 +184,5 @@ inverseOnSurface: core.n1.tone(95), | ||
/** | ||
* @param argb ARGB representation of a color. | ||
* @return Dark Material color scheme, based on the color's hue. | ||
* Dark scheme from core palette | ||
*/ | ||
static dark(argb) { | ||
const core = CorePalette.of(argb); | ||
static darkFromCorePalette(core) { | ||
return new Scheme({ | ||
@@ -179,3 +212,5 @@ primary: core.a1.tone(80), | ||
outline: core.n2.tone(60), | ||
outlineVariant: core.n2.tone(30), | ||
shadow: core.n1.tone(0), | ||
scrim: core.n1.tone(0), | ||
inverseSurface: core.n1.tone(90), | ||
@@ -182,0 +217,0 @@ inverseOnSurface: core.n1.tone(20), |
@@ -46,4 +46,5 @@ /** | ||
*/ | ||
static score(colorsToPopulation: Map<number, number>): number[]; | ||
static score(colorsToPopulation: Map<number, number>, contentColor?: boolean): number[]; | ||
private static filter; | ||
private static filterContent; | ||
} |
@@ -42,3 +42,3 @@ /** | ||
*/ | ||
static score(colorsToPopulation) { | ||
static score(colorsToPopulation, contentColor = false) { | ||
// Determine the total count of all colors. | ||
@@ -89,3 +89,5 @@ let populationSum = 0; | ||
// Also, remove colors that are very similar in hue. | ||
const filteredColors = Score.filter(colorsToExcitedProportion, colorsToCam); | ||
const filteredColors = contentColor ? | ||
Score.filterContent(colorsToCam) : | ||
Score.filter(colorsToExcitedProportion, colorsToCam); | ||
const dedupedColorsToScore = new Map(); | ||
@@ -134,2 +136,5 @@ for (const color of filteredColors) { | ||
} | ||
static filterContent(colorsToCam) { | ||
return Array.from(colorsToCam.keys()); | ||
} | ||
} | ||
@@ -136,0 +141,0 @@ Score.TARGET_CHROMA = 48.0; |
@@ -22,2 +22,6 @@ /** | ||
/** | ||
* Converts a color from linear RGB components to ARGB format. | ||
*/ | ||
export declare function argbFromLinrgb(linrgb: number[]): number; | ||
/** | ||
* Returns the alpha component of a color in ARGB format. | ||
@@ -24,0 +28,0 @@ */ |
@@ -56,2 +56,11 @@ /** | ||
/** | ||
* Converts a color from linear RGB components to ARGB format. | ||
*/ | ||
export function argbFromLinrgb(linrgb) { | ||
const r = delinearized(linrgb[0]); | ||
const g = delinearized(linrgb[1]); | ||
const b = delinearized(linrgb[2]); | ||
return argbFromRgb(r, g, b); | ||
} | ||
/** | ||
* Returns the alpha component of a color in ARGB format. | ||
@@ -160,14 +169,5 @@ */ | ||
export function argbFromLstar(lstar) { | ||
const fy = (lstar + 16.0) / 116.0; | ||
const fz = fy; | ||
const fx = fy; | ||
const kappa = 24389.0 / 27.0; | ||
const epsilon = 216.0 / 24389.0; | ||
const lExceedsEpsilonKappa = lstar > 8.0; | ||
const y = lExceedsEpsilonKappa ? fy * fy * fy : lstar / kappa; | ||
const cubeExceedEpsilon = fy * fy * fy > epsilon; | ||
const x = cubeExceedEpsilon ? fx * fx * fx : lstar / kappa; | ||
const z = cubeExceedEpsilon ? fz * fz * fz : lstar / kappa; | ||
const whitePoint = WHITE_POINT_D65; | ||
return argbFromXyz(x * whitePoint[0], y * whitePoint[1], z * whitePoint[2]); | ||
const y = yFromLstar(lstar); | ||
const component = delinearized(y); | ||
return argbFromRgb(component, component, component); | ||
} | ||
@@ -181,11 +181,4 @@ /** | ||
export function lstarFromArgb(argb) { | ||
const y = xyzFromArgb(argb)[1] / 100.0; | ||
const e = 216.0 / 24389.0; | ||
if (y <= e) { | ||
return 24389.0 / 27.0 * y; | ||
} | ||
else { | ||
const yIntermediate = Math.pow(y, 1.0 / 3.0); | ||
return 116.0 * yIntermediate - 16.0; | ||
} | ||
const y = xyzFromArgb(argb)[1]; | ||
return 116.0 * labF(y / 100.0) - 16.0; | ||
} | ||
@@ -204,9 +197,3 @@ /** | ||
export function yFromLstar(lstar) { | ||
const ke = 8.0; | ||
if (lstar > ke) { | ||
return Math.pow((lstar + 16.0) / 116.0, 3.0) * 100.0; | ||
} | ||
else { | ||
return lstar / (24389.0 / 27.0) * 100.0; | ||
} | ||
return 100.0 * labInvf((lstar + 16.0) / 116.0); | ||
} | ||
@@ -213,0 +200,0 @@ /** |
@@ -61,2 +61,17 @@ /** | ||
/** | ||
* Sign of direction change needed to travel from one angle to | ||
* another. | ||
* | ||
* For angles that are 180 degrees apart from each other, both | ||
* directions have the same travel distance, so either direction is | ||
* shortest. The value 1.0 is returned in this case. | ||
* | ||
* @param from The angle travel starts from, in degrees. | ||
* @param to The angle travel ends at, in degrees. | ||
* @return -1 if decreasing from leads to the shortest travel | ||
* distance, 1 if increasing from leads to the shortest travel | ||
* distance. | ||
*/ | ||
export declare function rotationDirection(from: number, to: number): number; | ||
/** | ||
* Distance of two points on a circle, represented using degrees. | ||
@@ -63,0 +78,0 @@ */ |
@@ -102,2 +102,20 @@ /** | ||
/** | ||
* Sign of direction change needed to travel from one angle to | ||
* another. | ||
* | ||
* For angles that are 180 degrees apart from each other, both | ||
* directions have the same travel distance, so either direction is | ||
* shortest. The value 1.0 is returned in this case. | ||
* | ||
* @param from The angle travel starts from, in degrees. | ||
* @param to The angle travel ends at, in degrees. | ||
* @return -1 if decreasing from leads to the shortest travel | ||
* distance, 1 if increasing from leads to the shortest travel | ||
* distance. | ||
*/ | ||
export function rotationDirection(from, to) { | ||
const increasingDifference = sanitizeDegreesDouble(to - from); | ||
return increasingDifference <= 180.0 ? 1.0 : -1.0; | ||
} | ||
/** | ||
* Distance of two points on a circle, represented using degrees. | ||
@@ -104,0 +122,0 @@ */ |
@@ -99,2 +99,4 @@ /** | ||
target?: HTMLElement; | ||
brightnessSuffix?: boolean; | ||
paletteTones?: number[]; | ||
}): void; |
@@ -101,12 +101,30 @@ /** | ||
export function applyTheme(theme, options) { | ||
var _a; | ||
var _a, _b; | ||
const target = (options === null || options === void 0 ? void 0 : options.target) || document.body; | ||
const isDark = (_a = options === null || options === void 0 ? void 0 : options.dark) !== null && _a !== void 0 ? _a : false; | ||
const scheme = isDark ? theme.schemes.dark : theme.schemes.light; | ||
setSchemeProperties(target, scheme); | ||
if (options === null || options === void 0 ? void 0 : options.brightnessSuffix) { | ||
setSchemeProperties(target, theme.schemes.dark, '-dark'); | ||
setSchemeProperties(target, theme.schemes.light, '-light'); | ||
} | ||
if (options === null || options === void 0 ? void 0 : options.paletteTones) { | ||
const tones = (_b = options === null || options === void 0 ? void 0 : options.paletteTones) !== null && _b !== void 0 ? _b : []; | ||
for (const [key, palette] of Object.entries(theme.palettes)) { | ||
const paletteKey = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); | ||
for (const tone of tones) { | ||
const token = `--md-ref-palette-${paletteKey}-${paletteKey}${tone}`; | ||
const color = hexFromArgb(palette.tone(tone)); | ||
target.style.setProperty(token, color); | ||
} | ||
} | ||
} | ||
} | ||
function setSchemeProperties(target, scheme, suffix = '') { | ||
for (const [key, value] of Object.entries(scheme.toJSON())) { | ||
const token = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); | ||
const token = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); | ||
const color = hexFromArgb(value); | ||
target.style.setProperty(`--md-sys-color-${token}`, color); | ||
target.style.setProperty(`--md-sys-color-${token}${suffix}`, color); | ||
} | ||
} | ||
//# sourceMappingURL=theme_utils.js.map |
{ | ||
"name": "@material/material-color-utilities", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "Algorithms and utilities that power the Material Design 3 (M3) color system, including choosing theme colors from images and creating tones of colors; all in a new color space.", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
591955
41.62%100
13.64%6197
36.23%0
-100%