Skip to content

Commit

Permalink
Improvements for color calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
Dianliang233 committed Jan 9, 2024
1 parent 60f9326 commit de98323
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 55 deletions.
45 changes: 41 additions & 4 deletions src/tools/armorColor/App.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<script setup lang="ts">
import Field from '@/components/Field.vue'
import { ref, nextTick, watch } from 'vue'
import { CdxButton } from '@wikimedia/codex'
import { type Color, colorToSequence, colorStringToRgb, colorRgbMap } from '@/utils/colorUtils.ts'
import { CdxButton, CdxTabs, CdxTab } from '@wikimedia/codex'
import {
type Color,
colorToSequence,
colorStringToRgb,
sequenceToColorFloatAverage,
} from '@/utils/color/index.ts'
import { colorRgbMap as javaColorRgbMap } from '@/utils/color/java.ts'
import { colorRgbMap as bedrockColorRgbMap } from '@/utils/color/bedrock.ts'
const color = ref('#f9fffe')
const edition = ref<'java' | 'bedrock'>('java')
const canvasRef = ref<HTMLCanvasElement | null>(null)
const sequence = ref<[Color[], number, [number, number, number]]>([['White'], 0, [249, 255, 254]])
function sequenceToColor(c: Color[]): [number, number, number] {
function sequenceToColorJavaArmor(
c: Color[],
colorRgbMap: typeof javaColorRgbMap,
): [number, number, number] {
let numberOfColors = 0
let totalRed = 0
let totalGreen = 0
Expand Down Expand Up @@ -38,7 +49,11 @@ function sequenceToColor(c: Color[]): [number, number, number] {
async function updateSequence(targetColor: [number, number, number]) {
await nextTick()
sequence.value = colorToSequence(sequenceToColor, targetColor)
sequence.value = colorToSequence(
edition.value === 'java' ? javaColorRgbMap : bedrockColorRgbMap,
edition.value === 'java' ? sequenceToColorJavaArmor : sequenceToColorFloatAverage,
targetColor,
)
}
watch([sequence, canvasRef], ([sequence, canvasRef]) => {
Expand Down Expand Up @@ -73,6 +88,11 @@ watch([sequence, canvasRef], ([sequence, canvasRef]) => {
<template>
<Field>
<template #heading>Calculate dye sequence for a leather (horse) armor color</template>

<cdx-tabs v-model:active="edition">
<cdx-tab name="java" label="Java Edition" />
<cdx-tab name="bedrock" label="Bedrock Edition" />
</cdx-tabs>
<div
:style="{
display: 'flex',
Expand Down Expand Up @@ -138,3 +158,20 @@ watch([sequence, canvasRef], ([sequence, canvasRef]) => {
</div>
</Field>
</template>
<style>
.cdx-tabs--quiet > .cdx-tabs__header {
background-color: transparent;
}
.cdx-tabs--quiet > .cdx-tabs__header .cdx-tabs__list__item--enabled [role='tab'] {
color: var(--content-text-color);
}
.cdx-tabs__next-scroller {
display: none;
}
ul.cdx-tabs__list {
margin: 0;
}
</style>
51 changes: 33 additions & 18 deletions src/tools/beaconColor/App.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
<script setup lang="ts">
import Field from '@/components/Field.vue'
import { ref, nextTick, watch } from 'vue'
import { CdxButton } from '@wikimedia/codex'
import { CdxButton, CdxTabs, CdxTab } from '@wikimedia/codex'
import {
type Color,
colorToSequence,
colorStringToRgb,
colorRgbMap,
separateRgb,
colorMap,
floatRgbToInteger,
} from '@/utils/colorUtils.ts'
sequenceToColorFloatAverageRounded,
} from '@/utils/color/index.ts'
import { colorRgbMap as javaColorRgbMap } from '@/utils/color/java.ts'
import { colorRgbMap as bedrockColorRgbMap } from '@/utils/color/bedrock.ts'
const color = ref('#f9fffe')
const edition = ref<'java' | 'bedrock'>('java')
const canvasRef = ref<HTMLCanvasElement | null>(null)
const sequence = ref<[Color[], number, [number, number, number]]>([['White'], 0, [249, 255, 254]])
function sequenceToColor(c: Color[]) {
const color = separateRgb(colorMap[c[0]]).map((v) => v / 255) as [number, number, number]
for (let i = 1; i < c.length; i++) {
const [r, g, b] = colorRgbMap[c[i]]
color[0] = (color[0] + r / 255) / 2
color[1] = (color[1] + g / 255) / 2
color[2] = (color[2] + b / 255) / 2
}
return floatRgbToInteger(color)
}
async function updateSequence(targetColor: [number, number, number]) {
await nextTick()
sequence.value = colorToSequence(sequenceToColor, targetColor)
sequence.value = colorToSequence(
edition.value === 'java' ? javaColorRgbMap : bedrockColorRgbMap,
sequenceToColorFloatAverageRounded,
targetColor,
)
}
watch([sequence, canvasRef], ([sequence, canvasRef]) => {
Expand Down Expand Up @@ -64,6 +57,11 @@ watch([sequence, canvasRef], ([sequence, canvasRef]) => {
<template>
<Field>
<template #heading>Calculate glass sequence for a beacon beam color</template>

<cdx-tabs v-model:active="edition">
<cdx-tab name="java" label="Java Edition" />
<cdx-tab name="bedrock" label="Bedrock Edition" />
</cdx-tabs>
<div
:style="{
display: 'flex',
Expand Down Expand Up @@ -129,3 +127,20 @@ watch([sequence, canvasRef], ([sequence, canvasRef]) => {
</div>
</Field>
</template>
<style>
.cdx-tabs--quiet > .cdx-tabs__header {
background-color: transparent;
}
.cdx-tabs--quiet > .cdx-tabs__header .cdx-tabs__list__item--enabled [role='tab'] {
color: var(--content-text-color);
}
.cdx-tabs__next-scroller {
display: none;
}
ul.cdx-tabs__list {
margin: 0;
}
</style>
2 changes: 1 addition & 1 deletion src/tools/blockDistribution/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function plot(
// Draw the lines.
const line = d3.line()
const path = svg
svg
.append('g')
.attr('class', 'isolate')
.attr('fill', 'none')
Expand Down
28 changes: 28 additions & 0 deletions src/utils/color/bedrock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { rgb2lab, separateRgb } from './index.ts'

export const colorMap = {
White: 0xf9fffe,
'Light gray': 0x9d9d97,
Gray: 0x474f52,
Black: 0x1d1d21,
Brown: 0x835432,
Red: 0xb02e26,
Orange: 0xf9801d,
Yellow: 0xfed83d,
Lime: 0x80c71f,
Green: 0x5e7c16,
Cyan: 0x169c9c,
'Light blue': 0x3ab3da,
Blue: 0x3c44aa,
Purple: 0x8932b8,
Magenta: 0xc74ebd,
Pink: 0xf38baa,
} as const

export const colorRgbMap = Object.fromEntries(
Object.entries(colorMap).map(([k, v]) => [k, separateRgb(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>

export const colorLabMap = Object.fromEntries(
Object.entries(colorRgbMap).map(([k, v]) => [k, rgb2lab(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>
84 changes: 52 additions & 32 deletions src/utils/colorUtils.ts → src/utils/color/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
export const colorMap = {
White: 0xf9fffe,
'Light gray': 0x9d9d97,
Gray: 0x474f52,
Black: 0x1d1d21,
Brown: 0x835432,
Red: 0xb02e26,
Orange: 0xf9801d,
Yellow: 0xfed83d,
Lime: 0x80c71f,
Green: 0x5e7c16,
Cyan: 0x169c9c,
'Light blue': 0x3ab3da,
Blue: 0x3c44aa,
Purple: 0x8932b8,
Magenta: 0xc74ebd,
Pink: 0xf38baa,
} as const

export const combs = [
...combsWithRep(5, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
...combsWithRep(4, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
Expand All @@ -33,15 +14,23 @@ export function colorStringToRgb(color: string): [number, number, number] {
return [r, g, b]
}

export const colorRgbMap = Object.fromEntries(
Object.entries(colorMap).map(([k, v]) => [k, separateRgb(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>

export const colorLabMap = Object.fromEntries(
Object.entries(colorRgbMap).map(([k, v]) => [k, rgb2lab(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>

export type Color = keyof typeof colorMap
export type Color =
| 'White'
| 'Light gray'
| 'Gray'
| 'Black'
| 'Brown'
| 'Red'
| 'Orange'
| 'Yellow'
| 'Lime'
| 'Green'
| 'Cyan'
| 'Light blue'
| 'Blue'
| 'Purple'
| 'Magenta'
| 'Pink'

export function floatRgbToInteger(rgb: [number, number, number]) {
return rgb.map((v) => Math.floor(v * 255)) as [number, number, number]
Expand Down Expand Up @@ -113,7 +102,11 @@ function combsWithRep<T>(r: number, xs: T[] = []): T[][] {
}

export function colorToSequence(
sequenceToColor: (sequence: Color[]) => [number, number, number],
colorRgbMap: Record<Color, [number, number, number]>,
sequenceToColor: (
sequence: Color[],
colorRgbMap: Record<Color, [number, number, number]>,
) => [number, number, number],
targetRgb: [number, number, number],
): [Color[], number, [number, number, number]] {
const targetLab = rgb2lab(targetRgb)
Expand All @@ -124,10 +117,10 @@ export function colorToSequence(
for (const comb of combs) {
const sequence: Color[] = []
for (let k = 0; k < comb.length; k++) {
sequence.push(Object.keys(colorMap)[comb[k]] as Color)
sequence.push(Object.keys(colorRgbMap)[comb[k]] as Color)
}

const color = sequenceToColor(sequence)
const color = sequenceToColor(sequence, colorRgbMap)
const lab = rgb2lab(color)
const delta = deltaE(lab, targetLab)
if (delta < minDeltaE) {
Expand All @@ -136,5 +129,32 @@ export function colorToSequence(
}
}

return [minSequence, minDeltaE, sequenceToColor(minSequence)]
return [minSequence, minDeltaE, sequenceToColor(minSequence, colorRgbMap)]
}

export function sequenceToColorFloatAverage(
c: Color[],
colorRgbMap: Record<Color, [number, number, number]>,
round = false,
) {
const color = colorRgbMap[c[0]].map((v) => v / 255) as [number, number, number]
for (let i = 1; i < c.length; i++) {
const [r, g, b] = colorRgbMap[c[i]]
color[0] = (color[0] + r / 255) / 2
color[1] = (color[1] + g / 255) / 2
color[2] = (color[2] + b / 255) / 2
if (round) {
color[0] = Math.round(color[0])
color[1] = Math.round(color[1])
color[2] = Math.round(color[2])
}
}
return floatRgbToInteger(color)
}

export function sequenceToColorFloatAverageRounded(
c: Color[],
colorRgbMap: Record<Color, [number, number, number]>,
) {
return sequenceToColorFloatAverage(c, colorRgbMap, true)
}
28 changes: 28 additions & 0 deletions src/utils/color/java.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { rgb2lab, separateRgb } from './index.ts'

export const colorMap = {
White: 0xf9fffe,
'Light gray': 0x9d9d97,
Gray: 0x474f52,
Black: 0x1d1d21,
Brown: 0x835432,
Red: 0xb02e26,
Orange: 0xf9801d,
Yellow: 0xfed83d,
Lime: 0x80c71f,
Green: 0x5e7c16,
Cyan: 0x169c9c,
'Light blue': 0x3ab3da,
Blue: 0x3c44aa,
Purple: 0x8932b8,
Magenta: 0xc74ebd,
Pink: 0xf38baa,
} as const

export const colorRgbMap = Object.fromEntries(
Object.entries(colorMap).map(([k, v]) => [k, separateRgb(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>

export const colorLabMap = Object.fromEntries(
Object.entries(colorRgbMap).map(([k, v]) => [k, rgb2lab(v)]),
) as Record<keyof typeof colorMap, [number, number, number]>

0 comments on commit de98323

Please sign in to comment.