Canvas: Add symbol selector
This commit is contained in:
parent
bdc10264d5
commit
9cf56b308b
5 changed files with 140 additions and 39 deletions
|
@ -1,33 +1,26 @@
|
|||
import { IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { SHOW_SELECTOR_TEXT } from '../../utils/default';
|
||||
import { GetAbsolutePosition } from '../../utils/itertools';
|
||||
import { RemoveMargin } from '../../utils/svg';
|
||||
|
||||
interface ISelectorProps {
|
||||
containers: Map<string, IContainerModel>
|
||||
selected?: IContainerModel
|
||||
scale?: number
|
||||
text: string
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
scale: number
|
||||
}
|
||||
|
||||
export function RenderSelector(ctx: CanvasRenderingContext2D, frameCount: number, props: ISelectorProps): void {
|
||||
if (props.selected === undefined || props.selected === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scale = (props.scale ?? 1);
|
||||
let [x, y] = GetAbsolutePosition(props.containers, props.selected);
|
||||
let [width, height] = [
|
||||
props.selected.properties.width,
|
||||
props.selected.properties.height
|
||||
];
|
||||
|
||||
({ x, y, width, height } = RemoveMargin(x, y, width, height,
|
||||
props.selected.properties.margin.left,
|
||||
props.selected.properties.margin.bottom,
|
||||
props.selected.properties.margin.top,
|
||||
props.selected.properties.margin.right
|
||||
));
|
||||
|
||||
export function RenderSelector(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
frameCount: number,
|
||||
{
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
scale
|
||||
}: ISelectorProps
|
||||
): void {
|
||||
const xText = x + width / 2;
|
||||
const yText = y + height / 2;
|
||||
|
||||
|
@ -42,7 +35,7 @@ export function RenderSelector(ctx: CanvasRenderingContext2D, frameCount: number
|
|||
if (SHOW_SELECTOR_TEXT) {
|
||||
ctx.font = `${16 / scale}px Verdana`;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(props.selected.properties.displayedText, xText, yText);
|
||||
ctx.fillText(text, xText, yText);
|
||||
ctx.textAlign = 'left';
|
||||
}
|
||||
}
|
||||
|
|
48
src/Components/Canvas/SelectorContainer.ts
Normal file
48
src/Components/Canvas/SelectorContainer.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { GetAbsolutePosition } from '../../utils/itertools';
|
||||
import { RemoveMargin } from '../../utils/svg';
|
||||
import { RenderSelector } from './Selector';
|
||||
|
||||
interface ISelectorProps {
|
||||
containers: Map<string, IContainerModel>
|
||||
selected?: IContainerModel
|
||||
scale?: number
|
||||
}
|
||||
|
||||
export function RenderContainerSelector(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
frameCount: number,
|
||||
props: ISelectorProps
|
||||
): void {
|
||||
if (props.selected === undefined || props.selected === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scale = (props.scale ?? 1);
|
||||
let [x, y] = GetAbsolutePosition(props.containers, props.selected);
|
||||
let [width, height] = [
|
||||
props.selected.properties.width,
|
||||
props.selected.properties.height
|
||||
];
|
||||
|
||||
({ x, y, width, height } = RemoveMargin(x, y, width, height,
|
||||
props.selected.properties.margin.left,
|
||||
props.selected.properties.margin.bottom,
|
||||
props.selected.properties.margin.top,
|
||||
props.selected.properties.margin.right
|
||||
));
|
||||
|
||||
const text = props.selected.properties.displayedText;
|
||||
RenderSelector(
|
||||
ctx,
|
||||
frameCount,
|
||||
{
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
scale
|
||||
}
|
||||
);
|
||||
}
|
43
src/Components/Canvas/SelectorSymbol.ts
Normal file
43
src/Components/Canvas/SelectorSymbol.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { SYMBOL_MARGIN } from '../../utils/default';
|
||||
import { RenderSelector } from './Selector';
|
||||
|
||||
interface ISelectorProps {
|
||||
symbols: Map<string, ISymbolModel>
|
||||
selected?: ISymbolModel
|
||||
scale?: number
|
||||
}
|
||||
|
||||
export function RenderSymbolSelector(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
frameCount: number,
|
||||
props: ISelectorProps
|
||||
): void {
|
||||
if (props.selected === undefined || props.selected === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scale = (props.scale ?? 1);
|
||||
const [width, height] = [
|
||||
props.selected.width / scale,
|
||||
props.selected.height / scale
|
||||
];
|
||||
|
||||
const [x, y] = [
|
||||
props.selected.x + props.selected.width / 2,
|
||||
-SYMBOL_MARGIN - height];
|
||||
|
||||
const text = props.selected.displayedText;
|
||||
RenderSelector(
|
||||
ctx,
|
||||
frameCount,
|
||||
{
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
scale
|
||||
}
|
||||
);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { DIMENSION_MARGIN } from '../../utils/default';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../utils/default';
|
||||
|
||||
const IMAGE_CACHE = new Map<string, HTMLImageElement>();
|
||||
|
||||
|
@ -26,6 +26,7 @@ export function RenderSymbol(
|
|||
|
||||
DrawImage(ctx, scale, image, symbol);
|
||||
}
|
||||
|
||||
function DrawImage(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
scale: number,
|
||||
|
@ -34,12 +35,14 @@ function DrawImage(
|
|||
): void {
|
||||
ctx.save();
|
||||
ctx.fillStyle = '#000000';
|
||||
const width = symbol.width / scale;
|
||||
const height = symbol.height / scale;
|
||||
ctx.drawImage(
|
||||
image,
|
||||
symbol.x,
|
||||
-DIMENSION_MARGIN,
|
||||
symbol.width,
|
||||
symbol.height
|
||||
symbol.x + symbol.width / 2,
|
||||
-SYMBOL_MARGIN - height,
|
||||
width,
|
||||
height
|
||||
);
|
||||
ctx.restore();
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@ import { USE_EXPERIMENTAL_CANVAS_API } from '../../utils/default';
|
|||
import { FindContainerById, MakeRecursionDFSIterator } from '../../utils/itertools';
|
||||
import { BAR_WIDTH } from '../Bar/Bar';
|
||||
import { Canvas } from '../Canvas/Canvas';
|
||||
import { RenderSelector } from '../Canvas/Selector';
|
||||
import { RenderContainerSelector } from '../Canvas/SelectorContainer';
|
||||
import { SelectorMode, SVG } from '../SVG/SVG';
|
||||
import { useState } from 'react';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { RenderContainers, RenderContainerDimensions, RenderSymbols } from '../Canvas/Renderer';
|
||||
import { RenderContainer } from '../Canvas/Container';
|
||||
import { RenderSymbolSelector } from '../Canvas/SelectorSymbol';
|
||||
|
||||
interface IViewerProps {
|
||||
className: string
|
||||
|
@ -106,14 +107,27 @@ export function Viewer({
|
|||
current.containers,
|
||||
leftDim, bottomDim, topDim, rightDim, scale);
|
||||
|
||||
// Draw selector
|
||||
RenderSelector(ctx, frameCount, {
|
||||
containers: current.containers,
|
||||
scale,
|
||||
selected: selectedContainer
|
||||
});
|
||||
// Draw symbols and symbol dimensions
|
||||
RenderSymbols(ctx, current, scale);
|
||||
|
||||
// Draw selector
|
||||
switch (selectorMode) {
|
||||
case SelectorMode.Containers:
|
||||
RenderContainerSelector(ctx, frameCount, {
|
||||
containers: current.containers,
|
||||
scale,
|
||||
selected: selectedContainer
|
||||
});
|
||||
break;
|
||||
case SelectorMode.Symbols:
|
||||
RenderSymbolSelector(ctx, frameCount, {
|
||||
symbols: current.symbols,
|
||||
scale,
|
||||
selected: selectedSymbol
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
return (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue