stricter window position check

notice screen size changes
This commit is contained in:
HF 2022-09-28 11:44:02 +02:00
parent 40b7bbead7
commit d835a93e8c
3 changed files with 54 additions and 49 deletions

View File

@ -106,7 +106,6 @@ persistStore(store, {}, () => {
// listen for resize // listen for resize
// //
function onWindowResize() { function onWindowResize() {
console.log('WINDOW RESIZED');
store.dispatch(windowResize()); store.dispatch(windowResize());
} }
window.addEventListener('resize', onWindowResize); window.addEventListener('resize', onWindowResize);

View File

@ -81,6 +81,7 @@ function correctPositions(state) {
const { windows: newWindows, positions } = state; const { windows: newWindows, positions } = state;
const xMax = width - SCREEN_MARGIN_EW; const xMax = width - SCREEN_MARGIN_EW;
const yMax = height - SCREEN_MARGIN_S; const yMax = height - SCREEN_MARGIN_S;
const yMin = 0;
let modified = false; let modified = false;
const newPositions = {}; const newPositions = {};
@ -92,12 +93,14 @@ function correctPositions(state) {
width: winWidth, width: winWidth,
height: winHeight, height: winHeight,
} = positions[id]; } = positions[id];
const xMin = SCREEN_MARGIN_EW - winWidth;
if (xPos > xMax || yPos > yMax if (xPos > xMax || yPos > yMax
|| xPos < xMin || yPos < yMin
|| width > winWidth || height > winHeight) { || width > winWidth || height > winHeight) {
modified = true; modified = true;
newPositions[id] = { newPositions[id] = {
xPos: Math.min(xMax, xPos), xPos: clamp(xPos, xMin, xMax),
yPos: Math.min(yMax, yPos), yPos: clamp(yPos, yMin, yMax),
width: Math.min(winWidth, width - SCREEN_MARGIN_S), width: Math.min(winWidth, width - SCREEN_MARGIN_S),
height: Math.min(winHeight, height - SCREEN_MARGIN_S), height: Math.min(winHeight, height - SCREEN_MARGIN_S),
z: positions[id].z, z: positions[id].z,

View File

@ -18,21 +18,9 @@ import {
} from './render2Delements'; } from './render2Delements';
import PixelPainterControls from '../controls/PixelPainterControls'; import PixelPainterControls from '../controls/PixelPainterControls';
import ChunkLoader from './ChunkLoader2D'; import ChunkLoader from './ChunkLoader2D';
import pixelNotify from './PixelNotify'; import pixelNotify from './PixelNotify';
// dimensions of offscreen canvas NOT whole canvas
// eslint-disable-next-line max-len
const CANVAS_WIDTH = 2 * Math.ceil(window.screen.width / 2) + TILE_ZOOM_LEVEL * TILE_SIZE;
// eslint-disable-next-line max-len
const CANVAS_HEIGHT = 2 * Math.ceil(window.screen.height / 2) + TILE_ZOOM_LEVEL * TILE_SIZE;
const SCALE_THREASHOLD = Math.min(
CANVAS_WIDTH / TILE_SIZE / 3,
CANVAS_HEIGHT / TILE_SIZE / 3,
);
class Renderer { class Renderer {
is3D = false; is3D = false;
// //
@ -61,6 +49,7 @@ class Renderer {
this.canvasMaxTiledZoom = 0; this.canvasMaxTiledZoom = 0;
this.historicalCanvasMaxTiledZoom = 0; this.historicalCanvasMaxTiledZoom = 0;
this.hover = false; this.hover = false;
this.scaleThreshold = 1;
//-- //--
this.forceNextRender = true; this.forceNextRender = true;
this.forceNextSubrender = true; this.forceNextSubrender = true;
@ -68,29 +57,26 @@ class Renderer {
this.oldHistoricalTime = null; this.oldHistoricalTime = null;
//-- //--
const viewport = document.createElement('canvas'); const viewport = document.createElement('canvas');
viewport.width = window.innerWidth;
viewport.height = window.innerHeight;
viewport.className = 'viewport'; viewport.className = 'viewport';
this.viewport = viewport; this.viewport = viewport;
document.body.appendChild(this.viewport);
//--
this.resizeHandle = this.resizeHandle.bind(this);
window.addEventListener('resize', this.resizeHandle);
//-- //--
this.canvas = document.createElement('canvas'); this.canvas = document.createElement('canvas');
this.canvas.width = CANVAS_WIDTH; this.onWindowResize();
this.canvas.height = CANVAS_HEIGHT; document.body.appendChild(this.viewport);
//--
this.onWindowResize = this.onWindowResize.bind(this);
window.addEventListener('resize', this.onWindowResize);
const context = this.canvas.getContext('2d'); const context = this.canvas.getContext('2d');
context.fillStyle = '#000000'; context.fillStyle = '#000000';
context.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); context.fillRect(0, 0, this.canvas.width, this.canvas.height);
//-- //--
this.setStore(store); this.setStore(store);
} }
destructor() { destructor() {
this.controls.dispose(); this.controls.dispose();
window.removeEventListener('resize', this.resizeHandle); window.removeEventListener('resize', this.onWindowResize);
this.viewport.remove(); this.viewport.remove();
} }
@ -102,10 +88,26 @@ class Renderer {
return this.chunkLoader.getAllChunks(); return this.chunkLoader.getAllChunks();
} }
resizeHandle() { onWindowResize() {
console.log('WIN RESIZED', window.innerWidth, window.innerHeight);
this.viewport.width = window.innerWidth; this.viewport.width = window.innerWidth;
this.viewport.height = window.innerHeight; this.viewport.height = window.innerHeight;
// dimensions of offscreen canvas NOT whole canvas
const canvasWidth = 2 * Math.ceil(window.screen.width / 2)
+ TILE_ZOOM_LEVEL * TILE_SIZE;
const canvasHeight = 2 * Math.ceil(window.screen.height / 2)
+ TILE_ZOOM_LEVEL * TILE_SIZE;
if (this.canvas.width !== canvasWidth
|| this.canvas.height !== canvasHeight
) {
// eslint-disable-next-line no-console
console.log(`Noticed screen: ${canvasWidth} / ${canvasHeight}`);
this.canvas.width = canvasWidth;
this.canvas.height = canvasHeight;
this.scaleThreshold = Math.min(
canvasWidth / TILE_SIZE / 3,
canvasHeight / TILE_SIZE / 3,
);
}
this.forceNextRender = true; this.forceNextRender = true;
} }
@ -199,7 +201,7 @@ class Renderer {
this.relScale = relScale; this.relScale = relScale;
this.updateView(state); this.updateView(state);
if (prevScale === null if (prevScale === null
|| viewscale < SCALE_THREASHOLD || prevScale < SCALE_THREASHOLD) { || viewscale < this.scaleThreshold || prevScale < this.scaleThreshold) {
this.forceNextRender = true; this.forceNextRender = true;
} else { } else {
this.forceNextSubrender = true; this.forceNextSubrender = true;
@ -249,7 +251,7 @@ class Renderer {
this.chunkLoader.getPixelUpdate(i, j, offset, color); this.chunkLoader.getPixelUpdate(i, j, offset, color);
if (scale < 0.8 || isHistoricalView) return; if (scale < 0.8 || isHistoricalView) return;
const scaleM = (scale > SCALE_THREASHOLD) ? 1 : scale; const scaleM = (scale > this.scaleThreshold) ? 1 : scale;
const context = this.canvas.getContext('2d'); const context = this.canvas.getContext('2d');
if (!context) return; if (!context) return;
@ -258,10 +260,11 @@ class Renderer {
const [canX, canY] = this.centerChunk const [canX, canY] = this.centerChunk
.map((z) => (z + 0.5) * TILE_SIZE - canvasSize / 2); .map((z) => (z + 0.5) * TILE_SIZE - canvasSize / 2);
const px = ((x - canX) * scaleM) + (CANVAS_WIDTH / 2); const { width: canvasWidth, height: canvasHeight } = this.canvas;
const py = ((y - canY) * scaleM) + (CANVAS_HEIGHT / 2); const px = ((x - canX) * scaleM) + (canvasWidth / 2);
const py = ((y - canY) * scaleM) + (canvasHeight / 2);
// if not part of our current canvas, do not render // if not part of our current canvas, do not render
if (px < 0 || px >= CANVAS_WIDTH || py < 0 || py >= CANVAS_HEIGHT) return; if (px < 0 || px >= canvasWidth || py < 0 || py >= canvasHeight) return;
context.fillStyle = palette.colors[color]; context.fillStyle = palette.colors[color];
context.fillRect(px, py, scaleM, scaleM); context.fillRect(px, py, scaleM, scaleM);
@ -337,7 +340,7 @@ class Renderer {
const CHUNK_RENDER_RADIUS_Y = Math.ceil(height / TILE_SIZE / 2 / relScale); const CHUNK_RENDER_RADIUS_Y = Math.ceil(height / TILE_SIZE / 2 / relScale);
// If scale is so large that neighbouring chunks wouldn't fit in canvas, // If scale is so large that neighbouring chunks wouldn't fit in canvas,
// do scale = 1 and scale in render() // do scale = 1 and scale in render()
if (scale > SCALE_THREASHOLD) relScale = 1.0; if (scale > this.scaleThreshold) relScale = 1.0;
// scale // scale
context.save(); context.save();
context.fillStyle = '#C4C4C4'; context.fillStyle = '#C4C4C4';
@ -350,8 +353,8 @@ class Renderer {
touch = true; touch = true;
} }
const xOffset = CANVAS_WIDTH / 2 / relScale - TILE_SIZE / 2; const xOffset = this.canvas.width / 2 / relScale - TILE_SIZE / 2;
const yOffset = CANVAS_HEIGHT / 2 / relScale - TILE_SIZE / 2; const yOffset = this.canvas.height / 2 / relScale - TILE_SIZE / 2;
const [xc, yc] = chunkPosition; // center chunk const [xc, yc] = chunkPosition; // center chunk
// CLEAN margin // CLEAN margin
@ -494,24 +497,24 @@ class Renderer {
// If scale is so large that neighbouring chunks wouldn't fit in offscreen // If scale is so large that neighbouring chunks wouldn't fit in offscreen
// canvas, do scale = 1 in renderChunks and scale in render() // canvas, do scale = 1 in renderChunks and scale in render()
const canvasCenter = canvasSize / 2; const canvasCenter = canvasSize / 2;
if (viewscale > SCALE_THREASHOLD) { if (viewscale > this.scaleThreshold) {
viewportCtx.save(); viewportCtx.save();
viewportCtx.scale(viewscale, viewscale); viewportCtx.scale(viewscale, viewscale);
viewportCtx.drawImage( viewportCtx.drawImage(
this.canvas, this.canvas,
width / 2 / viewscale - CANVAS_WIDTH / 2 + ( width / 2 / viewscale - this.canvas.width / 2 + (
(cx + 0.5) * TILE_SIZE - canvasCenter - x), (cx + 0.5) * TILE_SIZE - canvasCenter - x),
height / 2 / viewscale - CANVAS_HEIGHT / 2 + ( height / 2 / viewscale - this.canvas.height / 2 + (
(cy + 0.5) * TILE_SIZE - canvasCenter - y), (cy + 0.5) * TILE_SIZE - canvasCenter - y),
); );
viewportCtx.restore(); viewportCtx.restore();
} else { } else {
viewportCtx.drawImage( viewportCtx.drawImage(
this.canvas, this.canvas,
Math.floor(width / 2 - CANVAS_WIDTH / 2 Math.floor(width / 2 - this.canvas.width / 2
+ ((cx + 0.5) * TILE_SIZE / this.tiledScale + ((cx + 0.5) * TILE_SIZE / this.tiledScale
- canvasCenter - x) * viewscale), - canvasCenter - x) * viewscale),
Math.floor(height / 2 - CANVAS_HEIGHT / 2 Math.floor(height / 2 - this.canvas.height / 2
+ ((cy + 0.5) * TILE_SIZE / this.tiledScale + ((cy + 0.5) * TILE_SIZE / this.tiledScale
- canvasCenter - y) * viewscale), - canvasCenter - y) * viewscale),
); );
@ -563,7 +566,7 @@ class Renderer {
context.imageSmoothingEnabled = true; context.imageSmoothingEnabled = true;
} }
const scale = (viewscale > SCALE_THREASHOLD) ? 1.0 : viewscale; const scale = (viewscale > this.scaleThreshold) ? 1.0 : viewscale;
// define how many chunks we will render // define how many chunks we will render
// don't render chunks outside of viewport // don't render chunks outside of viewport
const { width, height } = viewport; const { width, height } = viewport;
@ -574,7 +577,7 @@ class Renderer {
context.fillStyle = '#C4C4C4'; context.fillStyle = '#C4C4C4';
// clear canvas and do nothing if no time selected // clear canvas and do nothing if no time selected
if (!historicalDate || !historicalTime) { if (!historicalDate || !historicalTime) {
context.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); context.fillRect(0, 0, this.canvas.width, this.canvas.height);
context.restore(); context.restore();
return; return;
} }
@ -588,8 +591,8 @@ class Renderer {
touch = true; touch = true;
} }
const xOffset = CANVAS_WIDTH / 2 / scale - TILE_SIZE / 2; const xOffset = this.canvas.width / 2 / scale - TILE_SIZE / 2;
const yOffset = CANVAS_HEIGHT / 2 / scale - TILE_SIZE / 2; const yOffset = this.canvas.height / 2 / scale - TILE_SIZE / 2;
const [xc, yc] = chunkPosition; // center chunk const [xc, yc] = chunkPosition; // center chunk
// CLEAN margin // CLEAN margin
@ -701,24 +704,24 @@ class Renderer {
// If scale is so large that neighbouring chunks wouldn't fit in offscreen // If scale is so large that neighbouring chunks wouldn't fit in offscreen
// canvas, do scale = 1 in renderChunks and scale in render() // canvas, do scale = 1 in renderChunks and scale in render()
const canvasCenter = historicalCanvasSize / 2; const canvasCenter = historicalCanvasSize / 2;
if (viewscale > SCALE_THREASHOLD) { if (viewscale > this.scaleThreshold) {
viewportCtx.save(); viewportCtx.save();
viewportCtx.scale(viewscale, viewscale); viewportCtx.scale(viewscale, viewscale);
viewportCtx.drawImage( viewportCtx.drawImage(
this.canvas, this.canvas,
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
width / 2 / viewscale - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x), width / 2 / viewscale - this.canvas.width / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x),
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
height / 2 / viewscale - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y), height / 2 / viewscale - this.canvas.height / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y),
); );
viewportCtx.restore(); viewportCtx.restore();
} else { } else {
viewportCtx.drawImage( viewportCtx.drawImage(
this.canvas, this.canvas,
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
Math.floor(width / 2 - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x) * viewscale), Math.floor(width / 2 - this.canvas.width / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x) * viewscale),
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
Math.floor(height / 2 - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y) * viewscale), Math.floor(height / 2 - this.canvas.height / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y) * viewscale),
); );
} }