mirror of
https://github.com/duckietm/Nitro-Cool-UI.git
synced 2025-06-21 22:36:58 +00:00
Fix: Move Floorplan out of Pixi and make it full selectable
This commit is contained in:
parent
8c244f1132
commit
304e945c13
21
src/common/Slider.tsx
Normal file
21
src/common/Slider.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { FC } from 'react';
|
||||
import ReactSlider, { ReactSliderProps } from 'react-slider';
|
||||
import { Button } from './Button';
|
||||
import { Flex } from './Flex';
|
||||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||||
|
||||
export interface SliderProps extends ReactSliderProps
|
||||
{
|
||||
disabledButton?: boolean;
|
||||
}
|
||||
|
||||
export const Slider: FC<SliderProps> = props =>
|
||||
{
|
||||
const { disabledButton, max, min, value, onChange, ...rest } = props;
|
||||
|
||||
return <Flex fullWidth gap={ 1 }>
|
||||
{ !disabledButton && <Button disabled={ min >= value } onClick={ () => onChange(min < value ? value - 1 : min, 0) }><FaAngleLeft /></Button> }
|
||||
<ReactSlider className={ 'nitro-slider' } max={ max } min={ min } value={ value } onChange={ onChange } { ...rest } />
|
||||
{ !disabledButton && <Button disabled={ max <= value } onClick={ () => onChange(max > value ? value + 1 : max, 0) }><FaAngleRight /></Button> }
|
||||
</Flex>;
|
||||
}
|
@ -16,6 +16,7 @@ export * from './HorizontalRule';
|
||||
export * from './InfiniteScroll';
|
||||
export * from './layout';
|
||||
export * from './layout/limited-edition';
|
||||
export * from "./Slider";
|
||||
export * from './Text';
|
||||
export * from './transitions';
|
||||
export * from './types';
|
||||
|
@ -4,6 +4,6 @@
|
||||
}
|
||||
|
||||
.floorplan-import-export {
|
||||
width: 500px;
|
||||
width: 630px;
|
||||
height: 475px;
|
||||
}
|
||||
|
@ -3,11 +3,11 @@ import { FC, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { Button, ButtonGroup, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
||||
import { useMessageEvent, useRoomEngineEvent } from '../../hooks';
|
||||
import { FloorplanEditorContextProvider } from './FloorplanEditorContext';
|
||||
import { FloorplanEditor } from './common/FloorplanEditor';
|
||||
import { IFloorplanSettings } from './common/IFloorplanSettings';
|
||||
import { IVisualizationSettings } from './common/IVisualizationSettings';
|
||||
import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils';
|
||||
import { FloorplanEditorContextProvider } from './FloorplanEditorContext';
|
||||
import { FloorplanCanvasView } from './views/FloorplanCanvasView';
|
||||
import { FloorplanImportExportView } from './views/FloorplanImportExportView';
|
||||
import { FloorplanOptionsView } from './views/FloorplanOptionsView';
|
||||
@ -135,11 +135,6 @@ export const FloorplanEditorView: FC<{}> = props =>
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
FloorplanEditor.instance.initialize();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FloorplanEditorContextProvider value={ { originalFloorplanSettings: originalFloorplanSettings, setOriginalFloorplanSettings: setOriginalFloorplanSettings, visualizationSettings: visualizationSettings, setVisualizationSettings: setVisualizationSettings } }>
|
||||
{ isVisible &&
|
||||
|
@ -1,5 +1,5 @@
|
||||
export const TILE_SIZE = 32;
|
||||
export const MAX_NUM_TILE_PER_AXIS = 64;
|
||||
export const MAX_NUM_TILE_PER_AXIS = 100;
|
||||
|
||||
export const HEIGHT_SCHEME: string = 'x0123456789abcdefghijklmnopq';
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { GetAssetManager, IGraphicAssetCollection, NitroPoint, NitroTilemap, PixiApplicationProxy, PixiInteractionEventProxy, POINT_STRUCT_SIZE } from '@nitrots/nitro-renderer';
|
||||
import { NitroPoint } from '@nitrots/nitro-renderer';
|
||||
import { ActionSettings } from './ActionSettings';
|
||||
import { FloorAction, HEIGHT_SCHEME, MAX_NUM_TILE_PER_AXIS, TILE_SIZE } from './Constants';
|
||||
import { imageBase64, spritesheet } from './FloorplanResource';
|
||||
import { Tile } from './Tile';
|
||||
import { getScreenPositionForTile, getTileFromScreenPosition } from './Utils';
|
||||
import { getScreenPositionForTile } from './Utils';
|
||||
|
||||
export class FloorplanEditor extends PixiApplicationProxy
|
||||
export class FloorplanEditor
|
||||
{
|
||||
private static _INSTANCE: FloorplanEditor = null;
|
||||
|
||||
@ -14,160 +15,107 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
private _tilemap: Tile[][];
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
private _isHolding: boolean;
|
||||
private _isPointerDown: boolean;
|
||||
private _doorLocation: NitroPoint;
|
||||
private _lastUsedTile: NitroPoint;
|
||||
private _tilemapRenderer: NitroTilemap;
|
||||
private _renderer: CanvasRenderingContext2D;
|
||||
private _actionSettings: ActionSettings;
|
||||
private _isInitialized: boolean;
|
||||
|
||||
private _assetCollection: IGraphicAssetCollection;
|
||||
private _image: HTMLImageElement;
|
||||
|
||||
constructor()
|
||||
{
|
||||
const width = TILE_SIZE * MAX_NUM_TILE_PER_AXIS + 20;
|
||||
const height = (TILE_SIZE * MAX_NUM_TILE_PER_AXIS) / 2 + 100;
|
||||
|
||||
super({
|
||||
width: width,
|
||||
height: height,
|
||||
backgroundColor: 0x000000,
|
||||
antialias: true,
|
||||
autoDensity: true,
|
||||
resolution: 1,
|
||||
sharedLoader: true,
|
||||
sharedTicker: true
|
||||
});
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
canvas.height = height;
|
||||
canvas.width = width;
|
||||
|
||||
canvas.style.touchAction = 'none';
|
||||
|
||||
this._renderer = canvas.getContext('2d');
|
||||
|
||||
this._image = new Image();
|
||||
|
||||
this._image.src = imageBase64;
|
||||
|
||||
this._tilemap = [];
|
||||
this._doorLocation = new NitroPoint(0, 0);
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this._isHolding = false;
|
||||
this._isPointerDown = false;
|
||||
this._lastUsedTile = new NitroPoint(-1, -1);
|
||||
this._actionSettings = new ActionSettings();
|
||||
}
|
||||
|
||||
public initialize(): void
|
||||
public onPointerRelease(): void
|
||||
{
|
||||
if(this._isInitialized) return;
|
||||
|
||||
const collection = GetAssetManager().getCollection('floor_editor');
|
||||
|
||||
if(!collection) return;
|
||||
|
||||
this._assetCollection = collection;
|
||||
this._tilemapRenderer = new NitroTilemap(collection.baseTexture);
|
||||
|
||||
this.registerEventListeners();
|
||||
|
||||
this.stage.addChild(this._tilemapRenderer);
|
||||
|
||||
this._isInitialized = true;
|
||||
this._isPointerDown = false;
|
||||
}
|
||||
|
||||
private registerEventListeners(): void
|
||||
public onPointerDown(event: PointerEvent): void
|
||||
{
|
||||
//this._tilemapRenderer.interactive = true;
|
||||
if(event.button === 2) return;
|
||||
|
||||
const tempPoint = new NitroPoint();
|
||||
// @ts-ignore
|
||||
this._tilemapRenderer.containsPoint = (position) =>
|
||||
{
|
||||
this._tilemapRenderer.worldTransform.applyInverse(position, tempPoint);
|
||||
return this.tileHitDetection(tempPoint, false);
|
||||
};
|
||||
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||
|
||||
this._tilemapRenderer.on('pointerup', () =>
|
||||
{
|
||||
this._isHolding = false;
|
||||
});
|
||||
this._isPointerDown = true;
|
||||
|
||||
this._tilemapRenderer.on('pointerout', () =>
|
||||
{
|
||||
this._isHolding = false;
|
||||
});
|
||||
|
||||
this._tilemapRenderer.on('pointerdown', (event: PixiInteractionEventProxy) =>
|
||||
{
|
||||
if(!(event.data.originalEvent instanceof PointerEvent) && !(event.data.originalEvent instanceof TouchEvent)) return;
|
||||
|
||||
const pointerEvent = event.data.originalEvent;
|
||||
if((pointerEvent instanceof MouseEvent) && pointerEvent.button === 2) return;
|
||||
|
||||
|
||||
const location = event.data.global;
|
||||
this.tileHitDetection(location, true);
|
||||
});
|
||||
|
||||
this._tilemapRenderer.on('click', (event: PixiInteractionEventProxy) =>
|
||||
{
|
||||
if(!(event.data.originalEvent instanceof PointerEvent)) return;
|
||||
|
||||
const pointerEvent = event.data.originalEvent;
|
||||
if(pointerEvent.button === 2) return;
|
||||
|
||||
const location = event.data.global;
|
||||
this.tileHitDetection(location, true, true);
|
||||
});
|
||||
this.tileHitDetection(location, true);
|
||||
}
|
||||
|
||||
private tileHitDetection(tempPoint: NitroPoint, setHolding: boolean, isClick: boolean = false): boolean
|
||||
public onPointerMove(event: PointerEvent): void
|
||||
{
|
||||
// @ts-ignore
|
||||
const buffer = this._tilemapRenderer.pointsBuf;
|
||||
const bufSize = POINT_STRUCT_SIZE;
|
||||
if(!this._isPointerDown) return;
|
||||
|
||||
const len = buffer.length;
|
||||
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||
this.tileHitDetection(location, false);
|
||||
}
|
||||
|
||||
if(setHolding)
|
||||
private tileHitDetection(tempPoint: NitroPoint, isClick: boolean = false): boolean
|
||||
{
|
||||
const mousePositionX = Math.floor(tempPoint.x);
|
||||
const mousePositionY = Math.floor(tempPoint.y);
|
||||
|
||||
const width = TILE_SIZE;
|
||||
const height = TILE_SIZE / 2;
|
||||
|
||||
for(let y = 0; y < this._tilemap.length; y++)
|
||||
{
|
||||
this._isHolding = true;
|
||||
}
|
||||
|
||||
for(let j = 0; j < len; j += bufSize)
|
||||
{
|
||||
const bufIndex = j + bufSize;
|
||||
const data = buffer.slice(j, bufIndex);
|
||||
|
||||
const width = TILE_SIZE;
|
||||
const height = TILE_SIZE / 2;
|
||||
|
||||
const mousePositionX = Math.floor(tempPoint.x);
|
||||
const mousePositionY = Math.floor(tempPoint.y);
|
||||
|
||||
const tileStartX = data[2];
|
||||
const tileStartY = data[3];
|
||||
|
||||
const centreX = tileStartX + (width / 2);
|
||||
const centreY = tileStartY + (height / 2);
|
||||
|
||||
const dx = Math.abs(mousePositionX - centreX);
|
||||
const dy = Math.abs(mousePositionY - centreY);
|
||||
|
||||
const solution = (dx / (width * 0.5) + dy / (height * 0.5) <= 1);//todo: improve this
|
||||
if(solution)
|
||||
for(let x = 0; x < this.tilemap[y].length; x++)
|
||||
{
|
||||
if(this._isHolding)
|
||||
const [ tileStartX, tileStartY ] = getScreenPositionForTile(x, y);
|
||||
|
||||
const centreX = tileStartX + (width / 2);
|
||||
const centreY = tileStartY + (height / 2);
|
||||
|
||||
const dx = Math.abs(mousePositionX - centreX);
|
||||
const dy = Math.abs(mousePositionY - centreY);
|
||||
|
||||
const solution = (dx / (width * 0.5) + dy / (height * 0.5) <= 1);//todo: improve this
|
||||
|
||||
if(solution)
|
||||
{
|
||||
const [ realX, realY ] = getTileFromScreenPosition(tileStartX, tileStartY);
|
||||
|
||||
if(isClick)
|
||||
if(this._isPointerDown)
|
||||
{
|
||||
this.onClick(realX, realY);
|
||||
}
|
||||
if(isClick)
|
||||
{
|
||||
this.onClick(x, y);
|
||||
}
|
||||
|
||||
else if(this._lastUsedTile.x !== realX || this._lastUsedTile.y !== realY)
|
||||
{
|
||||
this._lastUsedTile.x = realX;
|
||||
this._lastUsedTile.y = realY;
|
||||
this.onClick(realX, realY);
|
||||
}
|
||||
else if(this._lastUsedTile.x !== x || this._lastUsedTile.y !== y)
|
||||
{
|
||||
this._lastUsedTile.x = x;
|
||||
this._lastUsedTile.y = y;
|
||||
this.onClick(x, y);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -221,7 +169,7 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
|
||||
if(!newHeight) return;
|
||||
|
||||
if(tile.isBlocked) return;
|
||||
// if(tile.isBlocked) return;
|
||||
|
||||
this._tilemap[y][x].height = newHeight;
|
||||
|
||||
@ -230,7 +178,7 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
|
||||
public renderTiles(): void
|
||||
{
|
||||
this.tilemapRenderer.clear();
|
||||
this.clearCanvas();
|
||||
|
||||
for(let y = 0; y < this._tilemap.length; y++)
|
||||
{
|
||||
@ -244,10 +192,13 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
|
||||
if(tile.isBlocked) assetName = FloorplanEditor.TILE_BLOCKED;
|
||||
|
||||
//if((tile.height === 'x') || tile.height === 'X') continue;
|
||||
if ((tile.height === 'x' || tile.height === 'X') && tile.isBlocked) assetName = 'x';
|
||||
|
||||
const [ positionX, positionY ] = getScreenPositionForTile(x, y);
|
||||
|
||||
this._tilemapRenderer.tile(this._assetCollection.getTexture(`floor_editor_${ assetName }`), positionX, positionY);
|
||||
const asset = spritesheet.frames[assetName];
|
||||
|
||||
this.renderer.drawImage(this._image, asset.frame.x, asset.frame.y, asset.frame.w, asset.frame.h, positionX, positionY, asset.frame.w, asset.frame.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,20 +323,25 @@ export class FloorplanEditor extends PixiApplicationProxy
|
||||
|
||||
public clear(): void
|
||||
{
|
||||
this._tilemapRenderer.interactive = false;
|
||||
this._tilemap = [];
|
||||
this._doorLocation.set(-1, -1);
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this._isHolding = false;
|
||||
this._isPointerDown = false;
|
||||
this._lastUsedTile.set(-1, -1);
|
||||
this._actionSettings.clear();
|
||||
this._tilemapRenderer.clear();
|
||||
this.clearCanvas();
|
||||
}
|
||||
|
||||
public get tilemapRenderer(): NitroTilemap
|
||||
public clearCanvas(): void
|
||||
{
|
||||
return this._tilemapRenderer;
|
||||
this.renderer.fillStyle = '0x000000';
|
||||
this.renderer.fillRect(0, 0, this._renderer.canvas.width, this._renderer.canvas.height);
|
||||
}
|
||||
|
||||
public get renderer(): CanvasRenderingContext2D
|
||||
{
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
public get tilemap(): Tile[][]
|
||||
|
227
src/components/floorplan-editor/common/FloorplanResource.ts
Normal file
227
src/components/floorplan-editor/common/FloorplanResource.ts
Normal file
@ -0,0 +1,227 @@
|
||||
export const imageBase64 =
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAAC+CAMAAADnThrbAAAAYFBMVEUAAAAiIiIAZf8A6P8A/5MZ/wCb/wD/tQD/MgD/AHr/APxDXocAkf8A/+oA/2hE/wDy/wD/iQD/BwD/AKXWAP////8AvP8A/78A/z1w/wD/4AD/XgD/ACP/ANGqAP8QEBBSz3qJAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAABJxJREFUeNrt1tuOszoMBeDpD7QFBloKDGf6/m+51UTj1PUhN1uWOup3vSQLkSzn6+vV4fAV9X9lLIcdDv/+xWKHw/d3PPPzE8k8Rj1osceoBz3z4yiZ31HauN9R2rjfUcq451HSuOdR0rjnUcK411HcuNdR3LjXUcw4btTrOG7U6zhu1Ms4adTzOGnU8zhpVBh30Eb5cQ/fKp/5UR1+51l9mfU/Mz6NxvfMuEGMu9G49f/y8vzLz4Ikif/8qopnhiF6FhNHP9aVo2cGR71lCZAvbAXkzADE/kgQvooqhM8MCNuMCUFLtiJoZiBI5ycsvD4qFs4MLLTNElFYjJUoZAYRPAsSlV/5lcpnBhU8C6y+zPqfGZ9G43tm3CDG3Wjc+p9N/Z7PgjSN//y6jmfGMXoWU0c/1rWjZ0ZHvWUpkC9sDeTMCMT+SBG+imqEz4wI24wpQUu2JmhmJEjnpyy8PmoWzowstM1SUViMtShkRhE8C1KVX/m1ymdGFTwLrL7M+p8Zn0bje2bcIMbdaNz6n039ns+CLIv//Mslnpmm6FnMHP1YXxw9MznqLcuAfGEvQM5MQOyPDOGr6ILwmQlhmzEjaMleCJqZCNL5GQuvjwsLZyYW2maZKCzGiyhkJhE8CzKVX/kXlc9MKngWWH2Z9T8zPo3G98y4QYy70bj1P5v6PZ8Fx2P851+v8cw8R8/i0dGP9dXRM7Oj3rIjkC/sFciZGYj9cUT4KroifGZG2GY8ErRkrwTNzATp/CMLr48rC2dmFtpmR1FYjFdRyMwieBYcVX7lX1U+M6vgWWD1Zdb/zPg0Gt8z4wYx7kbj1v9s6vd8FpxO8Z/fNPHMskTP4snRj3Xj6JnFUW/ZCcgXtgFyZgFif5wQvooahM8sCNuMJ4KWbEPQzEKQzj+x8PpoWDizsNA2O4nCYmxEIbOI4FlwUvmV36h8ZlHBs8Dqy6z/mfFpNL5nxg1i3I3Grf/Z1O/5LDif4z//dotn1jV6Fs+Ofqxvjp5ZHfWWnYF8YW9AzqxA7I8zwlfRDeEzK8I245mgJXsjaGYlSOefWXh93Fg4s7LQNjuLwmK8iUJmFcGz4KzyK/+m8plVBc8Cqy+z/mfGp9H4nhk3iHE3Grf+Z1O/57Mgz+M/v23jmW2LnsXc0Y916+iZzVFvWQ7kC9sCObMBsT9yhK+iFuEzG8I2Y07Qkm0JmtkI0vk5C6+PloUzGwtts1wUFmMrCplNBM+CXOVXfqvymU0FzwKrL7P+Z8an0fieGTeIcTcat/5nU7/ns6Ao4j+/6+KZfY+excLRj3Xn6JndUW9ZAeQL2wE5swOxPwqEr6IO4TM7wjZjQdCS7Qia2QnS+QULr4+OhTM7C22zQhQWYycKmV0Ez4JC5Vd+p/KZXQXPAqsvs/5nxqfR+J4ZN4hxNxq3/mdTv+ezoCzjP7/v45n7PXoWS0c/1r2jZ+6OestKIF/YHsiZOxD7o0T4KuoRPnNH2GYsCVqyPUEzd4J0fsnC66Nn4cydhbZZKQqLsReFzF0Ez4JS5Vd+r/KZuwqeBVZfZv3PjE+j8T0zbhDjbjRu/b+0PP8DZwi9QurvbfwAAAAASUVORK5CYII=';
|
||||
|
||||
export const spritesheet = {
|
||||
frames: {
|
||||
'0': {
|
||||
frame: { x: 1, y: 1, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'1': {
|
||||
frame: { x: 37, y: 1, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'2': {
|
||||
frame: { x: 73, y: 1, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'3': {
|
||||
frame: { x: 1, y: 20, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'4': {
|
||||
frame: { x: 37, y: 20, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'5': {
|
||||
frame: { x: 73, y: 20, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'6': {
|
||||
frame: { x: 1, y: 39, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'7': {
|
||||
frame: { x: 37, y: 39, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'8': {
|
||||
frame: { x: 73, y: 39, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'9': {
|
||||
frame: { x: 1, y: 58, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'a': {
|
||||
frame: { x: 37, y: 58, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'b': {
|
||||
frame: { x: 73, y: 58, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'c': {
|
||||
frame: { x: 1, y: 77, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'd': {
|
||||
frame: { x: 37, y: 77, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'e': {
|
||||
frame: { x: 73, y: 77, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'f': {
|
||||
frame: { x: 1, y: 96, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'g': {
|
||||
frame: { x: 37, y: 96, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'h': {
|
||||
frame: { x: 73, y: 96, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'i': {
|
||||
frame: { x: 1, y: 115, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'j': {
|
||||
frame: { x: 37, y: 115, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'k': {
|
||||
frame: { x: 73, y: 115, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'l': {
|
||||
frame: { x: 1, y: 134, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'm': {
|
||||
frame: { x: 37, y: 134, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'n': {
|
||||
frame: { x: 73, y: 134, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'o': {
|
||||
frame: { x: 1, y: 153, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'p': {
|
||||
frame: { x: 37, y: 153, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'q': {
|
||||
frame: { x: 73, y: 153, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'r_blocked': {
|
||||
frame: { x: 1, y: 172, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'r_door': {
|
||||
frame: { x: 37, y: 172, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
'x': {
|
||||
frame: { x: 73, y: 172, w: 34, h: 17 },
|
||||
rotated: false,
|
||||
trimmed: false,
|
||||
spriteSourceSize: { x: 0, y: 0, w: 34, h: 17 },
|
||||
sourceSize: { w: 34, h: 17 },
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
app: 'https://www.codeandweb.com/texturepacker',
|
||||
version: '1.0',
|
||||
image: 'tiles.png',
|
||||
format: 'RGBA8888',
|
||||
size: { w: 108, h: 190 },
|
||||
scale: '1',
|
||||
smartupdate:
|
||||
'$TexturePacker:SmartUpdate:6d0f8373580629749f786a0b0f6c6bb9:96dff9df69bdc6938cf02f254bbe028b:accbe1e7e294ded8391337fc1c446319$',
|
||||
},
|
||||
};
|
@ -5,14 +5,14 @@ export const getScreenPositionForTile = (x: number, y: number): [number , number
|
||||
let positionX = (x * TILE_SIZE / 2) - (y * TILE_SIZE / 2);
|
||||
const positionY = (x * TILE_SIZE / 4) + (y * TILE_SIZE / 4);
|
||||
|
||||
positionX = positionX + 1024; // center the map in the canvas
|
||||
positionX = positionX + 1600; // center the map in the canvas
|
||||
|
||||
return [ positionX, positionY ];
|
||||
}
|
||||
|
||||
export const getTileFromScreenPosition = (x: number, y: number): [number, number] =>
|
||||
{
|
||||
const translatedX = x - 1024; // after centering translation
|
||||
const translatedX = x - 1600; // after centering translation
|
||||
|
||||
const realX = ((translatedX /(TILE_SIZE / 2)) + (y / (TILE_SIZE / 4))) / 2;
|
||||
const realY = ((y /(TILE_SIZE / 4)) - (translatedX / (TILE_SIZE / 2))) / 2;
|
||||
|
@ -4,8 +4,8 @@ import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from 'react-icons/f
|
||||
import { SendMessageComposer } from '../../../api';
|
||||
import { Base, Button, Column, ColumnProps, Flex, Grid } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
import { FloorplanEditor } from '../common/FloorplanEditor';
|
||||
import { useFloorplanEditorContext } from '../FloorplanEditorContext';
|
||||
import { FloorplanEditor } from '../common/FloorplanEditor';
|
||||
|
||||
export const FloorplanCanvasView: FC<ColumnProps> = props =>
|
||||
{
|
||||
@ -32,7 +32,7 @@ export const FloorplanCanvasView: FC<ColumnProps> = props =>
|
||||
|
||||
setOccupiedTilesReceived(true);
|
||||
|
||||
elementRef.current.scrollTo((FloorplanEditor.instance.view.width / 3), 0);
|
||||
elementRef.current.scrollTo((FloorplanEditor.instance.renderer.canvas.width / 3), 0);
|
||||
});
|
||||
|
||||
useMessageEvent<RoomEntryTileMessageEvent>(RoomEntryTileMessageEvent, event =>
|
||||
@ -86,6 +86,25 @@ export const FloorplanCanvasView: FC<ColumnProps> = props =>
|
||||
}
|
||||
}
|
||||
|
||||
const onPointerEvent = (event: PointerEvent) =>
|
||||
{
|
||||
event.preventDefault();
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case 'pointerout':
|
||||
case 'pointerup':
|
||||
FloorplanEditor.instance.onPointerRelease();
|
||||
break;
|
||||
case 'pointerdown':
|
||||
FloorplanEditor.instance.onPointerDown(event);
|
||||
break;
|
||||
case 'pointermove':
|
||||
FloorplanEditor.instance.onPointerMove(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return () =>
|
||||
@ -116,22 +135,46 @@ export const FloorplanCanvasView: FC<ColumnProps> = props =>
|
||||
SendMessageComposer(new GetRoomEntryTileMessageComposer());
|
||||
SendMessageComposer(new GetOccupiedTilesMessageComposer());
|
||||
|
||||
FloorplanEditor.instance.tilemapRenderer.interactive = true;
|
||||
const currentElement = elementRef.current;
|
||||
|
||||
if(!elementRef.current) return;
|
||||
if(!currentElement) return;
|
||||
|
||||
elementRef.current.appendChild(FloorplanEditor.instance.renderer.view);
|
||||
currentElement.appendChild(FloorplanEditor.instance.renderer.canvas);
|
||||
|
||||
currentElement.addEventListener('pointerup', onPointerEvent);
|
||||
|
||||
currentElement.addEventListener('pointerout', onPointerEvent);
|
||||
|
||||
currentElement.addEventListener('pointerdown', onPointerEvent);
|
||||
|
||||
currentElement.addEventListener('pointermove', onPointerEvent);
|
||||
|
||||
return () =>
|
||||
{
|
||||
if(currentElement)
|
||||
{
|
||||
currentElement.removeEventListener('pointerup', onPointerEvent);
|
||||
|
||||
currentElement.removeEventListener('pointerout', onPointerEvent);
|
||||
|
||||
currentElement.removeEventListener('pointerdown', onPointerEvent);
|
||||
|
||||
currentElement.removeEventListener('pointermove', onPointerEvent);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const isSmallScreen = () => window.innerWidth < 768;
|
||||
|
||||
return (
|
||||
<Column gap={ gap } { ...rest }>
|
||||
<Grid overflow="hidden" gap={ 1 }>
|
||||
<Column center size={ 1 }>
|
||||
<Column center size={ 1 } className="d-md-none">
|
||||
<Button className="d-md-none" onClick={ event => onClickArrowButton('left') }>
|
||||
<FaArrowLeft className="fa-icon" />
|
||||
</Button>
|
||||
</Column>
|
||||
<Column overflow="hidden" size={ 10 } gap={ 1 }>
|
||||
<Column overflow="hidden" size={ isSmallScreen() ? 10: 12 } gap={ 1 }>
|
||||
<Flex justifyContent="center" className="d-md-none">
|
||||
<Button shrink onClick={ event => onClickArrowButton('up') }>
|
||||
<FaArrowUp className="fa-icon" />
|
||||
@ -144,7 +187,7 @@ export const FloorplanCanvasView: FC<ColumnProps> = props =>
|
||||
</Button>
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column center size={ 1 }>
|
||||
<Column center size={ 1 } className="d-md-none">
|
||||
<Button className="d-md-none" onClick={ event => onClickArrowButton('right') }>
|
||||
<FaArrowRight className="fa-icon" />
|
||||
</Button>
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { FC, useState } from 'react';
|
||||
import { FaCaretLeft, FaCaretRight } from 'react-icons/fa';
|
||||
import ReactSlider from 'react-slider';
|
||||
import { LocalizeText } from '../../../api';
|
||||
import { Column, Flex, LayoutGridItem, Text } from '../../../common';
|
||||
import { Column, Flex, LayoutGridItem, Slider, Text } from '../../../common';
|
||||
import { COLORMAP, FloorAction } from '../common/Constants';
|
||||
import { FloorplanEditor } from '../common/FloorplanEditor';
|
||||
import { useFloorplanEditorContext } from '../FloorplanEditorContext';
|
||||
@ -157,8 +156,7 @@ export const FloorplanOptionsView: FC<{}> = props =>
|
||||
<Flex gap={ 1 }>
|
||||
<Column size={ 6 }>
|
||||
<Text bold>{ LocalizeText('floor.plan.editor.tile.height') }: { floorHeight }</Text>
|
||||
<ReactSlider
|
||||
className="nitro-slider"
|
||||
<Slider
|
||||
min={ MIN_FLOOR_HEIGHT }
|
||||
max={ MAX_FLOOR_HEIGHT }
|
||||
step={ 1 }
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Spritesheet } from '@pixi/spritesheet';
|
||||
import { Dict } from '@pixi/utils';
|
||||
import { Dict } from '../utils';
|
||||
import { GetTickerTime } from '../../pixi-proxy';
|
||||
import { GraphicAsset } from './GraphicAsset';
|
||||
import { GraphicAssetPalette } from './GraphicAssetPalette';
|
||||
|
@ -87,6 +87,7 @@ export class SocketConnection extends EventDispatcher implements IConnection
|
||||
|
||||
this._dataBuffer = new ArrayBuffer(0);
|
||||
this._socket = new WebSocket(socketUrl);
|
||||
this._socket.binaryType = 'arraybuffer';
|
||||
|
||||
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_OPENED, this.onOpen);
|
||||
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_CLOSED, this.onClose);
|
||||
@ -105,6 +106,8 @@ export class SocketConnection extends EventDispatcher implements IConnection
|
||||
|
||||
if(this._socket.readyState === WebSocket.OPEN) this._socket.close();
|
||||
|
||||
NitroLogger.error('Bye Bye connection.');
|
||||
|
||||
this._socket = null;
|
||||
}
|
||||
|
||||
@ -129,16 +132,9 @@ export class SocketConnection extends EventDispatcher implements IConnection
|
||||
|
||||
//this.dispatchConnectionEvent(SocketConnectionEvent.CONNECTION_MESSAGE, event);
|
||||
|
||||
const reader = new FileReader();
|
||||
this._dataBuffer = this.concatArrayBuffers(this._dataBuffer, event.data);
|
||||
|
||||
reader.readAsArrayBuffer(event.data);
|
||||
|
||||
reader.onloadend = () =>
|
||||
{
|
||||
this._dataBuffer = this.concatArrayBuffers(this._dataBuffer, (reader.result as ArrayBuffer));
|
||||
|
||||
this.processReceivedData();
|
||||
};
|
||||
this.processReceivedData();
|
||||
}
|
||||
|
||||
private dispatchConnectionEvent(type: string, event: Event): void
|
||||
|
@ -2,7 +2,6 @@ import '@pixi/canvas-display';
|
||||
import { BatchRenderer, extensions } from '@pixi/core';
|
||||
import { Extract } from '@pixi/extract';
|
||||
import '@pixi/graphics-extras';
|
||||
import { InteractionManager } from '@pixi/interaction';
|
||||
import { AppLoaderPlugin } from '@pixi/loaders';
|
||||
import '@pixi/math-extras';
|
||||
import '@pixi/mixin-cache-as-bitmap';
|
||||
@ -17,7 +16,6 @@ extensions.add(
|
||||
BatchRenderer,
|
||||
Extract,
|
||||
TilingSpriteRenderer,
|
||||
InteractionManager,
|
||||
SpritesheetLoader,
|
||||
AppLoaderPlugin,
|
||||
TickerPlugin);
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { Tilemap } from '@pixi/tilemap';
|
||||
|
||||
export class NitroTilemap extends Tilemap
|
||||
{
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
import { InteractionEvent } from '@pixi/interaction';
|
||||
|
||||
export class PixiInteractionEventProxy extends InteractionEvent
|
||||
{}
|
@ -1,4 +1,3 @@
|
||||
export { POINT_STRUCT_SIZE } from '@pixi/tilemap';
|
||||
export * from './adjustment-filter';
|
||||
export * from './CopyChannelFilter';
|
||||
export * from './GetTicker';
|
||||
@ -16,9 +15,7 @@ export * from './NitroRenderTexture';
|
||||
export * from './NitroSprite';
|
||||
export * from './NitroSpritesheet';
|
||||
export * from './NitroTexture';
|
||||
export * from './NitroTilemap';
|
||||
export * from './PaletteMapFilter';
|
||||
export * from './PixiApplicationProxy';
|
||||
export * from './PixiInteractionEventProxy';
|
||||
export * from './RoomTextureUtils';
|
||||
export * from './TextureUtils';
|
||||
|
Loading…
x
Reference in New Issue
Block a user