right shift -> place from historical view
This commit is contained in:
parent
e4a6171666
commit
2d0c31fac6
|
@ -37,7 +37,8 @@ const HelpModal = () => (
|
|||
<p className="modaltext">Drag mouse to move</p>
|
||||
<p className="modaltext">Scroll mouse wheel to zoom</p>
|
||||
<p className="modaltext">Click middle mouse button to current hovering color</p>
|
||||
<p className="modaltext">Hold shift for placing while moving mouse</p>
|
||||
<p className="modaltext">Hold left shift for placing while moving mouse</p>
|
||||
<p className="modaltext">Hold right shift for placing while moving mouse according to historical view</p>
|
||||
<p className="modaltext">Pinch to zoom (on touch devices)</p>
|
||||
<p className="modaltext">Pan to move (on touch devices)</p>
|
||||
<p className="modaltext">Click or tap to place a pixel</p>
|
||||
|
|
|
@ -61,8 +61,13 @@ class PixelPlainterControls {
|
|||
this.isMultiTab = false;
|
||||
// on touch: timeout to detect long-press
|
||||
this.tapTimeout = null;
|
||||
// if we are shift-hold-painting
|
||||
this.holdPainting = false;
|
||||
/*
|
||||
* if we are shift-hold-painting
|
||||
* 0: no
|
||||
* 1: left shift
|
||||
* 2: right shift
|
||||
*/
|
||||
this.holdPainting = 0;
|
||||
// if we are waiting before placeing pixel via holdPainting again
|
||||
this.coolDownDelta = false;
|
||||
|
||||
|
@ -162,14 +167,20 @@ class PixelPlainterControls {
|
|||
return null;
|
||||
}
|
||||
|
||||
static placePixel(store, renderer, cell) {
|
||||
/*
|
||||
* place pixel
|
||||
* either with given colorIndex or with selected color if none is given
|
||||
*/
|
||||
static placePixel(store, renderer, cell, colorIndex = null) {
|
||||
const state = store.getState();
|
||||
const { autoZoomIn } = state.gui;
|
||||
const {
|
||||
scale,
|
||||
isHistoricalView,
|
||||
selectedColor,
|
||||
} = state.canvas;
|
||||
const selectedColor = (colorIndex === null)
|
||||
? state.canvas.selectedColor
|
||||
: colorIndex;
|
||||
|
||||
if (isHistoricalView) return;
|
||||
|
||||
|
@ -393,16 +404,42 @@ class PixelPlainterControls {
|
|||
|| y < -maxCoords || y >= maxCoords
|
||||
) {
|
||||
if (hover) {
|
||||
store.dispatch(unsetHover(screenCoor));
|
||||
store.dispatch(unsetHover());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hover || hover[0] !== x || hover[1] !== y) {
|
||||
store.dispatch(setHover(screenCoor));
|
||||
/* shift placing */
|
||||
if (!this.coolDownDelta) {
|
||||
switch (this.holdPainting) {
|
||||
case 1: {
|
||||
/* left shift: from selected color */
|
||||
PixelPlainterControls.placePixel(
|
||||
store,
|
||||
this.renderer,
|
||||
screenCoor,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
/* right shift: from historical view */
|
||||
const colorIndex = this.renderer
|
||||
.getColorIndexOfPixel(x, y, true);
|
||||
if (colorIndex !== null) {
|
||||
PixelPlainterControls.placePixel(
|
||||
store,
|
||||
this.renderer,
|
||||
screenCoor,
|
||||
colorIndex,
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (this.holdPainting && !this.coolDownDelta) {
|
||||
PixelPlainterControls.placePixel(store, this.renderer, screenCoor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +449,7 @@ class PixelPlainterControls {
|
|||
viewport.style.cursor = 'auto';
|
||||
store.dispatch(unsetHover());
|
||||
store.dispatch(onViewFinishChange());
|
||||
this.holdPainting = false;
|
||||
this.holdPainting = 0;
|
||||
this.clearTabTimeout();
|
||||
}
|
||||
|
||||
|
@ -448,7 +485,7 @@ class PixelPlainterControls {
|
|||
switch (event.key) {
|
||||
case 'Shift':
|
||||
case 'CapsLock':
|
||||
this.holdPainting = false;
|
||||
this.holdPainting = 0;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
@ -496,19 +533,28 @@ class PixelPlainterControls {
|
|||
if (event.key === 'Control') {
|
||||
// ctrl
|
||||
const clrIndex = this.renderer.getColorIndexOfPixel(...hover);
|
||||
if (clrIndex !== null) {
|
||||
store.dispatch(selectColor(clrIndex));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
|
||||
// left shift
|
||||
this.holdPainting = true;
|
||||
this.holdPainting = 1;
|
||||
PixelPlainterControls.placePixel(store, this.renderer, hover);
|
||||
return;
|
||||
}
|
||||
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
|
||||
// right shift
|
||||
this.holdPainting = 2;
|
||||
const colorIndex = this.renderer
|
||||
.getColorIndexOfPixel(...hover, true);
|
||||
if (colorIndex !== null) {
|
||||
PixelPlainterControls.placePixel(
|
||||
store,
|
||||
this.renderer,
|
||||
hover,
|
||||
colorIndex,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -77,6 +77,46 @@ class ChunkLoader {
|
|||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get color of pixel in current historical view
|
||||
* @param x, y world coordiantes of pixel
|
||||
* @return ColorIndex or null if chunks not loaded or historical view not set
|
||||
*/
|
||||
getHistoricalIndexOfPixel(
|
||||
x: number,
|
||||
y: number,
|
||||
) {
|
||||
const state: State = this.store.getState();
|
||||
const { canvasSize, historicalDate, historicalTime } = state.canvas;
|
||||
if (!historicalDate) {
|
||||
return null;
|
||||
}
|
||||
const [cx, cy] = getChunkOfPixel(canvasSize, x, y);
|
||||
const px = getCellInsideChunk(canvasSize, [x, y]);
|
||||
const curTime = Date.now();
|
||||
|
||||
if (!historicalTime || historicalTime !== '0000') {
|
||||
// eslint-disable-next-line max-len
|
||||
const incrementialChunkKey = `${historicalDate}${historicalTime}:${cx}:${cy}`;
|
||||
const incrementialChunk = this.chunks.get(incrementialChunkKey);
|
||||
if (incrementialChunk) {
|
||||
const incrementialColor = incrementialChunk.getColorIndex(px);
|
||||
incrementialChunk.timestamp = curTime;
|
||||
if (incrementialColor !== null) {
|
||||
return incrementialColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const chunkKey = `${historicalDate}:${cx}:${cy}`;
|
||||
const chunk = this.chunks.get(chunkKey);
|
||||
if (!chunk) {
|
||||
return null;
|
||||
}
|
||||
chunk.timestamp = curTime;
|
||||
return chunk.getColorIndex(px);
|
||||
}
|
||||
|
||||
/*
|
||||
* preLoad chunks by generating them out of
|
||||
* available lower zoomlevel chunks
|
||||
|
|
|
@ -146,8 +146,10 @@ class Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
getColorIndexOfPixel(cx, cy) {
|
||||
return this.chunkLoader.getColorIndexOfPixel(cx, cy);
|
||||
getColorIndexOfPixel(cx, cy, historical: boolean = false) {
|
||||
return (historical)
|
||||
? this.chunkLoader.getHistoricalIndexOfPixel(cx, cy)
|
||||
: this.chunkLoader.getColorIndexOfPixel(cx, cy);
|
||||
}
|
||||
|
||||
updateScale(
|
||||
|
|
Loading…
Reference in New Issue
Block a user