mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
Implement color sliders
This commit is contained in:
parent
2a44421487
commit
a79341271b
@ -1,19 +1,81 @@
|
|||||||
import React, {useContext, useEffect, useState} from "react";
|
import React, {useContext, useEffect, useMemo, useRef, useState} from "react";
|
||||||
import * as params from "../src/params";
|
import * as params from "../src/params";
|
||||||
import {PainterContext} from "../src/Canvas";
|
import {PainterContext} from "../src/Canvas";
|
||||||
import {chaosGameColor} from "./chaosGameColor";
|
import {chaosGameColor} from "./chaosGameColor";
|
||||||
|
|
||||||
|
import styles from "../src/css/styles.module.css";
|
||||||
|
import {palette} from "../src/params";
|
||||||
|
|
||||||
|
const colorSwatch = (width: number, height: number, palette: number[], color: number): ImageData => {
|
||||||
|
return new ImageData(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColorSliderProps = {
|
||||||
|
title: string;
|
||||||
|
palette: number[];
|
||||||
|
color: number;
|
||||||
|
setColor: (color: number) => void;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
const ColorSlider: React.FC<ColorSliderProps> = ({title, palette, color, setColor, children}) => {
|
||||||
|
const swatch = useMemo(() => colorSwatch(50, 20, palette, color), [palette, color]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={styles.inputElement}>
|
||||||
|
<p>{title}: {color}</p>
|
||||||
|
<input type={'range'} min={0} max={1} step={.01} style={{width: '100%'}} value={color}
|
||||||
|
onInput={e => setColor(Number(e.currentTarget.value))}/>
|
||||||
|
</div>
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PaletteBarProps = {
|
||||||
|
height: number;
|
||||||
|
palette: number[];
|
||||||
|
sizingStyle: any;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
const PaletteBar: React.FC<PaletteBarProps> = ({height, palette, sizingStyle, children}) => {
|
||||||
|
const sizingRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [width, setWidth] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!sizingRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWidth(sizingRef.current.offsetWidth);
|
||||||
|
}, [sizingRef.current]);
|
||||||
|
|
||||||
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!canvasRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [canvasRef.current]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={sizingRef} style={sizingStyle}><canvas width={width} height={height}/></div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
quality?: number;
|
quality?: number;
|
||||||
children?: React.ReactElement;
|
children?: React.ReactElement;
|
||||||
}
|
}
|
||||||
export default function FlameHistogram({quality, children}: Props) {
|
export default function FlameColor({quality, children}: Props) {
|
||||||
const {width, height, setPainter} = useContext(PainterContext);
|
const {width, height, setPainter} = useContext(PainterContext);
|
||||||
|
|
||||||
const [counter, setCount] = useState(0);
|
|
||||||
const [xform1Color, setXform1Color] = useState(params.xform1Color);
|
const [xform1Color, setXform1Color] = useState(params.xform1Color);
|
||||||
const [xform2Color, setXform2Color] = useState(params.xform2Color);
|
const [xform2Color, setXform2Color] = useState(params.xform2Color);
|
||||||
const [xform3Color, setXform3Color] = useState(params.xform3Color);
|
const [xform3Color, setXform3Color] = useState(params.xform3Color);
|
||||||
|
const resetColor = () => {
|
||||||
|
setXform1Color(params.xform1Color);
|
||||||
|
setXform2Color(params.xform2Color);
|
||||||
|
setXform3Color(params.xform3Color);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const gameParams = {
|
const gameParams = {
|
||||||
@ -26,12 +88,16 @@ export default function FlameHistogram({quality, children}: Props) {
|
|||||||
colors: [xform1Color, xform2Color, xform3Color]
|
colors: [xform1Color, xform2Color, xform3Color]
|
||||||
}
|
}
|
||||||
setPainter(chaosGameColor(gameParams));
|
setPainter(chaosGameColor(gameParams));
|
||||||
}, [counter, xform1Color, xform2Color, xform3Color]);
|
}, [xform1Color, xform2Color, xform3Color]);
|
||||||
|
|
||||||
|
const resetButton = <button className={styles.inputReset} onClick={resetColor}>Reset</button>
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.inputGroup} style={{display: 'grid', gridTemplateColumns: 'auto auto auto'}}>
|
||||||
{children}
|
<p className={styles.inputTitle} style={{gridColumn: '1/-1'}}>Transform Colors {resetButton}</p>
|
||||||
<button onClick={() => setCount(counter + 1)}>Re-render {counter}</button>
|
<PaletteBar height={40} palette={palette} sizingStyle={{gridColumn: '1/-1'}}/>
|
||||||
</>
|
<ColorSlider title={"Transform 1"} palette={palette} color={xform1Color} setColor={setXform1Color}/>
|
||||||
|
<ColorSlider title={"Transform 2"} palette={palette} color={xform2Color} setColor={setXform2Color}/>
|
||||||
|
<ColorSlider title={"Transform 3"} palette={palette} color={xform3Color} setColor={setXform3Color}/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,5 +1,3 @@
|
|||||||
import {histIndex} from "../src/camera";
|
|
||||||
|
|
||||||
export function colorFromPalette(palette: number[], colorIndex: number): [number, number, number] {
|
export function colorFromPalette(palette: number[], colorIndex: number): [number, number, number] {
|
||||||
const paletteIndex = Math.floor(colorIndex * (palette.length / 3)) * 3;
|
const paletteIndex = Math.floor(colorIndex * (palette.length / 3)) * 3;
|
||||||
return [palette[paletteIndex], palette[paletteIndex + 1], palette[paletteIndex + 2]];
|
return [palette[paletteIndex], palette[paletteIndex + 1], palette[paletteIndex + 2]];
|
||||||
|
Loading…
Reference in New Issue
Block a user