|
|
@ -21,7 +21,7 @@ import {
|
|
|
|
} from "../element";
|
|
|
|
} from "../element";
|
|
|
|
|
|
|
|
|
|
|
|
import { roundRect } from "./roundRect";
|
|
|
|
import { roundRect } from "./roundRect";
|
|
|
|
import { SceneState } from "../scene/types";
|
|
|
|
import { RenderConfig } from "../scene/types";
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
getScrollBars,
|
|
|
|
getScrollBars,
|
|
|
|
SCROLLBAR_COLOR,
|
|
|
|
SCROLLBAR_COLOR,
|
|
|
@ -146,12 +146,12 @@ const strokeGrid = (
|
|
|
|
const renderLinearPointHandles = (
|
|
|
|
const renderLinearPointHandles = (
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
appState: AppState,
|
|
|
|
appState: AppState,
|
|
|
|
sceneState: SceneState,
|
|
|
|
renderConfig: RenderConfig,
|
|
|
|
element: NonDeleted<ExcalidrawLinearElement>,
|
|
|
|
element: NonDeleted<ExcalidrawLinearElement>,
|
|
|
|
) => {
|
|
|
|
) => {
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.translate(sceneState.scrollX, sceneState.scrollY);
|
|
|
|
context.translate(renderConfig.scrollX, renderConfig.scrollY);
|
|
|
|
context.lineWidth = 1 / sceneState.zoom.value;
|
|
|
|
context.lineWidth = 1 / renderConfig.zoom.value;
|
|
|
|
|
|
|
|
|
|
|
|
LinearElementEditor.getPointsGlobalCoordinates(element).forEach(
|
|
|
|
LinearElementEditor.getPointsGlobalCoordinates(element).forEach(
|
|
|
|
(point, idx) => {
|
|
|
|
(point, idx) => {
|
|
|
@ -166,7 +166,7 @@ const renderLinearPointHandles = (
|
|
|
|
context,
|
|
|
|
context,
|
|
|
|
point[0],
|
|
|
|
point[0],
|
|
|
|
point[1],
|
|
|
|
point[1],
|
|
|
|
POINT_HANDLE_SIZE / 2 / sceneState.zoom.value,
|
|
|
|
POINT_HANDLE_SIZE / 2 / renderConfig.zoom.value,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -180,31 +180,20 @@ export const renderScene = (
|
|
|
|
scale: number,
|
|
|
|
scale: number,
|
|
|
|
rc: RoughCanvas,
|
|
|
|
rc: RoughCanvas,
|
|
|
|
canvas: HTMLCanvasElement,
|
|
|
|
canvas: HTMLCanvasElement,
|
|
|
|
sceneState: SceneState,
|
|
|
|
renderConfig: RenderConfig,
|
|
|
|
// extra options passed to the renderer
|
|
|
|
// extra options passed to the renderer
|
|
|
|
{
|
|
|
|
|
|
|
|
renderScrollbars = true,
|
|
|
|
|
|
|
|
renderSelection = true,
|
|
|
|
|
|
|
|
// Whether to employ render optimizations to improve performance.
|
|
|
|
|
|
|
|
// Should not be turned on for export operations and similar, because it
|
|
|
|
|
|
|
|
// doesn't guarantee pixel-perfect output.
|
|
|
|
|
|
|
|
renderOptimizations = false,
|
|
|
|
|
|
|
|
renderGrid = true,
|
|
|
|
|
|
|
|
/** when exporting the behavior is slightly different (e.g. we can't use
|
|
|
|
|
|
|
|
CSS filters) */
|
|
|
|
|
|
|
|
isExport = false,
|
|
|
|
|
|
|
|
}: {
|
|
|
|
|
|
|
|
renderScrollbars?: boolean;
|
|
|
|
|
|
|
|
renderSelection?: boolean;
|
|
|
|
|
|
|
|
renderOptimizations?: boolean;
|
|
|
|
|
|
|
|
renderGrid?: boolean;
|
|
|
|
|
|
|
|
isExport?: boolean;
|
|
|
|
|
|
|
|
} = {},
|
|
|
|
|
|
|
|
) => {
|
|
|
|
) => {
|
|
|
|
if (canvas === null) {
|
|
|
|
if (canvas === null) {
|
|
|
|
return { atLeastOneVisibleElement: false };
|
|
|
|
return { atLeastOneVisibleElement: false };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
|
|
renderScrollbars = true,
|
|
|
|
|
|
|
|
renderSelection = true,
|
|
|
|
|
|
|
|
renderGrid = true,
|
|
|
|
|
|
|
|
isExporting,
|
|
|
|
|
|
|
|
} = renderConfig;
|
|
|
|
|
|
|
|
|
|
|
|
const context = canvas.getContext("2d")!;
|
|
|
|
const context = canvas.getContext("2d")!;
|
|
|
|
|
|
|
|
|
|
|
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
|
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
|
@ -215,22 +204,22 @@ export const renderScene = (
|
|
|
|
const normalizedCanvasWidth = canvas.width / scale;
|
|
|
|
const normalizedCanvasWidth = canvas.width / scale;
|
|
|
|
const normalizedCanvasHeight = canvas.height / scale;
|
|
|
|
const normalizedCanvasHeight = canvas.height / scale;
|
|
|
|
|
|
|
|
|
|
|
|
if (isExport && sceneState.theme === "dark") {
|
|
|
|
if (isExporting && renderConfig.theme === "dark") {
|
|
|
|
context.filter = THEME_FILTER;
|
|
|
|
context.filter = THEME_FILTER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Paint background
|
|
|
|
// Paint background
|
|
|
|
if (typeof sceneState.viewBackgroundColor === "string") {
|
|
|
|
if (typeof renderConfig.viewBackgroundColor === "string") {
|
|
|
|
const hasTransparence =
|
|
|
|
const hasTransparence =
|
|
|
|
sceneState.viewBackgroundColor === "transparent" ||
|
|
|
|
renderConfig.viewBackgroundColor === "transparent" ||
|
|
|
|
sceneState.viewBackgroundColor.length === 5 || // #RGBA
|
|
|
|
renderConfig.viewBackgroundColor.length === 5 || // #RGBA
|
|
|
|
sceneState.viewBackgroundColor.length === 9 || // #RRGGBBA
|
|
|
|
renderConfig.viewBackgroundColor.length === 9 || // #RRGGBBA
|
|
|
|
/(hsla|rgba)\(/.test(sceneState.viewBackgroundColor);
|
|
|
|
/(hsla|rgba)\(/.test(renderConfig.viewBackgroundColor);
|
|
|
|
if (hasTransparence) {
|
|
|
|
if (hasTransparence) {
|
|
|
|
context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
|
|
|
context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.fillStyle = sceneState.viewBackgroundColor;
|
|
|
|
context.fillStyle = renderConfig.viewBackgroundColor;
|
|
|
|
context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
|
|
|
context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
|
|
|
context.restore();
|
|
|
|
context.restore();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -238,42 +227,46 @@ export const renderScene = (
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Apply zoom
|
|
|
|
// Apply zoom
|
|
|
|
const zoomTranslationX = sceneState.zoom.translation.x;
|
|
|
|
const zoomTranslationX = renderConfig.zoom.translation.x;
|
|
|
|
const zoomTranslationY = sceneState.zoom.translation.y;
|
|
|
|
const zoomTranslationY = renderConfig.zoom.translation.y;
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.translate(zoomTranslationX, zoomTranslationY);
|
|
|
|
context.translate(zoomTranslationX, zoomTranslationY);
|
|
|
|
context.scale(sceneState.zoom.value, sceneState.zoom.value);
|
|
|
|
context.scale(renderConfig.zoom.value, renderConfig.zoom.value);
|
|
|
|
|
|
|
|
|
|
|
|
// Grid
|
|
|
|
// Grid
|
|
|
|
if (renderGrid && appState.gridSize) {
|
|
|
|
if (renderGrid && appState.gridSize) {
|
|
|
|
strokeGrid(
|
|
|
|
strokeGrid(
|
|
|
|
context,
|
|
|
|
context,
|
|
|
|
appState.gridSize,
|
|
|
|
appState.gridSize,
|
|
|
|
-Math.ceil(zoomTranslationX / sceneState.zoom.value / appState.gridSize) *
|
|
|
|
-Math.ceil(
|
|
|
|
|
|
|
|
zoomTranslationX / renderConfig.zoom.value / appState.gridSize,
|
|
|
|
|
|
|
|
) *
|
|
|
|
appState.gridSize +
|
|
|
|
appState.gridSize +
|
|
|
|
(sceneState.scrollX % appState.gridSize),
|
|
|
|
(renderConfig.scrollX % appState.gridSize),
|
|
|
|
-Math.ceil(zoomTranslationY / sceneState.zoom.value / appState.gridSize) *
|
|
|
|
-Math.ceil(
|
|
|
|
|
|
|
|
zoomTranslationY / renderConfig.zoom.value / appState.gridSize,
|
|
|
|
|
|
|
|
) *
|
|
|
|
appState.gridSize +
|
|
|
|
appState.gridSize +
|
|
|
|
(sceneState.scrollY % appState.gridSize),
|
|
|
|
(renderConfig.scrollY % appState.gridSize),
|
|
|
|
normalizedCanvasWidth / sceneState.zoom.value,
|
|
|
|
normalizedCanvasWidth / renderConfig.zoom.value,
|
|
|
|
normalizedCanvasHeight / sceneState.zoom.value,
|
|
|
|
normalizedCanvasHeight / renderConfig.zoom.value,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Paint visible elements
|
|
|
|
// Paint visible elements
|
|
|
|
const visibleElements = elements.filter((element) =>
|
|
|
|
const visibleElements = elements.filter((element) =>
|
|
|
|
isVisibleElement(element, normalizedCanvasWidth, normalizedCanvasHeight, {
|
|
|
|
isVisibleElement(element, normalizedCanvasWidth, normalizedCanvasHeight, {
|
|
|
|
zoom: sceneState.zoom,
|
|
|
|
zoom: renderConfig.zoom,
|
|
|
|
offsetLeft: appState.offsetLeft,
|
|
|
|
offsetLeft: appState.offsetLeft,
|
|
|
|
offsetTop: appState.offsetTop,
|
|
|
|
offsetTop: appState.offsetTop,
|
|
|
|
scrollX: sceneState.scrollX,
|
|
|
|
scrollX: renderConfig.scrollX,
|
|
|
|
scrollY: sceneState.scrollY,
|
|
|
|
scrollY: renderConfig.scrollY,
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
visibleElements.forEach((element) => {
|
|
|
|
visibleElements.forEach((element) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
renderElement(element, rc, context, renderOptimizations, sceneState);
|
|
|
|
renderElement(element, rc, context, renderConfig);
|
|
|
|
} catch (error: any) {
|
|
|
|
} catch (error: any) {
|
|
|
|
console.error(error);
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -284,20 +277,14 @@ export const renderScene = (
|
|
|
|
appState.editingLinearElement.elementId,
|
|
|
|
appState.editingLinearElement.elementId,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (element) {
|
|
|
|
if (element) {
|
|
|
|
renderLinearPointHandles(context, appState, sceneState, element);
|
|
|
|
renderLinearPointHandles(context, appState, renderConfig, element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Paint selection element
|
|
|
|
// Paint selection element
|
|
|
|
if (selectionElement) {
|
|
|
|
if (selectionElement) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
renderElement(
|
|
|
|
renderElement(selectionElement, rc, context, renderConfig);
|
|
|
|
selectionElement,
|
|
|
|
|
|
|
|
rc,
|
|
|
|
|
|
|
|
context,
|
|
|
|
|
|
|
|
renderOptimizations,
|
|
|
|
|
|
|
|
sceneState,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
} catch (error: any) {
|
|
|
|
console.error(error);
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -307,7 +294,7 @@ export const renderScene = (
|
|
|
|
appState.suggestedBindings
|
|
|
|
appState.suggestedBindings
|
|
|
|
.filter((binding) => binding != null)
|
|
|
|
.filter((binding) => binding != null)
|
|
|
|
.forEach((suggestedBinding) => {
|
|
|
|
.forEach((suggestedBinding) => {
|
|
|
|
renderBindingHighlight(context, sceneState, suggestedBinding!);
|
|
|
|
renderBindingHighlight(context, renderConfig, suggestedBinding!);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -327,12 +314,14 @@ export const renderScene = (
|
|
|
|
selectionColors.push(oc.black);
|
|
|
|
selectionColors.push(oc.black);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// remote users
|
|
|
|
// remote users
|
|
|
|
if (sceneState.remoteSelectedElementIds[element.id]) {
|
|
|
|
if (renderConfig.remoteSelectedElementIds[element.id]) {
|
|
|
|
selectionColors.push(
|
|
|
|
selectionColors.push(
|
|
|
|
...sceneState.remoteSelectedElementIds[element.id].map((socketId) => {
|
|
|
|
...renderConfig.remoteSelectedElementIds[element.id].map(
|
|
|
|
|
|
|
|
(socketId) => {
|
|
|
|
const { background } = getClientColors(socketId, appState);
|
|
|
|
const { background } = getClientColors(socketId, appState);
|
|
|
|
return background;
|
|
|
|
return background;
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (selectionColors.length) {
|
|
|
|
if (selectionColors.length) {
|
|
|
@ -374,37 +363,37 @@ export const renderScene = (
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
selections.forEach((selection) =>
|
|
|
|
selections.forEach((selection) =>
|
|
|
|
renderSelectionBorder(context, sceneState, selection),
|
|
|
|
renderSelectionBorder(context, renderConfig, selection),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const locallySelectedElements = getSelectedElements(elements, appState);
|
|
|
|
const locallySelectedElements = getSelectedElements(elements, appState);
|
|
|
|
|
|
|
|
|
|
|
|
// Paint resize transformHandles
|
|
|
|
// Paint resize transformHandles
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.translate(sceneState.scrollX, sceneState.scrollY);
|
|
|
|
context.translate(renderConfig.scrollX, renderConfig.scrollY);
|
|
|
|
if (locallySelectedElements.length === 1) {
|
|
|
|
if (locallySelectedElements.length === 1) {
|
|
|
|
context.fillStyle = oc.white;
|
|
|
|
context.fillStyle = oc.white;
|
|
|
|
const transformHandles = getTransformHandles(
|
|
|
|
const transformHandles = getTransformHandles(
|
|
|
|
locallySelectedElements[0],
|
|
|
|
locallySelectedElements[0],
|
|
|
|
sceneState.zoom,
|
|
|
|
renderConfig.zoom,
|
|
|
|
"mouse", // when we render we don't know which pointer type so use mouse
|
|
|
|
"mouse", // when we render we don't know which pointer type so use mouse
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (!appState.viewModeEnabled) {
|
|
|
|
if (!appState.viewModeEnabled) {
|
|
|
|
renderTransformHandles(
|
|
|
|
renderTransformHandles(
|
|
|
|
context,
|
|
|
|
context,
|
|
|
|
sceneState,
|
|
|
|
renderConfig,
|
|
|
|
transformHandles,
|
|
|
|
transformHandles,
|
|
|
|
locallySelectedElements[0].angle,
|
|
|
|
locallySelectedElements[0].angle,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (locallySelectedElements.length > 1 && !appState.isRotating) {
|
|
|
|
} else if (locallySelectedElements.length > 1 && !appState.isRotating) {
|
|
|
|
const dashedLinePadding = 4 / sceneState.zoom.value;
|
|
|
|
const dashedLinePadding = 4 / renderConfig.zoom.value;
|
|
|
|
context.fillStyle = oc.white;
|
|
|
|
context.fillStyle = oc.white;
|
|
|
|
const [x1, y1, x2, y2] = getCommonBounds(locallySelectedElements);
|
|
|
|
const [x1, y1, x2, y2] = getCommonBounds(locallySelectedElements);
|
|
|
|
const initialLineDash = context.getLineDash();
|
|
|
|
const initialLineDash = context.getLineDash();
|
|
|
|
context.setLineDash([2 / sceneState.zoom.value]);
|
|
|
|
context.setLineDash([2 / renderConfig.zoom.value]);
|
|
|
|
const lineWidth = context.lineWidth;
|
|
|
|
const lineWidth = context.lineWidth;
|
|
|
|
context.lineWidth = 1 / sceneState.zoom.value;
|
|
|
|
context.lineWidth = 1 / renderConfig.zoom.value;
|
|
|
|
strokeRectWithRotation(
|
|
|
|
strokeRectWithRotation(
|
|
|
|
context,
|
|
|
|
context,
|
|
|
|
x1 - dashedLinePadding,
|
|
|
|
x1 - dashedLinePadding,
|
|
|
@ -420,11 +409,11 @@ export const renderScene = (
|
|
|
|
const transformHandles = getTransformHandlesFromCoords(
|
|
|
|
const transformHandles = getTransformHandlesFromCoords(
|
|
|
|
[x1, y1, x2, y2],
|
|
|
|
[x1, y1, x2, y2],
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
sceneState.zoom,
|
|
|
|
renderConfig.zoom,
|
|
|
|
"mouse",
|
|
|
|
"mouse",
|
|
|
|
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
|
|
|
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
renderTransformHandles(context, sceneState, transformHandles, 0);
|
|
|
|
renderTransformHandles(context, renderConfig, transformHandles, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
context.restore();
|
|
|
|
context.restore();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -433,8 +422,8 @@ export const renderScene = (
|
|
|
|
context.restore();
|
|
|
|
context.restore();
|
|
|
|
|
|
|
|
|
|
|
|
// Paint remote pointers
|
|
|
|
// Paint remote pointers
|
|
|
|
for (const clientId in sceneState.remotePointerViewportCoords) {
|
|
|
|
for (const clientId in renderConfig.remotePointerViewportCoords) {
|
|
|
|
let { x, y } = sceneState.remotePointerViewportCoords[clientId];
|
|
|
|
let { x, y } = renderConfig.remotePointerViewportCoords[clientId];
|
|
|
|
|
|
|
|
|
|
|
|
x -= appState.offsetLeft;
|
|
|
|
x -= appState.offsetLeft;
|
|
|
|
y -= appState.offsetTop;
|
|
|
|
y -= appState.offsetTop;
|
|
|
@ -459,14 +448,14 @@ export const renderScene = (
|
|
|
|
context.strokeStyle = stroke;
|
|
|
|
context.strokeStyle = stroke;
|
|
|
|
context.fillStyle = background;
|
|
|
|
context.fillStyle = background;
|
|
|
|
|
|
|
|
|
|
|
|
const userState = sceneState.remotePointerUserStates[clientId];
|
|
|
|
const userState = renderConfig.remotePointerUserStates[clientId];
|
|
|
|
if (isOutOfBounds || userState === UserIdleState.AWAY) {
|
|
|
|
if (isOutOfBounds || userState === UserIdleState.AWAY) {
|
|
|
|
context.globalAlpha = 0.48;
|
|
|
|
context.globalAlpha = 0.48;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
sceneState.remotePointerButton &&
|
|
|
|
renderConfig.remotePointerButton &&
|
|
|
|
sceneState.remotePointerButton[clientId] === "down"
|
|
|
|
renderConfig.remotePointerButton[clientId] === "down"
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
context.beginPath();
|
|
|
|
context.beginPath();
|
|
|
|
context.arc(x, y, 15, 0, 2 * Math.PI, false);
|
|
|
|
context.arc(x, y, 15, 0, 2 * Math.PI, false);
|
|
|
@ -492,7 +481,7 @@ export const renderScene = (
|
|
|
|
context.fill();
|
|
|
|
context.fill();
|
|
|
|
context.stroke();
|
|
|
|
context.stroke();
|
|
|
|
|
|
|
|
|
|
|
|
const username = sceneState.remotePointerUsernames[clientId];
|
|
|
|
const username = renderConfig.remotePointerUsernames[clientId];
|
|
|
|
|
|
|
|
|
|
|
|
let idleState = "";
|
|
|
|
let idleState = "";
|
|
|
|
if (userState === UserIdleState.AWAY) {
|
|
|
|
if (userState === UserIdleState.AWAY) {
|
|
|
@ -552,7 +541,7 @@ export const renderScene = (
|
|
|
|
elements,
|
|
|
|
elements,
|
|
|
|
normalizedCanvasWidth,
|
|
|
|
normalizedCanvasWidth,
|
|
|
|
normalizedCanvasHeight,
|
|
|
|
normalizedCanvasHeight,
|
|
|
|
sceneState,
|
|
|
|
renderConfig,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
@ -579,7 +568,7 @@ export const renderScene = (
|
|
|
|
|
|
|
|
|
|
|
|
const renderTransformHandles = (
|
|
|
|
const renderTransformHandles = (
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
sceneState: SceneState,
|
|
|
|
renderConfig: RenderConfig,
|
|
|
|
transformHandles: TransformHandles,
|
|
|
|
transformHandles: TransformHandles,
|
|
|
|
angle: number,
|
|
|
|
angle: number,
|
|
|
|
): void => {
|
|
|
|
): void => {
|
|
|
@ -587,7 +576,7 @@ const renderTransformHandles = (
|
|
|
|
const transformHandle = transformHandles[key as TransformHandleType];
|
|
|
|
const transformHandle = transformHandles[key as TransformHandleType];
|
|
|
|
if (transformHandle !== undefined) {
|
|
|
|
if (transformHandle !== undefined) {
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.lineWidth = 1 / sceneState.zoom.value;
|
|
|
|
context.lineWidth = 1 / renderConfig.zoom.value;
|
|
|
|
if (key === "rotation") {
|
|
|
|
if (key === "rotation") {
|
|
|
|
fillCircle(
|
|
|
|
fillCircle(
|
|
|
|
context,
|
|
|
|
context,
|
|
|
@ -615,7 +604,7 @@ const renderTransformHandles = (
|
|
|
|
|
|
|
|
|
|
|
|
const renderSelectionBorder = (
|
|
|
|
const renderSelectionBorder = (
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
sceneState: SceneState,
|
|
|
|
renderConfig: RenderConfig,
|
|
|
|
elementProperties: {
|
|
|
|
elementProperties: {
|
|
|
|
angle: number;
|
|
|
|
angle: number;
|
|
|
|
elementX1: number;
|
|
|
|
elementX1: number;
|
|
|
@ -630,13 +619,13 @@ const renderSelectionBorder = (
|
|
|
|
const elementWidth = elementX2 - elementX1;
|
|
|
|
const elementWidth = elementX2 - elementX1;
|
|
|
|
const elementHeight = elementY2 - elementY1;
|
|
|
|
const elementHeight = elementY2 - elementY1;
|
|
|
|
|
|
|
|
|
|
|
|
const dashedLinePadding = 4 / sceneState.zoom.value;
|
|
|
|
const dashedLinePadding = 4 / renderConfig.zoom.value;
|
|
|
|
const dashWidth = 8 / sceneState.zoom.value;
|
|
|
|
const dashWidth = 8 / renderConfig.zoom.value;
|
|
|
|
const spaceWidth = 4 / sceneState.zoom.value;
|
|
|
|
const spaceWidth = 4 / renderConfig.zoom.value;
|
|
|
|
|
|
|
|
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.translate(sceneState.scrollX, sceneState.scrollY);
|
|
|
|
context.translate(renderConfig.scrollX, renderConfig.scrollY);
|
|
|
|
context.lineWidth = 1 / sceneState.zoom.value;
|
|
|
|
context.lineWidth = 1 / renderConfig.zoom.value;
|
|
|
|
|
|
|
|
|
|
|
|
const count = selectionColors.length;
|
|
|
|
const count = selectionColors.length;
|
|
|
|
for (let index = 0; index < count; ++index) {
|
|
|
|
for (let index = 0; index < count; ++index) {
|
|
|
@ -662,7 +651,7 @@ const renderSelectionBorder = (
|
|
|
|
|
|
|
|
|
|
|
|
const renderBindingHighlight = (
|
|
|
|
const renderBindingHighlight = (
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
context: CanvasRenderingContext2D,
|
|
|
|
sceneState: SceneState,
|
|
|
|
renderConfig: RenderConfig,
|
|
|
|
suggestedBinding: SuggestedBinding,
|
|
|
|
suggestedBinding: SuggestedBinding,
|
|
|
|
) => {
|
|
|
|
) => {
|
|
|
|
const renderHighlight = Array.isArray(suggestedBinding)
|
|
|
|
const renderHighlight = Array.isArray(suggestedBinding)
|
|
|
@ -670,7 +659,7 @@ const renderBindingHighlight = (
|
|
|
|
: renderBindingHighlightForBindableElement;
|
|
|
|
: renderBindingHighlightForBindableElement;
|
|
|
|
|
|
|
|
|
|
|
|
context.save();
|
|
|
|
context.save();
|
|
|
|
context.translate(sceneState.scrollX, sceneState.scrollY);
|
|
|
|
context.translate(renderConfig.scrollX, renderConfig.scrollY);
|
|
|
|
renderHighlight(context, suggestedBinding as any);
|
|
|
|
renderHighlight(context, suggestedBinding as any);
|
|
|
|
|
|
|
|
|
|
|
|
context.restore();
|
|
|
|
context.restore();
|
|
|
|