Canvas: Add symbol dimension + Clean Viewer

This commit is contained in:
Eric NGUYEN 2023-02-17 15:37:08 +01:00
parent 5544eb05a4
commit fe72768142
5 changed files with 154 additions and 47 deletions

View file

@ -0,0 +1,18 @@
import { type IContainerModel } from '../../Interfaces/IContainerModel';
export function RenderContainer(
ctx: CanvasRenderingContext2D,
container: IContainerModel,
x: number,
y: number
): void {
ctx.save();
ctx.strokeStyle = container.properties.style?.stroke ?? '#000000';
ctx.fillStyle = container.properties.style?.fill ?? '#000000';
ctx.lineWidth = Number(container.properties.style?.strokeWidth ?? 1);
ctx.globalAlpha = Number(container.properties.style?.fillOpacity ?? 1);
ctx.fillRect(x, y, container.properties.width, container.properties.height);
ctx.globalAlpha = Number(container.properties.style?.strokeOpacity ?? 1);
ctx.strokeRect(x, y, container.properties.width, container.properties.height);
ctx.restore();
}

View file

@ -1,12 +1,14 @@
import { Orientation } from '../../Enums/Orientation';
import { Position } from '../../Enums/Position';
import { type IContainerModel } from '../../Interfaces/IContainerModel';
import { SHOW_SELF_DIMENSIONS, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS } from '../../utils/default';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { SHOW_SELF_DIMENSIONS, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, DIMENSION_MARGIN } from '../../utils/default';
import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../utils/itertools';
import { TransformX, TransformY } from '../../utils/svg';
import { type IDimensionStyle } from '../SVG/Elements/Dimension';
import { RenderDimension } from './Dimension';
export function AddDimensions(
export function AddContainerDimensions(
ctx: CanvasRenderingContext2D,
containers: Map<string, IContainerModel>,
container: IContainerModel,
@ -66,6 +68,20 @@ export function AddDimensions(
}
}
export function AddSymbolDimensions(
ctx: CanvasRenderingContext2D,
symbol: ISymbolModel,
scale: number,
depth: number
): void {
AddHorizontalSymbolDimension(
ctx,
symbol,
scale,
depth
);
}
/**
* Fonction that call another function given the positions
* @param dimMapped Position mapped depending on the Position enum in order:
@ -420,3 +436,39 @@ function AddHorizontalSelfDimension(
style
});
}
function AddHorizontalSymbolDimension(
ctx: CanvasRenderingContext2D,
symbol: ISymbolModel,
scale: number,
depth: number
): void {
const width = symbol.x + (symbol.width / 2);
if (width == null || width <= 0) {
return;
}
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
const offset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const text = width
.toFixed(0)
.toString();
// TODO: Put this in default.ts
const defaultDimensionSymbolStyle: IDimensionStyle = {
color: 'black'
};
RenderDimension(ctx, {
id,
xStart: 0,
yStart: -offset,
xEnd: width,
yEnd: -offset,
text,
scale,
style: defaultDimensionSymbolStyle
});
}

View file

@ -1,10 +1,49 @@
import { type IContainerModel } from '../../Interfaces/IContainerModel';
import { type IHistoryState } from '../../Interfaces/IHistoryState';
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
import { DIMENSION_MARGIN } from '../../utils/default';
import { AddDimensions } from './DimensionLayer';
import { MakeRecursionDFSIterator } from '../../utils/itertools';
import { RenderContainer } from './Container';
import { AddContainerDimensions, AddSymbolDimensions } from './DimensionLayer';
import { RenderSymbol } from './Symbol';
export function RenderDimensions(
export function RenderContainers(
ctx: CanvasRenderingContext2D,
root: IContainerModel,
containers: Map<string, IContainerModel>,
leftDim: number,
bottomDim: number,
topDim: number,
rightDim: number,
scale: number
): void {
const it = MakeRecursionDFSIterator(root, containers, 0, [0, 0]);
for (const { container, depth, currentTransform } of it) {
const [x, y] = [
container.properties.x + currentTransform[0],
container.properties.y + currentTransform[1]
];
// Draw container
RenderContainer(ctx, container, x, y);
// Draw dimensions
RenderContainerDimensions(
ctx,
leftDim,
bottomDim,
topDim,
rightDim,
depth,
scale,
containers,
container,
currentTransform
);
}
}
export function RenderContainerDimensions(
ctx: CanvasRenderingContext2D,
leftDim: number,
bottomDim: number,
@ -23,33 +62,43 @@ export function RenderDimensions(
const containerBottomDim = bottomDim + depthOffset;
const containerRightDim = rightDim + depthOffset;
const dimMapped = [containerLeftDim, containerBottomDim, containerTopDim, containerRightDim];
AddDimensions(ctx, containers, container, dimMapped, currentTransform, scale, depth);
AddContainerDimensions(ctx, containers, container, dimMapped, currentTransform, scale, depth);
ctx.restore();
}
export function RenderSymbols(
current: IHistoryState,
ctx: CanvasRenderingContext2D,
current: IHistoryState,
scale: number
): void {
current.symbols.forEach((symbol) => {
RenderSymbol(symbol, ctx, scale);
let count = 0;
current.symbols.forEach((symbol: ISymbolModel) => {
RenderSymbol(ctx, symbol, scale);
if (!symbol.showDimension) {
return;
}
AddSymbolDimensions(ctx, symbol, scale, count);
count++;
});
}
export function RenderContainers(
export function RenderSymbolDimensions(
ctx: CanvasRenderingContext2D,
depth: number,
scale: number,
containers: Map<string, IContainerModel>,
container: IContainerModel,
x: number,
y: number
currentTransform: [number, number]
): void {
ctx.save();
ctx.strokeStyle = container.properties.style?.stroke ?? '#000000';
ctx.fillStyle = container.properties.style?.fill ?? '#000000';
ctx.lineWidth = Number(container.properties.style?.strokeWidth ?? 1);
ctx.globalAlpha = Number(container.properties.style?.fillOpacity ?? 1);
ctx.fillRect(x, y, container.properties.width, container.properties.height);
ctx.globalAlpha = Number(container.properties.style?.strokeOpacity ?? 1);
ctx.strokeRect(x, y, container.properties.width, container.properties.height);
const depthOffset = (DIMENSION_MARGIN * (depth + 1)) / scale;
const containerLeftDim = -depthOffset;
const containerTopDim = -depthOffset;
const containerBottomDim = depthOffset;
const containerRightDim = depthOffset;
const dimMapped = [containerLeftDim, containerBottomDim, containerTopDim, containerRightDim];
AddContainerDimensions(ctx, containers, container, dimMapped, currentTransform, scale, depth);
ctx.restore();
}

View file

@ -4,8 +4,8 @@ import { DIMENSION_MARGIN } from '../../utils/default';
const IMAGE_CACHE = new Map<string, HTMLImageElement>();
export function RenderSymbol(
symbol: ISymbolModel,
ctx: CanvasRenderingContext2D,
symbol: ISymbolModel,
scale: number): void {
const href = symbol.config.Image.Base64Image ?? symbol.config.Image.Url;

View file

@ -10,7 +10,8 @@ import { RenderSelector } from '../Canvas/Selector';
import { SelectorMode, SVG } from '../SVG/SVG';
import { useState } from 'react';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { RenderContainers, RenderDimensions, RenderSymbols } from '../Canvas/Renderer';
import { RenderContainers, RenderContainerDimensions, RenderSymbols } from '../Canvas/Renderer';
import { RenderContainer } from '../Canvas/Container';
interface IViewerProps {
className: string
@ -78,7 +79,12 @@ export function Viewer({
}
if (USE_EXPERIMENTAL_CANVAS_API) {
function Draw(ctx: CanvasRenderingContext2D, frameCount: number, scale: number, translatePos: IPoint): void {
function Draw(
ctx: CanvasRenderingContext2D,
frameCount: number,
scale: number,
translatePos: IPoint
): void {
if (mainContainer === undefined) {
return;
}
@ -93,30 +99,12 @@ export function Viewer({
ctx.setTransform(scale, 0, 0, scale, translatePos.x, translatePos.y);
ctx.fillStyle = '#000000';
const it = MakeRecursionDFSIterator(mainContainer, current.containers, 0, [0, 0]);
for (const { container, depth, currentTransform } of it) {
const [x, y] = [
container.properties.x + currentTransform[0],
container.properties.y + currentTransform[1]
];
// Draw container
RenderContainers(ctx, container, x, y);
// Draw dimensions
RenderDimensions(
// Draw containers and symbol dimensions
RenderContainers(
ctx,
leftDim,
bottomDim,
topDim,
rightDim,
depth,
scale,
mainContainer,
current.containers,
container,
currentTransform
);
}
leftDim, bottomDim, topDim, rightDim, scale);
// Draw selector
RenderSelector(ctx, frameCount, {
@ -124,8 +112,8 @@ export function Viewer({
scale,
selected: selectedContainer
});
// Draw symbols
RenderSymbols(current, ctx, scale);
// Draw symbols and symbol dimensions
RenderSymbols(ctx, current, scale);
ctx.restore();
}
return (