Skip to content

Commit e6c9844

Browse files
fix styles
1 parent 7f2808d commit e6c9844

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+969
-1238
lines changed

custom.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ declare module 'react-syntax-highlighter' {
22
export const Light: any
33
}
44
declare module 'react-syntax-highlighter/dist/cjs/styles/hljs' {
5+
export const atomOneDark: any
56
export const github: any
67
}
78
declare module 'react-syntax-highlighter/dist/cjs/languages/*' {

next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ module.exports = {
4444
return config
4545
},
4646
i18n,
47-
reactStrictMode: true
47+
reactStrictMode: false
4848
}

package-lock.json

Lines changed: 350 additions & 532 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pages/chocobo-color/about.tsx

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import { useTranslation } from 'next-i18next'
44
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
55
import { alpha } from '@mui/system'
66
import { Theme } from '@mui/material/styles'
7+
import Typography from '@mui/material/Typography'
78
import Box from '@mui/material/Box'
9+
import Paper from '@mui/material/Paper'
810
import Collapse from '@mui/material/Collapse'
911
import TableContainer from '@mui/material/TableContainer'
1012
import Table from '@mui/material/Table'
1113
import TableHead from '@mui/material/TableHead'
1214
import TableBody from '@mui/material/TableBody'
1315
import TableRow from '@mui/material/TableRow'
1416
import TableCell from '@mui/material/TableCell'
15-
import Typography from '@mui/material/Typography'
16-
import MuiLink from '@mui/material/Link'
1717
import Button from '@mui/material/Button'
1818
import Page from '../../src/Page'
1919
import Section from '../../src/Section'
@@ -56,12 +56,8 @@ const ClampedTable = (): React.ReactElement => {
5656
<Box mb={2}>
5757
<Button variant='contained' onClick={handleClickToggleClamping}>{showClamping ? 'Hide' : 'Show'} Solutions</Button>
5858
<Collapse in={showClamping}>
59-
<TableContainer>
60-
<Table size='small' sx={{
61-
width: 'auto',
62-
margin: '0 auto',
63-
'& td': { py: 0 }
64-
}}>
59+
<TableContainer sx={{ mb: 2 }}>
60+
<Paper component={Table} sx={{ width: 'auto', m: 'auto', '& td': { py: 0 } }}>
6561
<TableHead>
6662
<TableRow>
6763
<TableCell colSpan={5} align='center'>Without clamping</TableCell>
@@ -102,12 +98,12 @@ const ClampedTable = (): React.ReactElement => {
10298

10399
rows.push(
104100
<TableRow key={index}>
105-
<TableCell align='center'>{matrixFruit !== undefined && <FruitIcon fruit={matrixFruit} size={0.8} />}</TableCell>
101+
<TableCell align='center'>{matrixFruit !== undefined && <FruitIcon fruit={matrixFruit} size={0.8} sx={{ verticalAlign: 'middle' }} />}</TableCell>
106102
<TableCell align='center'>{matrixFruit !== undefined && $(`${currentColorMatrix.R}`)}</TableCell>
107103
<TableCell align='center'>{matrixFruit !== undefined && $(`${currentColorMatrix.G}`)}</TableCell>
108104
<TableCell align='center'>{matrixFruit !== undefined && $(`${currentColorMatrix.B}`)}</TableCell>
109105
<TableCell>{matrixFruit !== undefined && <StainButton color={currentColorMatrix} />}</TableCell>
110-
<TableCell align='center'>{distanceFruit !== undefined && <FruitIcon fruit={distanceFruit} size={0.8} />}</TableCell>
106+
<TableCell align='center'>{distanceFruit !== undefined && <FruitIcon fruit={distanceFruit} size={0.8} sx={{ verticalAlign: 'middle' }} />}</TableCell>
111107
<TableCell align='center'>{distanceFruit !== undefined && $(`${currentColorDistance.R}`)}</TableCell>
112108
<TableCell align='center'>{distanceFruit !== undefined && $(`${currentColorDistance.G}`)}</TableCell>
113109
<TableCell align='center'>{distanceFruit !== undefined && $(`${currentColorDistance.B}`)}</TableCell>
@@ -119,7 +115,7 @@ const ClampedTable = (): React.ReactElement => {
119115
return rows
120116
})()}
121117
</TableBody>
122-
</Table>
118+
</Paper>
123119
</TableContainer>
124120
</Collapse>
125121
</Box>
@@ -137,7 +133,7 @@ const About = (): React.ReactElement => {
137133
Your chocobo’s plumage can be modified by feeding it 6 possible fruits. Each fruit changes the chocobo’s RGB values according to the following table:
138134
</Typography>
139135
<TableContainer sx={{ mb: 2 }}>
140-
<Table size='small' sx={{ width: 'auto', margin: '0 auto' }}>
136+
<Paper component={Table} sx={{ width: 'auto', m: 'auto' }}>
141137
<TableHead>
142138
<TableRow>
143139
<TableCell align='center'>Fruit</TableCell>
@@ -160,7 +156,10 @@ const About = (): React.ReactElement => {
160156
const { R, G, B } = fruitValues[fruit]
161157
return (
162158
<TableRow key={fruit}>
163-
<TableCell><FruitIcon fruit={fruit} /> {translate(locale, fruits[fruit], 'name')}</TableCell>
159+
<TableCell>
160+
<FruitIcon fruit={fruit} sx={{ verticalAlign: 'middle', mr: 1 }} />
161+
<Typography component='span' sx={{ verticalAlign: 'middle' }}>{translate(locale, fruits[fruit], 'name')}</Typography>
162+
</TableCell>
164163
<TableCell
165164
align='center'
166165
sx={{ backgroundColor: R > 0 ? POSITIVE_COLOR : R < 0 ? NEGATIVE_COLOR : 'none' }}
@@ -184,14 +183,14 @@ const About = (): React.ReactElement => {
184183
})
185184
}
186185
</TableBody>
187-
</Table>
186+
</Paper>
188187
</TableContainer>
189-
<Typography paragraph>
190-
RGB values can never exceed {$('250')} or go below {$('0')}. If eating a fruit will cause a value to go beyond the valid range, it will be clamped. The RGB values of possible colors are known, and the problem is how to determine what sequence of fruits will get from one color to another. Unfortunately, not all RGB values are possible since the fruits always change values in increments of {$('5')} (ignoring clamping). The goal is to reach certain RGB values such that the closest possible color is the desired color. Distance here is measured using the <MuiLink href='https://en.wikipedia.org/wiki/Euclidean_distance'>Euclidean norm</MuiLink> (assuming this is what FFXIV uses).
188+
<Typography>
189+
RGB values can never exceed {$('250')} or go below {$('0')}. If eating a fruit will cause a value to go beyond the valid range, it will be clamped. The RGB values of possible colors are known, and the problem is how to determine what sequence of fruits will get from one color to another. Unfortunately, not all RGB values are possible since the fruits always change values in increments of {$('5')} (ignoring clamping). The goal is to reach certain RGB values such that the closest possible color is the desired color. Distance here is measured using the <Link href='https://en.wikipedia.org/wiki/Euclidean_distance'>Euclidean norm</Link> (assuming this is what FFXIV uses).
191190
</Typography>
192-
<Box mb={2}>
191+
<TableContainer sx={{ mb: 2 }}>
193192
{$$('\\lVert \\text{Color} \\rVert = \\sqrt{\\text{Color.R}^2 + \\text{Color.G}^2 + \\text{Color.B}^2}')}
194-
</Box>
193+
</TableContainer>
195194
</Section>
196195
<Section title='Greedy Algorithm'>
197196
<Typography paragraph>
@@ -231,10 +230,10 @@ function calculate (startColor: Color, endColor: Color): Fruit[] {
231230
</Typography>
232231
</Section>
233232
<Section title='Matrix Algorithm'>
234-
<Typography paragraph>
233+
<Typography>
235234
The next algorithm to consider involves treating the problem as a sort of matrix equation. Using the variables
236235
</Typography>
237-
<Box mb={2}>
236+
<TableContainer sx={{ mb: 2 }}>
238237
{$$(`
239238
\\begin{align}
240239
X & = \\text{# of ${translate(locale, fruits[Fruit.XelphatolApple], 'plural', 'singular')}} \\\\
@@ -245,11 +244,11 @@ function calculate (startColor: Color, endColor: Color): Fruit[] {
245244
C & = \\text{# of ${translate(locale, fruits[Fruit.CieldalaesPineapple], 'plural', 'singular')}} \\\\
246245
\\end{align}
247246
`)}
248-
</Box>
249-
<Typography paragraph>
247+
</TableContainer>
248+
<Typography>
250249
and not requiring them to be integers, we must solve
251250
</Typography>
252-
<Box mb={2}>
251+
<TableContainer sx={{ mb: 2 }}>
253252
{$$(`
254253
\\begin{array}{ll}
255254
\\text{minimize} & \\phantom{+}X +M +O +D +V +C, \\\\
@@ -261,14 +260,14 @@ function calculate (startColor: Color, endColor: Color): Fruit[] {
261260
\\text{and} & X, M, O, D, V, C \\geq 0 \\\\
262261
\\end{array}
263262
`)}
264-
</Box>
263+
</TableContainer>
265264
<Typography paragraph>
266-
where {$('R, G, B')} is the difference {$('\\text{DesiredColor} - \\text{CurrentColor}')}. This does not take into account clamping, which can be avoided almost always. It gives only the number of fruits required, which is then ordered to hopefully avoid clamping. I did this by repeatedly picking fruits that minimize the distance to {$('\\operatorname{RGB}(\\frac{256}{2}, \\frac{256}{2}, \\frac{256}{2})')} using the <MuiLink href='https://en.wikipedia.org/wiki/Uniform_norm'>uniform norm</MuiLink>.
265+
where {$('R, G, B')} is the difference {$('\\text{DesiredColor} - \\text{CurrentColor}')}. This does not take into account clamping, which can be avoided almost always. It gives only the number of fruits required, which is then ordered to hopefully avoid clamping. I did this by repeatedly picking fruits that minimize the distance to {$('\\operatorname{RGB}(\\frac{256}{2}, \\frac{256}{2}, \\frac{256}{2})')} using the <Link href='https://en.wikipedia.org/wiki/Uniform_norm'>uniform norm</Link>.
267266
</Typography>
268-
<Typography paragraph>
267+
<Typography>
269268
Since the {$('D, V, C')} fruits are “opposites” of the {$('X, M, O')} fruits, we can drop the {$('D, V, C')} variables by removing the nonnegativity constraints on {$('X, M, O')}. This transforms the problem into the standard linear equation
270269
</Typography>
271-
<Box mb={2}>
270+
<TableContainer sx={{ mb: 2 }}>
272271
{$$(`
273272
\\begin{pmatrix}
274273
\\phantom{+}5 & -5 & -5 \\\\
@@ -283,9 +282,9 @@ function calculate (startColor: Color, endColor: Color): Fruit[] {
283282
R \\\\ G \\\\ B
284283
\\end{pmatrix}
285284
`)}
286-
</Box>
285+
</TableContainer>
287286
<Typography paragraph>
288-
with a negative value of {$('X')} corresponding instead to a positive value of {$('D')}, etc. To turn the solutions into integers, I round them. (This doesn’t always give the closest color, and that problem is the <MuiLink href='https://en.wikipedia.org/wiki/Lattice_problem#Closest_vector_problem_(CVP)'>closest vector problem</MuiLink>. The lattice is “nice” enough though, and since I don’t end up using this strategy, I don’t bother optimizing it.) This algorithm can outperform the first algorithm in situations where the first algorithm would terminate early.
287+
with a negative value of {$('X')} corresponding instead to a positive value of {$('D')}, etc. To turn the solutions into integers, I round them. (This doesn’t always give the closest color, and that problem is the <Link href='https://en.wikipedia.org/wiki/Lattice_problem#Closest_vector_problem_(CVP)'>closest vector problem</Link>. The lattice is “nice” enough though, and since I don’t end up using this strategy, I don’t bother optimizing it.) This algorithm can outperform the first algorithm in situations where the first algorithm would terminate early.
289288
</Typography>
290289
</Section>
291290
<Section title='Lookahead'>
@@ -341,7 +340,7 @@ while (true) {
341340
Let the solution the algorithm returns be {$('\\operatorname{RGB(r, g, b)}')}. Focusing only on the red component, the optimal solution must have a red component of {$('r-5')}, {$('r')}, or {$('r+5')}. Now consider the 27 points:
342341
</Typography>
343342
<TableContainer sx={{ mb: 2 }}>
344-
<Table size='small' sx={{ width: 'auto', margin: '0 auto' }}>
343+
<Paper component={Table} sx={{ width: 'auto', m: 'auto' }}>
345344
<TableHead>
346345
<TableRow>
347346
<TableCell />
@@ -410,13 +409,13 @@ while (true) {
410409
<TableCell align='center' sx={{ backgroundColor: NEGATIVE_COLOR }}>{$('(r+5, g+5, b+5)')}</TableCell>
411410
</TableRow>
412411
</TableBody>
413-
</Table>
412+
</Paper>
414413
</TableContainer>
415414
<Typography paragraph>
416415
One of these points is the optimal solution, and all the points marked as red are impossible to reach due to parity (see the Error section below). Starting at {$('(r, g, b)')}, we must show that the algorithm considers all the green points with a lookahead of {$('L = 3')}. By symmetry, there are only 3 cases that need to be checked.
417416
</Typography>
418417
<TableContainer sx={{ mb: 2 }}>
419-
<Table size='small' sx={{ width: 'auto', margin: '0 auto' }}>
418+
<Paper component={Table} sx={{ width: 'auto', m: 'auto' }}>
420419
<TableHead>
421420
<TableRow>
422421
<TableCell align='center'>Target color</TableCell>
@@ -437,7 +436,7 @@ while (true) {
437436
<TableCell align='center'><FruitIcon fruit={Fruit.CieldalaesPineapple} /></TableCell>
438437
</TableRow>
439438
</TableBody>
440-
</Table>
439+
</Paper>
441440
</TableContainer>
442441
<Typography paragraph>
443442
Thus the algorithm is optimal, in the sense that it returns the closest possible color without clamping.
@@ -451,7 +450,7 @@ while (true) {
451450
Feeding a fruit will always change the parity of the RGB values, i.e. odd → even or even → odd. If the target color is {$('\\operatorname{RGB}(100, 100, 100)')} with all even values, and the current color is {$('\\operatorname{RGB}(100, 100, 105)')} with 1 odd value, no sequence of fruits can get closer (ignoring clamping). Thus the maximum error is bounded below by {$('5')}, and we cannot guarantee that the closest color is the desired color. The maximum error is actually {$('5\\sqrt{5}/2 \\approx 5.59')} given by the vector {$('(5, 2.5, 0)')}.
452451
</Typography>
453452
<Typography paragraph>
454-
A possible solution is to instead aim for some color that is near the desired color and far from other nearby colors, maximizing the likelihood that we end up at the desired color. The hope is that our final color ends up inside the <MuiLink href='https://en.wikipedia.org/wiki/Voronoi_diagram'>Voronoi cell</MuiLink> of the desired color, so a sensible target would be the centroid of this region. In 2D, this may look like
453+
A possible solution is to instead aim for some color that is near the desired color and far from other nearby colors, maximizing the likelihood that we end up at the desired color. The hope is that our final color ends up inside the <Link href='https://en.wikipedia.org/wiki/Voronoi_diagram'>Voronoi cell</Link> of the desired color, so a sensible target would be the centroid of this region. In 2D, this may look like
455454
</Typography>
456455
<Box component='figure' mb={2} textAlign='center'>
457456
<img src='/images/chocobo-color/voronoi-diagram.png' />
@@ -463,7 +462,7 @@ while (true) {
463462
This would allow more room for error, but I decided computing these targets would be too much work. It would also complicate recoloring chocobos. As long as the algorithm gets as close to the desired color as possible (ignoring clamping), it’s sufficient. There are only two color combinations where the closest color does not lead to the desired color, and those have hardcoded solutions for now.
464463
</Typography>
465464
<TableContainer sx={{ mb: 2 }}>
466-
<Table size='small' sx={{ width: 'auto', margin: '0 auto' }}>
465+
<Paper component={Table} sx={{ width: 'auto', m: 'auto' }}>
467466
<TableBody>
468467
<TableRow>
469468
<TableCell component='th' scope='row' align='center'>Current color</TableCell>
@@ -501,7 +500,7 @@ while (true) {
501500
<TableCell align='center'><StainButton color={new Color(50, 49, 55)} /></TableCell>
502501
</TableRow>
503502
</TableBody>
504-
</Table>
503+
</Paper>
505504
</TableContainer>
506505
</Section>
507506
</Page>

0 commit comments

Comments
 (0)