feat: tile painting

This commit is contained in:
cha0s 2022-04-04 12:34:24 -05:00
parent bda5dc2604
commit 0f0e61a514
3 changed files with 71 additions and 9 deletions

View File

@ -10,6 +10,7 @@ import {
Rectangle,
Vector,
} from '@avocado/math';
import {useJsonPatcher} from '@avocado/resource/persea';
import {
classnames,
hot,
@ -47,11 +48,13 @@ function TilesPage({
room,
roomRenderable,
}) {
const patch = useJsonPatcher();
const layerCount = resource.tiles.length;
const [currentLayer, setCurrentLayer] = useState(0);
const [tilesetEvents, setTilesetEvents] = useState();
const [solo, setSolo] = useState(Array(layerCount).fill(false));
const [incident, setIncident] = useState([0, 0]);
const [isHoldingPaint, setIsHoldingPaint] = useState(false);
const [isHolding, setIsHolding] = useState(false);
const [mute, setMute] = useState(Array(layerCount).fill(false));
const [selection, setSelection] = useState([0, 0, 16, 16]);
@ -90,15 +93,70 @@ function TilesPage({
if (!events) {
return undefined;
}
const tileSize = [16, 16];
const stamp = (translated) => {
const position = Vector.div([selection[0], selection[1]], tileSize);
const size = Vector.div([selection[2], selection[3]], tileSize);
let [x, y] = position;
const stamp = [];
for (let yy = 0; yy < size[1]; ++yy) {
for (let xx = 0; xx < size[0]; ++xx) {
stamp.push((y * (viewport[0] / tileSize[0])) + x);
x += 1;
}
x -= size[0];
y += 1;
}
const where = Rectangle.compose(translated, size);
room.tiles[currentLayer].stampAt(where, stamp);
room.tiles[currentLayer].emit('update', where);
const {data} = room.tiles[currentLayer].toJSON();
if (!data) {
patch({
op: 'remove',
path: `/tiles/${currentLayer}/data`,
});
}
else {
patch({
path: `/tiles/${currentLayer}/data`,
value: data,
});
}
};
const onValue = (
// {
// clientX,
// clientY,
// deltaY,
// target,
// type,
// },
{
clientX,
clientY,
target,
type,
},
) => {
switch (type) {
case 'touchstart':
case 'mousedown': {
const {left, top} = target.getBoundingClientRect();
const translated = Vector.floor(Vector.div([clientX - left, clientY - top], tileSize));
stamp(translated);
setIsHoldingPaint(true);
break;
}
case 'touchmove':
case 'mousemove': {
if (isHoldingPaint) {
const {left, top} = target.getBoundingClientRect();
const translated = Vector.floor(Vector.div([clientX - left, clientY - top], tileSize));
stamp(translated);
}
break;
}
case 'touchend':
case 'mouseup': {
setIsHoldingPaint(false);
break;
}
default:
}
};
events.onValue(onValue);
return () => {
@ -169,7 +227,7 @@ function TilesPage({
// eslint-disable-next-line react/no-array-index-key
<li key={i}>
<button
className={styles.layerButton}
className={classnames(styles.layerButton, {[styles.active]: currentLayer === i})}
onClick={(event) => {
// Bug? .stopPropagation() doesn't work when clicking the child checkboxes.
if (event.target === event.currentTarget) {

View File

@ -22,6 +22,9 @@
justify-content: space-between;
margin: 0.5rem 0 0 0;
width: 100%;
&.active {
background-color: rgb(0, 108, 134);
}
.info {
padding-right: 0.5rem;
}

View File

@ -289,9 +289,10 @@ export default (flecks) => {
}
toJSON() {
const isZero = !this.$$data.some((t) => !!t);
return {
area: this.area,
data: deflate(Buffer.from(this.$$data.buffer)).toString('base64'),
...(isZero ? {} : {data: deflate(Buffer.from(this.$$data.buffer)).toString('base64')}),
tileSize: this.$$tileSize,
...(this.$$tileImageUri ? {tileImageUri: this.$$tileImageUri} : []),
};