|
1 | 1 | import { Color } from "./color.js"; |
2 | 2 | import { Swatch } from "./swatch.js"; |
3 | | -import { binarySearch } from "./utilities/binary-search.js"; |
4 | | -import { directionByIsDark } from "./utilities/direction-by-is-dark.js"; |
5 | | -import { contrast, RelativeLuminance } from "./utilities/relative-luminance.js"; |
| 3 | +import { RelativeLuminance } from "./utilities/relative-luminance.js"; |
6 | 4 |
|
7 | 5 | /** |
8 | 6 | * Directional values for navigating {@link Swatch}es in {@link Palette}. |
@@ -111,137 +109,3 @@ export interface Palette<T extends Swatch = Swatch> { |
111 | 109 | */ |
112 | 110 | get(index: number): T; |
113 | 111 | } |
114 | | - |
115 | | -/** |
116 | | - * A base {@link Palette} with a common implementation of the interface. Use PaletteRGB for an implementation |
117 | | - * of a palette generation algorithm that is ready to be used directly, or extend this class to generate custom Swatches. |
118 | | - * |
119 | | - * @public |
120 | | - */ |
121 | | -export class BasePalette<T extends Swatch> implements Palette<T> { |
122 | | - /** |
123 | | - * {@inheritdoc Palette.source} |
124 | | - */ |
125 | | - readonly source: Color; |
126 | | - |
127 | | - /** |
128 | | - * {@inheritdoc Palette.swatches} |
129 | | - */ |
130 | | - readonly swatches: ReadonlyArray<T>; |
131 | | - |
132 | | - /** |
133 | | - * An index pointer to the end of the palette. |
134 | | - */ |
135 | | - readonly lastIndex: number; |
136 | | - |
137 | | - /** |
138 | | - * A copy of the `Swatch`es in reverse order, used for optimized searching. |
139 | | - */ |
140 | | - readonly reversedSwatches: ReadonlyArray<T>; |
141 | | - |
142 | | - /** |
143 | | - * Cache from `relativeLuminance` to `Swatch` index in the `Palette`. |
144 | | - */ |
145 | | - readonly closestIndexCache = new Map<number, number>(); |
146 | | - |
147 | | - /** |
148 | | - * Creates a new Palette. |
149 | | - * |
150 | | - * @param source - The source color for the Palette |
151 | | - * @param swatches - All Swatches in the Palette |
152 | | - */ |
153 | | - constructor(source: Color, swatches: ReadonlyArray<T>) { |
154 | | - this.source = source; |
155 | | - this.swatches = swatches; |
156 | | - |
157 | | - this.reversedSwatches = Object.freeze([...this.swatches].reverse()); |
158 | | - this.lastIndex = this.swatches.length - 1; |
159 | | - } |
160 | | - |
161 | | - /** |
162 | | - * {@inheritdoc Palette.colorContrast} |
163 | | - */ |
164 | | - colorContrast( |
165 | | - reference: RelativeLuminance, |
166 | | - contrastTarget: number, |
167 | | - initialSearchIndex?: number, |
168 | | - direction: PaletteDirection = directionByIsDark(reference) |
169 | | - ): T { |
170 | | - if (initialSearchIndex === undefined) { |
171 | | - initialSearchIndex = this.closestIndexOf(reference); |
172 | | - } |
173 | | - |
174 | | - let source: ReadonlyArray<T> = this.swatches; |
175 | | - const endSearchIndex = this.lastIndex; |
176 | | - let startSearchIndex = initialSearchIndex; |
177 | | - |
178 | | - const condition = (value: T) => contrast(reference, value) >= contrastTarget; |
179 | | - |
180 | | - if (direction === PaletteDirectionValue.lighter) { |
181 | | - source = this.reversedSwatches; |
182 | | - startSearchIndex = endSearchIndex - startSearchIndex; |
183 | | - } |
184 | | - |
185 | | - return binarySearch(source, condition, startSearchIndex, endSearchIndex); |
186 | | - } |
187 | | - |
188 | | - /** |
189 | | - * {@inheritdoc Palette.delta} |
190 | | - */ |
191 | | - delta(reference: RelativeLuminance, delta: number, direction: PaletteDirection): T { |
192 | | - const dir = resolvePaletteDirection(direction); |
193 | | - return this.get(this.closestIndexOf(reference) + dir * delta); |
194 | | - } |
195 | | - |
196 | | - /** |
197 | | - * {@inheritdoc Palette.closestIndexOf} |
198 | | - */ |
199 | | - closestIndexOf(reference: RelativeLuminance): number { |
200 | | - if (this.closestIndexCache.has(reference.relativeLuminance)) { |
201 | | - /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */ |
202 | | - return this.closestIndexCache.get(reference.relativeLuminance)!; |
203 | | - } |
204 | | - |
205 | | - let index = this.swatches.indexOf(reference as T); |
206 | | - |
207 | | - if (index !== -1) { |
208 | | - this.closestIndexCache.set(reference.relativeLuminance, index); |
209 | | - return index; |
210 | | - } |
211 | | - |
212 | | - const closest = this.swatches.reduce((previous, next) => |
213 | | - Math.abs(next.relativeLuminance - reference.relativeLuminance) < |
214 | | - Math.abs(previous.relativeLuminance - reference.relativeLuminance) |
215 | | - ? next |
216 | | - : previous |
217 | | - ); |
218 | | - |
219 | | - index = this.swatches.indexOf(closest); |
220 | | - this.closestIndexCache.set(reference.relativeLuminance, index); |
221 | | - |
222 | | - return index; |
223 | | - } |
224 | | - |
225 | | - /** |
226 | | - * Ensures that an input number does not exceed a max value and is not less than a min value. |
227 | | - * |
228 | | - * @param i - the number to clamp |
229 | | - * @param min - the maximum (inclusive) value |
230 | | - * @param max - the minimum (inclusive) value |
231 | | - */ |
232 | | - private clamp(i: number, min: number, max: number): number { |
233 | | - if (isNaN(i) || i <= min) { |
234 | | - return min; |
235 | | - } else if (i >= max) { |
236 | | - return max; |
237 | | - } |
238 | | - return i; |
239 | | - } |
240 | | - |
241 | | - /** |
242 | | - * {@inheritdoc Palette.get} |
243 | | - */ |
244 | | - get(index: number): T { |
245 | | - return this.swatches[index] || this.swatches[this.clamp(index, 0, this.lastIndex)]; |
246 | | - } |
247 | | -} |
0 commit comments