import type { ImageDocument } from "@core/document"; import type { EditorState } from "@editor/state"; import { resolveTransformTargetBounds, selectedTransformTarget } from "@editor/transform-targets"; import { clearScreenRect } from "./clear-rect"; import { documentRectToScreenRect } from "./screen-rect"; import type { RgbaColor, ScreenRect, WebGlRendererContext } from "./types"; const handleFillColor: RgbaColor = [0, 0, 0, 0.88]; const handleBorderColor: RgbaColor = [1, 1, 1, 0.95]; export function renderTransformControls(context: WebGlRendererContext, document: ImageDocument, editor: EditorState) { const target = selectedTransformTarget(document, editor.selection); const bounds = target ? resolveTransformTargetBounds(document, target) : undefined; if (!bounds) return; const rect = documentRectToScreenRect(context.canvas, bounds, editor.viewport); for (const handle of transformHandleRects(rect)) { clearScreenRect(context, handle.border, handleBorderColor); clearScreenRect(context, handle.fill, handleFillColor); } } function transformHandleRects(rect: ScreenRect) { const size = 12; const border = 2; const half = size / 2; const points = [ { x: rect.x, y: rect.y }, { x: rect.x + rect.w / 2, y: rect.y }, { x: rect.x + rect.w, y: rect.y }, { x: rect.x + rect.w, y: rect.y + rect.h / 2 }, { x: rect.x + rect.w, y: rect.y + rect.h }, { x: rect.x + rect.w / 2, y: rect.y + rect.h }, { x: rect.x, y: rect.y + rect.h }, { x: rect.x, y: rect.y + rect.h / 2 }, ]; return points.map((point) => ({ border: { x: Math.round(point.x - half - border), y: Math.round(point.y - half - border), w: size + border * 2, h: size + border * 2 }, fill: { x: Math.round(point.x - half), y: Math.round(point.y - half), w: size, h: size }, })); }