diff --git a/src/bundles/csg/functions.ts b/src/bundles/csg/functions.ts index c2f6b980b..0d79b721a 100644 --- a/src/bundles/csg/functions.ts +++ b/src/bundles/csg/functions.ts @@ -21,13 +21,12 @@ import { is_list } from 'js-slang/dist/stdlib/list'; import save from 'save-file'; -import { degreesToRadians } from '../../common/utilities'; +import { degreesToRadians, hexToColor } from '../../common/utilities'; import { Core } from './core'; import type { Solid } from './jscad/types'; import { Group, Shape, - hexToColor, type Operable, type RenderGroup, centerPrimitive diff --git a/src/bundles/csg/utilities.ts b/src/bundles/csg/utilities.ts index af4e6e699..277242028 100644 --- a/src/bundles/csg/utilities.ts +++ b/src/bundles/csg/utilities.ts @@ -9,6 +9,7 @@ import { scale as _scale, translate as _translate } from '@jscad/modeling/src/operations/transforms'; +import { hexToColor } from '../../common/utilities'; import type { ReplResult } from '../../typings/type_helpers'; import { Core } from './core'; import type { AlphaColor, Color, Solid } from './jscad/types'; @@ -218,21 +219,6 @@ export function centerPrimitive(shape: Shape) { return new Shape(solid); } -export function hexToColor(hex: string): Color { - const regex: RegExp - = /^#?(?[\da-f]{2})(?[\da-f]{2})(?[\da-f]{2})$/iu; - const potentialGroups: { [key: string]: string } | undefined - = hex.match(regex)?.groups; - if (potentialGroups === undefined) return [0, 0, 0]; - const groups: { [key: string]: string } = potentialGroups; - - return [ - parseInt(groups.red, 16) / 0xff, - parseInt(groups.green, 16) / 0xff, - parseInt(groups.blue, 16) / 0xff - ]; -} - export function colorToAlphaColor( color: Color, opacity: number = 1 diff --git a/src/bundles/rune/runes_ops.ts b/src/bundles/rune/runes_ops.ts index 58fc1e378..65c874758 100644 --- a/src/bundles/rune/runes_ops.ts +++ b/src/bundles/rune/runes_ops.ts @@ -1,6 +1,7 @@ /** * This file contains the bundle's private functions for runes. */ +import { hexToColor as hexToColorUtil } from '../../common/utilities'; import { Rune } from './rune'; // ============================================================================= @@ -338,18 +339,8 @@ export const colorPalette = [ ]; export function hexToColor(hex: string): number[] { - const result = /^#?(?[a-f\d]{2})(?[a-f\d]{2})(?[a-f\d]{2})$/iu.exec( - hex - ); - if (result === null || result.length < 4) { - return [0, 0, 0]; - } - return [ - parseInt(result[1], 16) / 255, - parseInt(result[2], 16) / 255, - parseInt(result[3], 16) / 255, - 1 - ]; + const result = hexToColorUtil(hex); + return [ ...result, 1]; } export function addColorFromHex(rune: Rune, hex: string) { diff --git a/src/common/__tests__/hextocolor.ts b/src/common/__tests__/hextocolor.ts new file mode 100644 index 000000000..835095350 --- /dev/null +++ b/src/common/__tests__/hextocolor.ts @@ -0,0 +1,17 @@ +import { hexToColor } from '../utilities'; + +describe('Test hexToColor', () => { + test.each([ + ['#FFFFFF', [1, 1, 1]], + ['ffffff', [1, 1, 1]], + ['0088ff', [0, 0.53, 1]], + ['#000000', [0, 0, 0]], + ['#GGGGGG', [0, 0, 0]], + ['888888', [0.53, 0.53, 0.53]] + ])('Testing %s', (c, expected) => { + const result = hexToColor(c); + for (let i = 0; i < expected.length; i++) { + expect(result[i]).toBeCloseTo(expected[i]); + } + }); +}); diff --git a/src/common/utilities.ts b/src/common/utilities.ts index 15ee21d21..f25780ffd 100644 --- a/src/common/utilities.ts +++ b/src/common/utilities.ts @@ -2,3 +2,15 @@ export function degreesToRadians(degrees: number): number { return (degrees / 360) * (2 * Math.PI); } + +export function hexToColor(hex: string): [number, number, number] { + const regex = /^#?([\da-f]{2})([\da-f]{2})([\da-f]{2})$/igu; + const groups = regex.exec(hex); + + if (groups == undefined) return [0, 0, 0]; + return [ + parseInt(groups[1], 16) / 0xff, + parseInt(groups[2], 16) / 0xff, + parseInt(groups[3], 16) / 0xff + ]; +}