add renderer for small-pixels overlay
This commit is contained in:
parent
7a15fa556b
commit
47b4db2602
|
@ -23,6 +23,7 @@ import {
|
||||||
renderPlaceholder,
|
renderPlaceholder,
|
||||||
renderPotatoPlaceholder,
|
renderPotatoPlaceholder,
|
||||||
renderOverlay,
|
renderOverlay,
|
||||||
|
renderSmallPOverlay,
|
||||||
} from './render2Delements';
|
} from './render2Delements';
|
||||||
import PixelPainterControls from '../controls/PixelPainterControls';
|
import PixelPainterControls from '../controls/PixelPainterControls';
|
||||||
|
|
||||||
|
@ -273,7 +274,6 @@ class Renderer2D extends Renderer {
|
||||||
|
|
||||||
const [x, y] = getPixelFromChunkOffset(i, j, offset, canvasSize);
|
const [x, y] = getPixelFromChunkOffset(i, j, offset, canvasSize);
|
||||||
|
|
||||||
// TODO centerChunk is scaled!
|
|
||||||
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 { width: canvasWidth, height: canvasHeight } = this.canvas;
|
const { width: canvasWidth, height: canvasHeight } = this.canvas;
|
||||||
|
@ -423,10 +423,12 @@ class Renderer2D extends Renderer {
|
||||||
}
|
}
|
||||||
context.restore();
|
context.restore();
|
||||||
// TODO conditions
|
// TODO conditions
|
||||||
renderOverlay(
|
if (false) {
|
||||||
this.canvas, chunkPosition, canvasSize, scale,
|
renderOverlay(
|
||||||
this.tiledScale, this.scaleThreshold,
|
state, this.canvas, chunkPosition, scale,
|
||||||
);
|
this.tiledScale, this.scaleThreshold,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -552,6 +554,11 @@ class Renderer2D extends Renderer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO conditions
|
||||||
|
if (viewscale >= 5) {
|
||||||
|
renderSmallPOverlay(viewport, _view, viewscale);
|
||||||
|
}
|
||||||
|
|
||||||
if (showGrid && viewscale >= 8) {
|
if (showGrid && viewscale >= 8) {
|
||||||
renderGrid(state, viewport, _view, viewscale, isLightGrid);
|
renderGrid(state, viewport, _view, viewscale, isLightGrid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,46 @@ class Template {
|
||||||
height;
|
height;
|
||||||
// if image is loaded
|
// if image is loaded
|
||||||
ready = false;
|
ready = false;
|
||||||
|
// small pixels image
|
||||||
|
#imageSmall;
|
||||||
|
|
||||||
constructor(imageId) {
|
constructor(imageId) {
|
||||||
this.id = imageId;
|
this.id = imageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get imageSmall() {
|
||||||
|
if (!this.#imageSmall) {
|
||||||
|
const imgData = this.image.getContext('2d').getImageData(
|
||||||
|
0, 0, this.width, this.height,
|
||||||
|
);
|
||||||
|
const imageSmall = document.createElement('canvas');
|
||||||
|
imageSmall.width = this.width * 3;
|
||||||
|
imageSmall.height = this.height * 3;
|
||||||
|
const targetContext = imageSmall.getContext('2d');
|
||||||
|
const targetData = targetContext.getImageData(
|
||||||
|
0, 0, imageSmall.width, imageSmall.height,
|
||||||
|
);
|
||||||
|
|
||||||
|
let c = 0;
|
||||||
|
let o = targetData.width * 4 + 4;
|
||||||
|
while (c < imgData.data.length) {
|
||||||
|
for (let r = 0; r < imgData.width; r += 1) {
|
||||||
|
targetData.data[o] = imgData.data[c];
|
||||||
|
targetData.data[++o] = imgData.data[++c];
|
||||||
|
targetData.data[++o] = imgData.data[++c];
|
||||||
|
targetData.data[++o] = imgData.data[++c];
|
||||||
|
o += 1 + 2 * 4;
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
o += targetData.width * 4 * 2;
|
||||||
|
}
|
||||||
|
targetContext.putImageData(targetData, 0, 0);
|
||||||
|
this.#imageSmall = imageSmall;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.#imageSmall;
|
||||||
|
}
|
||||||
|
|
||||||
async arrayBuffer() {
|
async arrayBuffer() {
|
||||||
return canvasToBuffer(this.image);
|
return canvasToBuffer(this.image);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,7 @@ export function renderPotatoPlaceholder(
|
||||||
) {
|
) {
|
||||||
const viewportCtx = $viewport.getContext('2d');
|
const viewportCtx = $viewport.getContext('2d');
|
||||||
|
|
||||||
const { hover } = state.canvas;
|
const { palette, selectedColor, hover } = state.canvas;
|
||||||
const { palette, selectedColor } = state.canvas;
|
|
||||||
|
|
||||||
const [sx, sy] = worldToScreen(view, scale, $viewport, hover);
|
const [sx, sy] = worldToScreen(view, scale, $viewport, hover);
|
||||||
|
|
||||||
|
@ -107,13 +106,14 @@ export function renderGrid(
|
||||||
* Overlay draws onto offscreen canvas, so its doing weirder math
|
* Overlay draws onto offscreen canvas, so its doing weirder math
|
||||||
*/
|
*/
|
||||||
export function renderOverlay(
|
export function renderOverlay(
|
||||||
|
state,
|
||||||
$canvas,
|
$canvas,
|
||||||
centerChunk,
|
centerChunk,
|
||||||
canvasSize,
|
|
||||||
scale,
|
scale,
|
||||||
tiledScale,
|
tiledScale,
|
||||||
scaleThreshold,
|
scaleThreshold,
|
||||||
) {
|
) {
|
||||||
|
const { canvasSize } = state.canvas;
|
||||||
// world coordinates of center of center chunk
|
// world coordinates of center of center chunk
|
||||||
const [x, y] = centerChunk
|
const [x, y] = centerChunk
|
||||||
.map((z) => z * TILE_SIZE / tiledScale
|
.map((z) => z * TILE_SIZE / tiledScale
|
||||||
|
@ -138,6 +138,7 @@ export function renderOverlay(
|
||||||
for (const template of templates) {
|
for (const template of templates) {
|
||||||
const image = templateLoader.getTemplateSync(template.imageId);
|
const image = templateLoader.getTemplateSync(template.imageId);
|
||||||
if (!image) continue;
|
if (!image) continue;
|
||||||
|
|
||||||
context.drawImage(image,
|
context.drawImage(image,
|
||||||
template.x - x + width / 2 / offscreenScale,
|
template.x - x + width / 2 / offscreenScale,
|
||||||
template.y - y + height / 2 / offscreenScale,
|
template.y - y + height / 2 / offscreenScale,
|
||||||
|
@ -145,3 +146,38 @@ export function renderOverlay(
|
||||||
}
|
}
|
||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Small pixel overlay draws into viewport, because it needs
|
||||||
|
* high scale values
|
||||||
|
*/
|
||||||
|
export function renderSmallPOverlay(
|
||||||
|
$viewport,
|
||||||
|
view,
|
||||||
|
scale,
|
||||||
|
) {
|
||||||
|
const [x, y] = view;
|
||||||
|
const { width, height } = $viewport;
|
||||||
|
const horizontalRadius = width / 2 / scale;
|
||||||
|
const verticalRadius = height / 2 / scale;
|
||||||
|
const templates = templateLoader.getTemplatesInView(
|
||||||
|
x, y, horizontalRadius, verticalRadius,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!templates.length) return;
|
||||||
|
const context = $viewport.getContext('2d');
|
||||||
|
if (!context) return;
|
||||||
|
|
||||||
|
const relScale = scale / 3;
|
||||||
|
context.save();
|
||||||
|
context.scale(relScale, relScale);
|
||||||
|
for (const template of templates) {
|
||||||
|
const image = templateLoader.getSmallTemplateSync(template.imageId);
|
||||||
|
if (!image) continue;
|
||||||
|
context.drawImage(image,
|
||||||
|
(template.x - x) * 3 + width / 2 / relScale,
|
||||||
|
(template.y - y) * 3 + height / 2 / relScale,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,19 @@ class TemplateLoader {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSmallTemplateSync(id) {
|
||||||
|
if (!this.ready) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const template = this.#templates.get(id);
|
||||||
|
if (template) {
|
||||||
|
return template.imageSmall;
|
||||||
|
}
|
||||||
|
// TODO some store action when available
|
||||||
|
this.loadExistingTemplate(id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
getTemplatesInView(x, y, horizontalRadius, verticalRadius) {
|
getTemplatesInView(x, y, horizontalRadius, verticalRadius) {
|
||||||
const topX = x - horizontalRadius;
|
const topX = x - horizontalRadius;
|
||||||
const topY = y - verticalRadius;
|
const topY = y - verticalRadius;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user