refactor: gen
This commit is contained in:
parent
6a45622b9d
commit
749a3356c3
|
@ -61,6 +61,9 @@ module.exports = {
|
|||
},
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'jsx-a11y/label-has-associated-control': [2, {
|
||||
controlComponents: ['SliderText'],
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
|
|
43
app/react/components/dev/slider-text.jsx
Normal file
43
app/react/components/dev/slider-text.jsx
Normal file
|
@ -0,0 +1,43 @@
|
|||
import {useState} from 'react';
|
||||
|
||||
function SliderText({
|
||||
defaultValue,
|
||||
max,
|
||||
min,
|
||||
name,
|
||||
onChange,
|
||||
step,
|
||||
}) {
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
value={value}
|
||||
max={max}
|
||||
min={min}
|
||||
name={name}
|
||||
onChange={({currentTarget: {value}}) => {
|
||||
setValue(value);
|
||||
if (onChange) {
|
||||
onChange(value);
|
||||
}
|
||||
}}
|
||||
step={step}
|
||||
type="range"
|
||||
/>
|
||||
<input
|
||||
value={value}
|
||||
name={name}
|
||||
onChange={({currentTarget: {value}}) => {
|
||||
setValue(value);
|
||||
if (onChange) {
|
||||
onChange(value);
|
||||
}
|
||||
}}
|
||||
type="text"
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SliderText;
|
10
app/routes/dev.gen._index/layer.jsx
Normal file
10
app/routes/dev.gen._index/layer.jsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import styles from './layer.module.css';
|
||||
|
||||
function Layer() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Layer;
|
0
app/routes/dev.gen._index/layer.module.css
Normal file
0
app/routes/dev.gen._index/layer.module.css
Normal file
51
app/routes/dev.gen._index/noise-field.jsx
Normal file
51
app/routes/dev.gen._index/noise-field.jsx
Normal file
|
@ -0,0 +1,51 @@
|
|||
import SliderText from '@/react/components/dev/slider-text.jsx';
|
||||
|
||||
import styles from './noise-field.module.css';
|
||||
|
||||
function NoiseField(props) {
|
||||
const {children, ...field} = props;
|
||||
return (
|
||||
<div className={styles.noiseField}>
|
||||
<input
|
||||
name="label[]"
|
||||
type="text"
|
||||
defaultValue={field.label}
|
||||
/>
|
||||
<label>
|
||||
<SliderText
|
||||
name="percent[]"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
defaultValue={field.percent}
|
||||
/>
|
||||
<span>%</span>
|
||||
</label>
|
||||
<div className={styles.scale}>
|
||||
<label>
|
||||
<span>x</span>
|
||||
<SliderText
|
||||
defaultValue={field.scale.x}
|
||||
max="100"
|
||||
min="0.01"
|
||||
name="scaleX[]"
|
||||
step="0.01"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>y</span>
|
||||
<SliderText
|
||||
defaultValue={field.scale.y}
|
||||
max="100"
|
||||
min="0.01"
|
||||
name="scaleY[]"
|
||||
step="0.01"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default NoiseField;
|
16
app/routes/dev.gen._index/noise-field.module.css
Normal file
16
app/routes/dev.gen._index/noise-field.module.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
.noiseField {
|
||||
gap: 8px;
|
||||
&, label {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
[type="text"][name^="label"] {
|
||||
width: 10em;
|
||||
}
|
||||
[type="text"][name^="percent"] {
|
||||
width: 3em;
|
||||
}
|
||||
[type="text"][name^="scale"] {
|
||||
width: 4em;
|
||||
}
|
||||
}
|
107
app/routes/dev.gen._index/route.jsx
Normal file
107
app/routes/dev.gen._index/route.jsx
Normal file
|
@ -0,0 +1,107 @@
|
|||
// import {Container, Sprite, Stage} from '@pixi/react';
|
||||
import {Form, json, redirect, useLoaderData} from '@remix-run/react';
|
||||
import {useState} from 'react';
|
||||
|
||||
import {commitSession, getSession, juggleSession} from '@/server/session.server.js';
|
||||
|
||||
import NoiseField from './noise-field.jsx';
|
||||
|
||||
function getFormSession(session) {
|
||||
return session.get('formSession') || {
|
||||
fields: [],
|
||||
};
|
||||
}
|
||||
|
||||
export async function action({request}) {
|
||||
const session = await getSession(request.headers.get('Cookie'));
|
||||
const formSession = getFormSession(session);
|
||||
const formData = await request.formData();
|
||||
const op = formData.get('op');
|
||||
if ('add-field' === op) {
|
||||
formSession.fields.push({
|
||||
label: '',
|
||||
percent: 100,
|
||||
scale: {x: 1, y: 1},
|
||||
});
|
||||
}
|
||||
else if (op.startsWith('delete/')) {
|
||||
const index = parseInt(op.slice('delete/'.length));
|
||||
if (index >= 0 && index < formSession.fields.length) {
|
||||
formSession.fields.splice(index, 1);
|
||||
}
|
||||
else {
|
||||
throw new Error('delete out of bounds');
|
||||
}
|
||||
}
|
||||
else if (op.startsWith('update/')) {
|
||||
const index = parseInt(op.slice('update/'.length));
|
||||
if (index >= 0 && index < formSession.fields.length) {
|
||||
formSession.fields[index] = {
|
||||
label: formData.getAll('label[]')[index],
|
||||
percent: formData.getAll('percent[]')[index],
|
||||
scale: {
|
||||
x: formData.getAll('scaleX[]')[index],
|
||||
y: formData.getAll('scaleY[]')[index],
|
||||
},
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error('delete out of bounds');
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error('unknown operation');
|
||||
}
|
||||
session.set('formSession', formSession);
|
||||
return json(null, {
|
||||
headers: {
|
||||
'Set-Cookie': await commitSession(session),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function loader({request}) {
|
||||
const session = await juggleSession(request);
|
||||
return json({
|
||||
formSession: getFormSession(session),
|
||||
});
|
||||
}
|
||||
|
||||
function Gen() {
|
||||
const {formSession: {fields}} = useLoaderData();
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
method="post"
|
||||
>
|
||||
{fields.map((field, i) => (
|
||||
<NoiseField
|
||||
key={i}
|
||||
{...field}
|
||||
>
|
||||
<button
|
||||
name="op"
|
||||
value={['update', i].join('/')}
|
||||
>
|
||||
o
|
||||
</button>
|
||||
<button
|
||||
name="op"
|
||||
value={['delete', i].join('/')}
|
||||
>
|
||||
x
|
||||
</button>
|
||||
</NoiseField>
|
||||
))}
|
||||
<button
|
||||
name="op"
|
||||
value="add-field"
|
||||
>
|
||||
Add field
|
||||
</button>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Gen;
|
|
@ -1,6 +1,7 @@
|
|||
import {Container, Sprite, Stage} from '@pixi/react';
|
||||
import {useState} from 'react';
|
||||
|
||||
import SliderText from '@/react/components/dev/slider-text.jsx';
|
||||
import TileLayer from '@/react/components/pixi/tile-layer.jsx';
|
||||
import AssetsContext from '@/react/context/assets.js';
|
||||
import {CHUNK_SIZE} from '@/util/constants.js';
|
||||
|
@ -45,8 +46,8 @@ function Gen() {
|
|||
const area = {x: 80, y: 80};
|
||||
const assetsTuple = useState({});
|
||||
const [seed, setSeed] = useState(0);
|
||||
const [dirtClump, setDirtClump] = useState(30);
|
||||
const [dirtPer, setDirtPer] = useState(0.3);
|
||||
const [dirtClump, setDirtClump] = useState(60);
|
||||
const [dirtPer, setDirtPer] = useState(0.6);
|
||||
|
||||
const dirtCheck = (x, y, noise) => noise(x / dirtClump, y / dirtClump) < dirtPer;
|
||||
|
||||
|
@ -163,21 +164,19 @@ function Gen() {
|
|||
</AssetsContext.Provider>
|
||||
</Stage>
|
||||
<input type="text" onChange={({currentTarget: {value}}) => setSeed(value || 0)} value={seed} />
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
<SliderText
|
||||
max="1"
|
||||
min="0"
|
||||
onChange={(value) => setDirtPer(value)}
|
||||
step="0.05"
|
||||
value={dirtPer}
|
||||
onChange={({currentTarget: {value}}) => setDirtPer(value)}
|
||||
defaultValue={dirtPer}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
<SliderText
|
||||
max="100"
|
||||
min="1"
|
||||
onChange={(value) => setDirtClump(value)}
|
||||
step="1"
|
||||
value={dirtClump}
|
||||
onChange={({currentTarget: {value}}) => setDirtClump(value)}
|
||||
defaultValue={dirtClump}
|
||||
/>
|
||||
</>
|
||||
);
|
Loading…
Reference in New Issue
Block a user