add renderer for small-pixels overlay
This commit is contained in:
parent
7a15fa556b
commit
47b4db2602
|
@ -23,6 +23,7 @@ import {
|
|||
renderPlaceholder,
|
||||
renderPotatoPlaceholder,
|
||||
renderOverlay,
|
||||
renderSmallPOverlay,
|
||||
} from './render2Delements';
|
||||
import PixelPainterControls from '../controls/PixelPainterControls';
|
||||
|
||||
|
@ -273,7 +274,6 @@ class Renderer2D extends Renderer {
|
|||
|
||||
const [x, y] = getPixelFromChunkOffset(i, j, offset, canvasSize);
|
||||
|
||||
// TODO centerChunk is scaled!
|
||||
const [canX, canY] = this.centerChunk
|
||||
.map((z) => (z + 0.5) * TILE_SIZE - canvasSize / 2);
|
||||
const { width: canvasWidth, height: canvasHeight } = this.canvas;
|
||||
|
@ -423,11 +423,13 @@ class Renderer2D extends Renderer {
|
|||
}
|
||||
context.restore();
|
||||
// TODO conditions
|
||||
if (false) {
|
||||
renderOverlay(
|
||||
this.canvas, chunkPosition, canvasSize, scale,
|
||||
state, this.canvas, chunkPosition, scale,
|
||||
this.tiledScale, this.scaleThreshold,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
@ -552,6 +554,11 @@ class Renderer2D extends Renderer {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO conditions
|
||||
if (viewscale >= 5) {
|
||||
renderSmallPOverlay(viewport, _view, viewscale);
|
||||
}
|
||||
|
||||
if (showGrid && viewscale >= 8) {
|
||||
renderGrid(state, viewport, _view, viewscale, isLightGrid);
|
||||
}
|
||||
|
|
|
@ -19,11 +19,46 @@ class Template {
|
|||
height;
|
||||
// if image is loaded
|
||||
ready = false;
|
||||
// small pixels image
|
||||
#imageSmall;
|
||||
|
||||
constructor(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() {
|
||||
return canvasToBuffer(this.image);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,7 @@ export function renderPotatoPlaceholder(
|
|||
) {
|
||||
const viewportCtx = $viewport.getContext('2d');
|
||||
|
||||
const { hover } = state.canvas;
|
||||
const { palette, selectedColor } = state.canvas;
|
||||
const { palette, selectedColor, hover } = state.canvas;
|
||||
|
||||
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
|
||||
*/
|
||||
export function renderOverlay(
|
||||
state,
|
||||
$canvas,
|
||||
centerChunk,
|
||||
canvasSize,
|
||||
scale,
|
||||
tiledScale,
|
||||
scaleThreshold,
|
||||
) {
|
||||
const { canvasSize } = state.canvas;
|
||||
// world coordinates of center of center chunk
|
||||
const [x, y] = centerChunk
|
||||
.map((z) => z * TILE_SIZE / tiledScale
|
||||
|
@ -138,6 +138,7 @@ export function renderOverlay(
|
|||
for (const template of templates) {
|
||||
const image = templateLoader.getTemplateSync(template.imageId);
|
||||
if (!image) continue;
|
||||
|
||||
context.drawImage(image,
|
||||
template.x - x + width / 2 / offscreenScale,
|
||||
template.y - y + height / 2 / offscreenScale,
|
||||
|
@ -145,3 +146,38 @@ export function renderOverlay(
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
const topX = x - horizontalRadius;
|
||||
const topY = y - verticalRadius;
|
||||
|
|
Loading…
Reference in New Issue
Block a user