You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.3 KiB
124 lines
4.3 KiB
import { freeCanvas, makeOffscreenBuffer } from "../../../core/buffer_utils";
|
|
import { globalConfig } from "../../../core/config";
|
|
import { Loader } from "../../../core/loader";
|
|
import { Vector } from "../../../core/vector";
|
|
import { MapChunkView } from "../../map_chunk_view";
|
|
import { THEME } from "../../theme";
|
|
import { BaseHUDPart } from "../base_hud_part";
|
|
|
|
/**
|
|
* Helper class which allows peaking through to the wires layer
|
|
*/
|
|
export class HUDLayerPreview extends BaseHUDPart {
|
|
initialize() {
|
|
this.initializeCanvas();
|
|
this.root.signals.aboutToDestruct.add(() => freeCanvas(this.canvas));
|
|
this.root.signals.resized.add(this.initializeCanvas, this);
|
|
this.previewOverlay = Loader.getSprite("sprites/wires/wires_preview.png");
|
|
}
|
|
|
|
/**
|
|
* (re) initializes the canvas
|
|
*/
|
|
initializeCanvas() {
|
|
if (this.canvas) {
|
|
freeCanvas(this.canvas);
|
|
delete this.canvas;
|
|
delete this.context;
|
|
}
|
|
|
|
// Compute how big the preview should be
|
|
this.previewSize = Math.round(
|
|
Math.min(1024, Math.min(this.root.gameWidth, this.root.gameHeight) * 0.8)
|
|
);
|
|
|
|
const [canvas, context] = makeOffscreenBuffer(this.previewSize, this.previewSize, {
|
|
smooth: true,
|
|
label: "layerPeeker",
|
|
reusable: true,
|
|
});
|
|
|
|
context.clearRect(0, 0, this.previewSize, this.previewSize);
|
|
this.canvas = canvas;
|
|
this.context = context;
|
|
}
|
|
|
|
/**
|
|
* Prepares the canvas to render at the given worldPos and the given camera scale
|
|
*
|
|
* @param {Vector} worldPos
|
|
* @param {number} scale 1 / zoomLevel
|
|
*/
|
|
prepareCanvasForPreview(worldPos, scale) {
|
|
this.context.clearRect(0, 0, this.previewSize, this.previewSize);
|
|
this.context.fillStyle = THEME.map.wires.previewColor;
|
|
this.context.fillRect(0, 0, this.previewSize, this.previewSize);
|
|
|
|
const dimensions = scale * this.previewSize;
|
|
|
|
const startWorldX = worldPos.x - dimensions / 2;
|
|
const startWorldY = worldPos.y - dimensions / 2;
|
|
|
|
const startTileX = Math.floor(startWorldX / globalConfig.tileSize);
|
|
const startTileY = Math.floor(startWorldY / globalConfig.tileSize);
|
|
const tileDimensions = Math.ceil(dimensions / globalConfig.tileSize);
|
|
|
|
this.context.save();
|
|
this.context.scale(1 / scale, 1 / scale);
|
|
this.context.translate(
|
|
startTileX * globalConfig.tileSize - startWorldX,
|
|
startTileY * globalConfig.tileSize - startWorldY
|
|
);
|
|
|
|
for (let dx = 0; dx < tileDimensions; ++dx) {
|
|
for (let dy = 0; dy < tileDimensions; ++dy) {
|
|
const tileX = dx + startTileX;
|
|
const tileY = dy + startTileY;
|
|
|
|
const content = this.root.map.getLayerContentXY(tileX, tileY, "wires");
|
|
if (content) {
|
|
MapChunkView.drawSingleWiresOverviewTile({
|
|
context: this.context,
|
|
x: dx * globalConfig.tileSize,
|
|
y: dy * globalConfig.tileSize,
|
|
entity: content,
|
|
tileSizePixels: globalConfig.tileSize,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
this.context.restore();
|
|
this.context.globalCompositeOperation = "destination-in";
|
|
this.previewOverlay.draw(this.context, 0, 0, this.previewSize, this.previewSize);
|
|
this.context.globalCompositeOperation = "source-over";
|
|
|
|
return this.canvas;
|
|
}
|
|
|
|
/**
|
|
* Renders the preview at the given position
|
|
* @param {import("../../../core/draw_utils").DrawParameters} parameters
|
|
* @param {Vector} worldPos
|
|
* @param {number} scale 1 / zoomLevel
|
|
*/
|
|
renderPreview(parameters, worldPos, scale) {
|
|
if (this.root.currentLayer !== "regular") {
|
|
// Only supporting wires right now
|
|
return;
|
|
}
|
|
|
|
const canvas = this.prepareCanvasForPreview(worldPos, scale);
|
|
|
|
parameters.context.globalAlpha = 0.3;
|
|
parameters.context.drawImage(
|
|
canvas,
|
|
worldPos.x - (scale * this.previewSize) / 2,
|
|
worldPos.y - (scale * this.previewSize) / 2,
|
|
scale * this.previewSize,
|
|
scale * this.previewSize
|
|
);
|
|
parameters.context.globalAlpha = 1;
|
|
}
|
|
}
|