mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-14 09:45:27 +01:00
POC: highlight center on hover
This commit is contained in:
@@ -2072,6 +2072,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<InteractiveCanvas
|
<InteractiveCanvas
|
||||||
|
app={this}
|
||||||
containerRef={this.excalidrawContainerRef}
|
containerRef={this.excalidrawContainerRef}
|
||||||
canvas={this.interactiveCanvas}
|
canvas={this.interactiveCanvas}
|
||||||
elementsMap={elementsMap}
|
elementsMap={elementsMap}
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ import type {
|
|||||||
RenderableElementsMap,
|
RenderableElementsMap,
|
||||||
RenderInteractiveSceneCallback,
|
RenderInteractiveSceneCallback,
|
||||||
} from "../../scene/types";
|
} from "../../scene/types";
|
||||||
import type { AppState, Device, InteractiveCanvasAppState } from "../../types";
|
import type {
|
||||||
|
AppClassProperties,
|
||||||
|
AppState,
|
||||||
|
Device,
|
||||||
|
InteractiveCanvasAppState,
|
||||||
|
} from "../../types";
|
||||||
import type { DOMAttributes } from "react";
|
import type { DOMAttributes } from "react";
|
||||||
|
|
||||||
type InteractiveCanvasProps = {
|
type InteractiveCanvasProps = {
|
||||||
@@ -36,6 +41,7 @@ type InteractiveCanvasProps = {
|
|||||||
appState: InteractiveCanvasAppState;
|
appState: InteractiveCanvasAppState;
|
||||||
renderScrollbars: boolean;
|
renderScrollbars: boolean;
|
||||||
device: Device;
|
device: Device;
|
||||||
|
app: AppClassProperties;
|
||||||
renderInteractiveSceneCallback: (
|
renderInteractiveSceneCallback: (
|
||||||
data: RenderInteractiveSceneCallback,
|
data: RenderInteractiveSceneCallback,
|
||||||
) => void;
|
) => void;
|
||||||
@@ -145,6 +151,8 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
|||||||
remotePointerUserStates,
|
remotePointerUserStates,
|
||||||
selectionColor,
|
selectionColor,
|
||||||
renderScrollbars: props.renderScrollbars,
|
renderScrollbars: props.renderScrollbars,
|
||||||
|
// NOTE not memoized on so we don't rerender on cursor move
|
||||||
|
lastViewportPosition: props.app.lastViewportPosition,
|
||||||
},
|
},
|
||||||
device: props.device,
|
device: props.device,
|
||||||
callback: props.renderInteractiveSceneCallback,
|
callback: props.renderInteractiveSceneCallback,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
pointDistance,
|
||||||
pointFrom,
|
pointFrom,
|
||||||
pointsEqual,
|
pointsEqual,
|
||||||
type GlobalPoint,
|
type GlobalPoint,
|
||||||
@@ -14,6 +15,7 @@ import {
|
|||||||
invariant,
|
invariant,
|
||||||
THEME,
|
THEME,
|
||||||
throttleRAF,
|
throttleRAF,
|
||||||
|
viewportCoordsToSceneCoords,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -192,6 +194,7 @@ const renderBindingHighlightForBindableElement = (
|
|||||||
elementsMap: RenderableElementsMap,
|
elementsMap: RenderableElementsMap,
|
||||||
allElementsMap: NonDeletedSceneElementsMap,
|
allElementsMap: NonDeletedSceneElementsMap,
|
||||||
appState: InteractiveCanvasAppState,
|
appState: InteractiveCanvasAppState,
|
||||||
|
renderConfig: InteractiveCanvasRenderConfig,
|
||||||
) => {
|
) => {
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case "magicframe":
|
case "magicframe":
|
||||||
@@ -337,16 +340,32 @@ const renderBindingHighlightForBindableElement = (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { x: cursorX, y: cursorY } = viewportCoordsToSceneCoords(
|
||||||
|
{
|
||||||
|
clientX: renderConfig.lastViewportPosition.x,
|
||||||
|
clientY: renderConfig.lastViewportPosition.y,
|
||||||
|
},
|
||||||
|
appState,
|
||||||
|
);
|
||||||
|
|
||||||
// Draw center snap area
|
// Draw center snap area
|
||||||
context.save();
|
context.save();
|
||||||
context.translate(element.x + appState.scrollX, element.y + appState.scrollY);
|
context.translate(element.x + appState.scrollX, element.y + appState.scrollY);
|
||||||
context.strokeStyle = "rgba(0, 0, 0, 0.1)";
|
context.strokeStyle = "rgba(0, 0, 0, 0.2)";
|
||||||
context.lineWidth = 1 / appState.zoom.value;
|
context.lineWidth = 1 / appState.zoom.value;
|
||||||
context.setLineDash([4 / appState.zoom.value, 4 / appState.zoom.value]);
|
context.setLineDash([4 / appState.zoom.value, 4 / appState.zoom.value]);
|
||||||
context.lineDashOffset = 0;
|
context.lineDashOffset = 0;
|
||||||
context.fillStyle = "rgba(0, 0, 0, 0.01)";
|
|
||||||
|
|
||||||
const radius = 0.5 * (Math.min(element.width, element.height) / 2);
|
const radius = 0.5 * (Math.min(element.width, element.height) / 2);
|
||||||
|
const centerX = element.x + element.width / 2;
|
||||||
|
const centerY = element.y + element.height / 2;
|
||||||
|
|
||||||
|
const isInsideEllipse =
|
||||||
|
pointDistance(pointFrom(cursorX, cursorY), pointFrom(centerX, centerY)) <=
|
||||||
|
radius;
|
||||||
|
|
||||||
|
context.fillStyle = isInsideEllipse ? "rgba(0, 0, 0, 0.04)" : "transparent";
|
||||||
|
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.ellipse(
|
context.ellipse(
|
||||||
element.width / 2,
|
element.width / 2,
|
||||||
@@ -899,6 +918,7 @@ const _renderInteractiveScene = ({
|
|||||||
elementsMap,
|
elementsMap,
|
||||||
allElementsMap,
|
allElementsMap,
|
||||||
appState,
|
appState,
|
||||||
|
renderConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ export type InteractiveCanvasRenderConfig = {
|
|||||||
remotePointerUsernames: Map<SocketId, string>;
|
remotePointerUsernames: Map<SocketId, string>;
|
||||||
remotePointerButton: Map<SocketId, string | undefined>;
|
remotePointerButton: Map<SocketId, string | undefined>;
|
||||||
selectionColor: string;
|
selectionColor: string;
|
||||||
|
lastViewportPosition: { x: number; y: number };
|
||||||
// extra options passed to the renderer
|
// extra options passed to the renderer
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
renderScrollbars?: boolean;
|
renderScrollbars?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user