Canvas: Add symbol selector

This commit is contained in:
Eric NGUYEN 2023-02-17 16:09:36 +01:00
parent bdc10264d5
commit 9cf56b308b
5 changed files with 140 additions and 39 deletions

View file

@ -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';
}
}

View 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
}
);
}

View 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
}
);
}

View file

@ -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();
}

View file

@ -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 (