diff --git a/README.md b/README.md index a5d7ff8b..77bb095e 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ Note: Canvas specific configuartion like colors and cooldown is in `src/canvases.json` for all canvases. The CanvasSize is expected to be a power of 4 (4096, 16384, 65536,...) and not smaller than 256. bcd is base cooldown for unset pixels, pcd is cooldown for placing on top of others, cds is stacktime, req is the requirement to be allowed to set on canvas in total pixels placed. All the cooldown values are in ms. +If you want to add a new canvas, be sure that you additionally create `public/loading${canvasId}.png` and `public/assets3d/normal${canvasId}.jpg` and `public/assets3d/specular${canvasId}.jpg`, check out the existing ones to see what those files are for. + The default configuration values can be seen in `src/core/config.js` and for the canvases in `src/core/constats.js` ### Running diff --git a/public/loading.png b/public/loading0.png similarity index 100% rename from public/loading.png rename to public/loading0.png diff --git a/public/loading1.png b/public/loading1.png new file mode 100644 index 00000000..766589c3 Binary files /dev/null and b/public/loading1.png differ diff --git a/src/actions/index.js b/src/actions/index.js index 87d50d11..5ef5eb09 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -12,7 +12,7 @@ import type { Cell } from '../core/Cell'; import type { ColorIndex } from '../core/Palette'; import ProtocolClient from '../socket/ProtocolClient'; -import loadImage from '../ui/loadImage'; +import { loadImage } from '../ui/loadImage'; import { getColorIndexOfPixel, } from '../core/utils'; diff --git a/src/components/Globe.jsx b/src/components/Globe.jsx index 5f351e98..ebb48c1d 100644 --- a/src/components/Globe.jsx +++ b/src/components/Globe.jsx @@ -19,6 +19,7 @@ const Globe = () => (
(0, 0)
Double click on globe to go back.
+
Loading...
); diff --git a/src/components/globe.tcss b/src/components/globe.tcss index b0ed9b21..950f55ba 100644 --- a/src/components/globe.tcss +++ b/src/components/globe.tcss @@ -58,3 +58,21 @@ body { left: 16px; top: 16px } + +:global(#loading) { + font-size: 16px; + font-weight: bold; + position: absolute; + background-color: hsla(0,0%,89%,.8); + color: #4d4d4d; + text-align: center; + vertical-align: middle; + line-height: 36px; + width: auto; + height: 36px; + padding: 0 24px; + border: solid #000; + border-width: thin; + right: 16px; + top: 16px +} diff --git a/src/globe.js b/src/globe.js index f51b13e6..7f1894a7 100644 --- a/src/globe.js +++ b/src/globe.js @@ -114,6 +114,7 @@ document.addEventListener('DOMContentLoaded', () => { rotateToCoords(canvasSize, object, [x, y]); controls = createControls(); render(); + document.getElementById('loading').style.display = "none"; }, () => { // console.log(`${xhr.loaded} loaded`); }, () => { diff --git a/src/ui/ChunkRGB.js b/src/ui/ChunkRGB.js index 325e5144..ebf62054 100644 --- a/src/ui/ChunkRGB.js +++ b/src/ui/ChunkRGB.js @@ -3,16 +3,7 @@ import type { Cell } from '../core/Cell'; import type { Palette } from '../core/Palette'; -import { TILE_SIZE, TILE_LOADING_IMAGE } from '../core/constants'; - -import loadImage from './loadImage'; - - -export const loadingTile = { - url: TILE_LOADING_IMAGE, - img: null, -}; -loadImage(TILE_LOADING_IMAGE).then((img) => { loadingTile.img = img; }); +import { TILE_SIZE } from '../core/constants'; class ChunkRGB { @@ -69,8 +60,8 @@ class ChunkRGB { return; } } - if (loadingTile.img) { - ctx.drawImage(loadingTile.img, 0, 0); + if (loadingTiles.hasTiles) { + ctx.drawImage(loadingTiles.getTile(0), 0, 0); return; } else { ctx.fillStyle = this.palette.colors[2]; diff --git a/src/ui/Renderer.js b/src/ui/Renderer.js index 1040d022..6092cda9 100644 --- a/src/ui/Renderer.js +++ b/src/ui/Renderer.js @@ -19,7 +19,8 @@ import { renderPlaceholder, renderPotatoPlaceholder, } from './renderelements'; -import ChunkRGB, { loadingTile } from './ChunkRGB'; +import ChunkRGB from './ChunkRGB'; +import { loadingTiles } from './loadImage'; import pixelNotify from './PixelNotify'; @@ -205,8 +206,11 @@ class Renderer { if (chunk.ready) { context.drawImage(chunk.image, x, y); if (fetch) chunk.timestamp = curTime; - } else if (loadingTile.img) context.drawImage(loadingTile.img, x, y); - else context.fillRect(x, y, TILE_SIZE, TILE_SIZE); + } else if (loadingTiles.hasTiles) { + context.drawImage(loadingTiles.getTile(canvasId), x, y); + } else { + context.fillRect(x, y, TILE_SIZE, TILE_SIZE); + } } else { // we don't have that chunk if (fetch) { @@ -216,8 +220,11 @@ class Renderer { store.dispatch(fetchTile(canvasId, [tiledZoom, cx, cy])); } } - if (loadingTile.img) context.drawImage(loadingTile.img, x, y); - else context.fillRect(x, y, TILE_SIZE, TILE_SIZE); + if (loadingTiles.hasTiles) { + context.drawImage(loadingTiles.getTile(canvasId), x, y); + } else { + context.fillRect(x, y, TILE_SIZE, TILE_SIZE); + } } } } diff --git a/src/ui/loadImage.js b/src/ui/loadImage.js index 09ae5a24..00f82f28 100644 --- a/src/ui/loadImage.js +++ b/src/ui/loadImage.js @@ -1,6 +1,11 @@ /* @flow */ -function loadImage(url) { +/* + * general function for async loading images + * @param url url of image + * @return Promise + */ +export function loadImage(url) { return new Promise((resolve, reject) => { const img = new Image(); img.addEventListener('load', () => resolve(img)); @@ -11,4 +16,38 @@ function loadImage(url) { }); } -export default loadImage; +/* + * loading tiles that get temporarily shown till real tile is loaded + */ +class LoadingTiles { + tiles: Object; + hasTiles: boolean; + + constructor() { + this.hasTiles = false; + this.tiles = {}; + this.loadLoadingTile(0); + } + + getTile(canvasId: number) { + if (typeof this.tiles[canvasId] === 'undefined') { + this.loadLoadingTile(canvasId); + } + return this.tiles[canvasId] || this.tiles[0]; + } + + async loadLoadingTile(canvasId: number) { + if (this.tiles[canvasId] === null) { + return; + } + this.tiles[canvasId] = null; + const img = await loadImage(`./loading${canvasId}.png`); + this.tiles[canvasId] = img; + if (canvasId === 0) { + this.hasTiles = true; + } + } +} + + +export const loadingTiles = new LoadingTiles();