Skip to content

Commit

Permalink
feat(web): improve rendering performance of maps
Browse files Browse the repository at this point in the history
  • Loading branch information
fallenoak committed Dec 2, 2023
1 parent e8b6a74 commit 7faedb2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 21 deletions.
25 changes: 23 additions & 2 deletions packages/spelunker-web/src/components/core/GameMap/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'leaflet/dist/leaflet.css';
import { Box } from '../';

import styles from './index.styl';
import {drawBlp, loadBlp} from "../../../utils/blp";

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 16

`../../../utils/blp` import should occur before import of `./index.styl`

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 16

A space is required after '{'

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 16

A space is required before '}'

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 18

`../../../utils/blp` import should occur before import of `./index.styl`

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 18

A space is required after '{'

Check failure on line 11 in packages/spelunker-web/src/components/core/GameMap/index.jsx

View workflow job for this annotation

GitHub Actions / Node 18

A space is required before '}'

const CHUNK_SIZE = 33.3333;
const TILE_INDEX = {};
Expand All @@ -32,13 +33,33 @@ const loadTileIndex = async (tileDirectory) => {
TILE_INDEX[tileDirectory] = tileIndex;
};

const loadTile = async (tileUrl, tile, done) => {
const blp = await loadBlp(tileUrl);

if (!blp) {
done(new Error('invalid blp'), tile);
return;
}

drawBlp(blp, tile);
done(undefined, tile);
};

class MinimapTileLayer extends TileLayer {
createTile(coords, done) {
const tile = document.createElement('canvas');
const tileUrl = this.getTileUrl(coords);
loadTile(tileUrl, tile, done);

return tile;
}

getTileUrl({ x, y }) {
const tx = 32 + x;
const ty = 32 + y;

// TODO use real url
const unknownTileUrl = `${process.env.PIPELINE_URI}/files/textures/minimap/unknown_${tx}_${ty}`;
const unknownTileUrl = `${process.env.DATA_URI}/textures/minimap/unknown_${tx}_${ty}.blp`;

const tileDirectory = this._url;
if (!tileDirectory) {
Expand All @@ -55,7 +76,7 @@ class MinimapTileLayer extends TileLayer {
return unknownTileUrl;
}

return `${process.env.PIPELINE_URI}/files/textures/minimap/${contentPath}.png`;
return `${process.env.DATA_URI}/textures/minimap/${contentPath}`;
}
}

Expand Down
32 changes: 13 additions & 19 deletions packages/spelunker-web/src/components/images/GameImage/index.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
import React, { useEffect, useRef } from 'react';
import { Blp, BLP_IMAGE_FORMAT } from '@wowserhq/format';
import classNames from 'classnames';

import { loadBlp, drawBlp } from '../../../utils/blp';
import { toPipelinePath } from '../../../utils/pipeline';

import styles from './index.styl';

const loadBlp = async (canvas, src) => {
const blpResponse = await fetch(src);
const blpData = await blpResponse.arrayBuffer();
const blp = new Blp();
blp.load(new Uint8Array(blpData));

const image = blp.getImage(0, BLP_IMAGE_FORMAT.IMAGE_RGBA8888);
const imageData = new ImageData(new Uint8ClampedArray(image.data), image.width, image.height);

canvas.width = image.width;
canvas.height = image.height;

const context = canvas.getContext('2d');
context.putImageData(imageData, 0, 0);
};

const GameImageBackground = (props) => {
const canvasRef = useRef();

useEffect(() => {
const load = async (src, canvas) => {
const blp = await loadBlp(src);
drawBlp(blp, canvas);
};

if (canvasRef.current) {
loadBlp(canvasRef.current, props.src);
load(props.src, canvasRef.current);
}
}, [props.src]);

Expand All @@ -50,8 +39,13 @@ const GameImageElement = (props) => {
const canvasRef = useRef();

useEffect(() => {
const load = async (src, canvas) => {
const blp = await loadBlp(src);
drawBlp(blp, canvas);
};

if (canvasRef.current) {
loadBlp(canvasRef.current, props.src);
load(props.src, canvasRef.current);
}
}, [props.src]);

Expand Down
27 changes: 27 additions & 0 deletions packages/spelunker-web/src/utils/blp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Blp, BLP_IMAGE_FORMAT } from "@wowserhq/format";

const drawBlp = (blp, canvas, x = 0, y = 0) => {
const image = blp.getImage(0, BLP_IMAGE_FORMAT.IMAGE_RGBA8888);
const imageData = new ImageData(new Uint8ClampedArray(image.data), image.width, image.height);

canvas.width = image.width;
canvas.height = image.height;

const context = canvas.getContext('2d');
context.putImageData(imageData, x, y);
};

const loadBlp = async (src) => {
const blpResponse = await fetch(src);
if (!blpResponse.ok) {
return null;
}

const blpData = await blpResponse.arrayBuffer();
const blp = new Blp();
blp.load(new Uint8Array(blpData));

return blp;
};

export { loadBlp, drawBlp };

0 comments on commit 7faedb2

Please sign in to comment.