Update for production.
22
Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Étape 1 : Build
|
||||||
|
FROM node:24-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM node:24-alpine AS runner
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
CMD ["serve", "-s", "build", "-l", "5000"]
|
||||||
847
package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"eslint-plugin-react-hooks": "^5.2.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.20",
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.3.0",
|
||||||
|
"serve": "^14.2.5",
|
||||||
"typescript": "~5.8.3",
|
"typescript": "~5.8.3",
|
||||||
"typescript-eslint": "^8.35.1",
|
"typescript-eslint": "^8.35.1",
|
||||||
"vite": "^7.0.4"
|
"vite": "^7.0.4"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
|
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 172 B |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 140 B |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
|
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 272 B |
22
src/App.tsx
@@ -95,53 +95,53 @@ function App() {
|
|||||||
<div className="div-hammer-container">
|
<div className="div-hammer-container">
|
||||||
<div className="tools">
|
<div className="tools">
|
||||||
|
|
||||||
<button onClick={() => inputFileMap.current?.click()} ref={button_import_map}><img src="/src/assets/images/import.png" alt="import" />
|
<button onClick={() => inputFileMap.current?.click()} ref={button_import_map}><img src="/assets/images/import.png" alt="import" />
|
||||||
<span>Import Map (I)</span>
|
<span>Import Map (I)</span>
|
||||||
<input type="file" id="inputFileMap" ref={inputFileMap} onChange={handleLoadMap} className="nodisplay" accept=".tmpx" />
|
<input type="file" id="inputFileMap" ref={inputFileMap} onChange={handleLoadMap} className="nodisplay" accept=".tmpx" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={() => { hammerRef.current && hammerRef.current.mapToJson() }}>
|
<button onClick={() => { hammerRef.current && hammerRef.current.mapToJson() }}>
|
||||||
<img src="/src/assets/images/save.png" alt="save" />
|
<img src="/assets/images/save.png" alt="save" />
|
||||||
<span>Save local copy (ctrl + s)</span>
|
<span>Save local copy (ctrl + s)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<button onClick={() => inputFileTilesheet.current?.click()} ref={button_set_tilesheet}>
|
<button onClick={() => inputFileTilesheet.current?.click()} ref={button_set_tilesheet}>
|
||||||
<img src="/src/assets/images/palet.png" alt="palet" />
|
<img src="/assets/images/palet.png" alt="palet" />
|
||||||
<span>Upload Tilesheet (U)</span>
|
<span>Upload Tilesheet (U)</span>
|
||||||
<input type="file" id="inputFileTS" ref={inputFileTilesheet} onChange={handleLoadTilesheet} className="nodisplay" accept="image/png, image/jpg, image/jpeg" />
|
<input type="file" id="inputFileTS" ref={inputFileTilesheet} onChange={handleLoadTilesheet} className="nodisplay" accept="image/png, image/jpg, image/jpeg" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={() => { if (hammerRef.current) { hammerRef.current.tool = "draw"; } }}>
|
<button onClick={() => { if (hammerRef.current) { hammerRef.current.heditor.tool = "draw"; } }}>
|
||||||
<img src="/src/assets/images/pen.png" alt="pen" />
|
<img src="/assets/images/pen.png" alt="pen" />
|
||||||
<span>Draw (D)</span>
|
<span>Draw (D)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={() => { if (hammerRef.current) { hammerRef.current.tool = "eraser"; } }}>
|
<button onClick={() => { if (hammerRef.current) { hammerRef.current.heditor.tool = "eraser"; } }}>
|
||||||
<img src="/src/assets/images/erase.png" alt="erase" />
|
<img src="/assets/images/erase.png" alt="erase" />
|
||||||
<span>Erase (E)</span>
|
<span>Erase (E)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button>
|
<button>
|
||||||
<img src="/src/assets/images/bucket.png" alt="bucket" />
|
<img src="/assets/images/bucket.png" alt="bucket" />
|
||||||
<span>Bucket (B)</span>
|
<span>Bucket (B)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button>
|
<button>
|
||||||
<img src="/src/assets/images/rect.png" alt="rect" />
|
<img src="/assets/images/rect.png" alt="rect" />
|
||||||
<span>Rectangle (R)</span>
|
<span>Rectangle (R)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button>
|
<button>
|
||||||
<img src="/src/assets/images/measure.png" alt="measure" />
|
<img src="/assets/images/measure.png" alt="measure" />
|
||||||
<span>Measure (M)</span>
|
<span>Measure (M)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<button>
|
<button>
|
||||||
<img src="/src/assets/images/center.png" alt="center" onClick={() => hammerRef.current && hammerRef.current.centerView()} />
|
<img src="/assets/images/center.png" alt="center" onClick={() => hammerRef.current && hammerRef.current.hcanvas.centerView()} />
|
||||||
<span>Center view (C)</span>
|
<span>Center view (C)</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class Hammer {
|
|||||||
|
|
||||||
// ? Load de la tile empty
|
// ? Load de la tile empty
|
||||||
const imgemp = new Image();
|
const imgemp = new Image();
|
||||||
imgemp.src = "/src/assets/images/missing_texture.png";
|
imgemp.src = "/assets/images/missing_texture.png";
|
||||||
|
|
||||||
imgemp.onload = async () => {
|
imgemp.onload = async () => {
|
||||||
this.emptyTile = new Tile(0, 0, imgemp);
|
this.emptyTile = new Tile(0, 0, imgemp);
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ canvas {
|
|||||||
position: relative;
|
position: relative;
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
background: url(/src/assets/images/bg.png);
|
background: url( /assets/images/bg.png);
|
||||||
background-size: 16px;
|
background-size: 16px;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|||||||