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 { SHOW_SELECTOR_TEXT } from '../../utils/default';
|
||||||
import { GetAbsolutePosition } from '../../utils/itertools';
|
|
||||||
import { RemoveMargin } from '../../utils/svg';
|
|
||||||
|
|
||||||
interface ISelectorProps {
|
interface ISelectorProps {
|
||||||
containers: Map<string, IContainerModel>
|
text: string
|
||||||
selected?: IContainerModel
|
x: number
|
||||||
scale?: number
|
y: number
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
scale: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RenderSelector(ctx: CanvasRenderingContext2D, frameCount: number, props: ISelectorProps): void {
|
export function RenderSelector(
|
||||||
if (props.selected === undefined || props.selected === null) {
|
ctx: CanvasRenderingContext2D,
|
||||||
return;
|
frameCount: number,
|
||||||
}
|
{
|
||||||
|
text,
|
||||||
const scale = (props.scale ?? 1);
|
x,
|
||||||
let [x, y] = GetAbsolutePosition(props.containers, props.selected);
|
y,
|
||||||
let [width, height] = [
|
width,
|
||||||
props.selected.properties.width,
|
height,
|
||||||
props.selected.properties.height
|
scale
|
||||||
];
|
}: ISelectorProps
|
||||||
|
): void {
|
||||||
({ 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 xText = x + width / 2;
|
const xText = x + width / 2;
|
||||||
const yText = y + height / 2;
|
const yText = y + height / 2;
|
||||||
|
|
||||||
|
@ -42,7 +35,7 @@ export function RenderSelector(ctx: CanvasRenderingContext2D, frameCount: number
|
||||||
if (SHOW_SELECTOR_TEXT) {
|
if (SHOW_SELECTOR_TEXT) {
|
||||||
ctx.font = `${16 / scale}px Verdana`;
|
ctx.font = `${16 / scale}px Verdana`;
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.fillText(props.selected.properties.displayedText, xText, yText);
|
ctx.fillText(text, xText, yText);
|
||||||
ctx.textAlign = 'left';
|
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 { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||||
import { DIMENSION_MARGIN } from '../../utils/default';
|
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../utils/default';
|
||||||
|
|
||||||
const IMAGE_CACHE = new Map<string, HTMLImageElement>();
|
const IMAGE_CACHE = new Map<string, HTMLImageElement>();
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ export function RenderSymbol(
|
||||||
|
|
||||||
DrawImage(ctx, scale, image, symbol);
|
DrawImage(ctx, scale, image, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DrawImage(
|
function DrawImage(
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
scale: number,
|
scale: number,
|
||||||
|
@ -34,12 +35,14 @@ function DrawImage(
|
||||||
): void {
|
): void {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.fillStyle = '#000000';
|
ctx.fillStyle = '#000000';
|
||||||
|
const width = symbol.width / scale;
|
||||||
|
const height = symbol.height / scale;
|
||||||
ctx.drawImage(
|
ctx.drawImage(
|
||||||
image,
|
image,
|
||||||
symbol.x,
|
symbol.x + symbol.width / 2,
|
||||||
-DIMENSION_MARGIN,
|
-SYMBOL_MARGIN - height,
|
||||||
symbol.width,
|
width,
|
||||||
symbol.height
|
height
|
||||||
);
|
);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,13 @@ import { USE_EXPERIMENTAL_CANVAS_API } from '../../utils/default';
|
||||||
import { FindContainerById, MakeRecursionDFSIterator } from '../../utils/itertools';
|
import { FindContainerById, MakeRecursionDFSIterator } from '../../utils/itertools';
|
||||||
import { BAR_WIDTH } from '../Bar/Bar';
|
import { BAR_WIDTH } from '../Bar/Bar';
|
||||||
import { Canvas } from '../Canvas/Canvas';
|
import { Canvas } from '../Canvas/Canvas';
|
||||||
import { RenderSelector } from '../Canvas/Selector';
|
import { RenderContainerSelector } from '../Canvas/SelectorContainer';
|
||||||
import { SelectorMode, SVG } from '../SVG/SVG';
|
import { SelectorMode, SVG } from '../SVG/SVG';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||||
import { RenderContainers, RenderContainerDimensions, RenderSymbols } from '../Canvas/Renderer';
|
import { RenderContainers, RenderContainerDimensions, RenderSymbols } from '../Canvas/Renderer';
|
||||||
import { RenderContainer } from '../Canvas/Container';
|
import { RenderContainer } from '../Canvas/Container';
|
||||||
|
import { RenderSymbolSelector } from '../Canvas/SelectorSymbol';
|
||||||
|
|
||||||
interface IViewerProps {
|
interface IViewerProps {
|
||||||
className: string
|
className: string
|
||||||
|
@ -106,14 +107,27 @@ export function Viewer({
|
||||||
current.containers,
|
current.containers,
|
||||||
leftDim, bottomDim, topDim, rightDim, scale);
|
leftDim, bottomDim, topDim, rightDim, scale);
|
||||||
|
|
||||||
// Draw selector
|
|
||||||
RenderSelector(ctx, frameCount, {
|
|
||||||
containers: current.containers,
|
|
||||||
scale,
|
|
||||||
selected: selectedContainer
|
|
||||||
});
|
|
||||||
// Draw symbols and symbol dimensions
|
// Draw symbols and symbol dimensions
|
||||||
RenderSymbols(ctx, current, scale);
|
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();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue