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.
tobspr_shapez.io/src/js/core/draw_utils.js

122 lines
3.3 KiB

/**
* @typedef {import("./sprites").AtlasSprite} AtlasSprite
* @typedef {import("./draw_parameters").DrawParameters} DrawParameters
*/
import { globalConfig } from "./config";
import { createLogger } from "./logging";
import { Rectangle } from "./rectangle";
const logger = createLogger("draw_utils");
export function initDrawUtils() {
CanvasRenderingContext2D.prototype.beginRoundedRect = function (x, y, w, h, r) {
this.beginPath();
if (r < 0.05) {
this.rect(x, y, w, h);
return;
}
if (w < 2 * r) {
r = w / 2;
}
if (h < 2 * r) {
r = h / 2;
}
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r);
this.arcTo(x, y, x + w, y, r);
};
CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) {
this.beginPath();
if (r < 0.05) {
this.rect(x, y, 1, 1);
return;
}
this.arc(x, y, r, 0, 2.0 * Math.PI);
};
}
/**
*
* @param {object} param0
* @param {DrawParameters} param0.parameters
* @param {AtlasSprite} param0.sprite
* @param {number} param0.x
* @param {number} param0.y
* @param {number} param0.angle
* @param {number} param0.size
* @param {number=} param0.offsetX
* @param {number=} param0.offsetY
*/
export function drawRotatedSprite({ parameters, sprite, x, y, angle, size, offsetX = 0, offsetY = 0 }) {
if (angle === 0) {
sprite.drawCachedCentered(parameters, x + offsetX, y + offsetY, size);
return;
}
parameters.context.translate(x, y);
parameters.context.rotate(angle);
sprite.drawCachedCentered(parameters, offsetX, offsetY, size, false);
parameters.context.rotate(-angle);
parameters.context.translate(-x, -y);
}
let warningsShown = 0;
/**
* Draws a sprite with clipping
* @param {object} param0
* @param {DrawParameters} param0.parameters
* @param {HTMLCanvasElement} param0.sprite
* @param {number} param0.x
* @param {number} param0.y
* @param {number} param0.w
* @param {number} param0.h
* @param {number} param0.originalW
* @param {number} param0.originalH
*/
export function drawSpriteClipped({ parameters, sprite, x, y, w, h, originalW, originalH }) {
const rect = new Rectangle(x, y, w, h);
const intersection = rect.getIntersection(parameters.visibleRect);
if (!intersection) {
// Clipped
if (++warningsShown % 200 === 1) {
logger.warn(
"Sprite drawn clipped but it's not on screen - perform culling before (",
warningsShown,
"warnings)"
);
}
if (G_IS_DEV && globalConfig.debug.testClipping) {
parameters.context.fillStyle = "yellow";
parameters.context.fillRect(x, y, w, h);
}
return;
}
parameters.context.drawImage(
sprite,
// src pos and size
((intersection.x - x) / w) * originalW,
((intersection.y - y) / h) * originalH,
(originalW * intersection.w) / w,
(originalH * intersection.h) / h,
// dest pos and size
intersection.x,
intersection.y,
intersection.w,
intersection.h
);
}