Skip to content

Commit

Permalink
playground: lot of fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
draedful committed Oct 10, 2024
1 parent 9e09b8c commit f398f5e
Show file tree
Hide file tree
Showing 18 changed files with 210 additions and 86 deletions.
35 changes: 16 additions & 19 deletions src/components/canvas/anchors/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EventedComponent } from "../../../mixins/withEvents";
import { withHitTest } from "../../../mixins/withHitTest";
import { debugHitBox, withHitTest } from "../../../mixins/withHitTest";
import { ECameraScaleLevel } from "../../../services/camera/CameraService";
import { frameDebouncer } from "../../../services/optimizations/frameDebouncer";
import { AnchorState, EAnchorType } from "../../../store/anchor/Anchor";
Expand All @@ -13,7 +13,7 @@ export type TAnchor = {
id: string;
blockId: TBlockId;
type: EAnchorType | string;
index: number;
index?: number;
};

export type TAnchorProps = TAnchor & {
Expand Down Expand Up @@ -48,7 +48,7 @@ export class Anchor extends withHitTest(EventedComponent) {

private shift: number;

private hitBoxHash: number;
private hitBoxHash: string;

private debouncedSetHitBox: (...args: any[]) => void;

Expand Down Expand Up @@ -102,9 +102,18 @@ export class Anchor extends withHitTest(EventedComponent) {

public willIterate() {
super.willIterate();
const { x: poxX, y: posY } = this.props.getPosition(this.props);
const hash = `${poxX}/${posY}/${this.shift}`;

if (this.hitBoxHash !== hash) {
this.hitBoxHash = hash;
this.debouncedSetHitBox();
}

const { x, y, width, height } = this.hitBox.getRect();

this.shouldRender = width && height ? this.context.camera.isRectVisible(x, y, width, height) : true;

}

public handleEvent(event: MouseEvent | KeyboardEvent) {
Expand All @@ -115,14 +124,16 @@ export class Anchor extends withHitTest(EventedComponent) {
case "click":
this.toggleSelected();
break;
case "mouseenter":
case "mouseenter":{
this.setState({ raised: true });
this.computeRenderSize(this.props.size, true);
break;
case "mouseleave":
}
case "mouseleave": {
this.setState({ raised: false });
this.computeRenderSize(this.props.size, false);
break;
}
}
}

Expand All @@ -131,18 +142,6 @@ export class Anchor extends withHitTest(EventedComponent) {
this.setHitBox(x - this.shift, y - this.shift, x + this.shift, y + this.shift);
}

public didRender() {
super.didRender();
const { x, y } = this.props.getPosition(this.props);

const hash = x / y + this.shift;

if (this.hitBoxHash !== hash) {
this.hitBoxHash = hash;
this.debouncedSetHitBox();
}
}

private computeRenderSize(size: number, raised: boolean) {
if (raised) {
this.setState({ size: size * 1.8 });
Expand All @@ -152,8 +151,6 @@ export class Anchor extends withHitTest(EventedComponent) {
}

protected render() {
// debugHitBox(this.context.ctx, this);

if (this.context.camera.getCameraBlockScaleLevel() === ECameraScaleLevel.Detailed) {
return;
}
Expand Down
9 changes: 8 additions & 1 deletion src/components/canvas/blocks/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ export class Block<T extends TBlock = TBlock, Props extends TBlockProps = TBlock
});
this.updateHitBox(this.connectedState.$geometry.value);
}),
this.connectedState.$anchors.subscribe(() => {
this.shouldUpdateChildren = true;
this.performRender();
})
];
}

Expand Down Expand Up @@ -334,10 +338,11 @@ export class Block<T extends TBlock = TBlock, Props extends TBlockProps = TBlock

/* Calculate the position of the anchors relative to the block container. */
public getAnchorPosition(anchor: TAnchor): TPoint {
const index = this.connectedState.$anchorIndexs.value?.get(anchor.id) || 0;
const offset = this.context.constants.block.HEAD_HEIGHT + this.context.constants.block.BODY_PADDING;
return {
x: anchor.type === EAnchorType.OUT ? this.state.width : 0,
y: offset + anchor.index * this.context.constants.system.GRID_SIZE * 2,
y: offset + index * this.context.constants.system.GRID_SIZE * 2,
};
}

Expand All @@ -355,6 +360,8 @@ export class Block<T extends TBlock = TBlock, Props extends TBlockProps = TBlock
size: 18,
lineWidth: 2,
getPosition,
}, {
key: anchor.id
});
}

Expand Down
9 changes: 1 addition & 8 deletions src/components/canvas/layers/graphLayer/GraphLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export class GraphLayer extends Layer<TGraphLayerProps, TGraphLayerContext> {

this.eventByTargetComponent = event;

const point = this.getTargetPoint(event);
const point = this.context.graph.getPointInCameraSpace(event);

this.targetComponent = this.context.graph.getElementOverPoint(point) || this.$.camera;
}
Expand Down Expand Up @@ -269,13 +269,6 @@ export class GraphLayer extends Layer<TGraphLayerProps, TGraphLayerContext> {
return this.onRootPointerStart(event);
};

private getTargetPoint(event: MouseEvent) {
const xy = getXY(this.context.canvas, event);

const applied = this.camera.applyToPoint(xy[0], xy[1]);
return new Point(applied[0], applied[1], { x: xy[0], y: xy[1] });
}

private onRootPointerStart(event: MouseEvent) {
if (event.button === 2 /* Mouse right button */) {
/*
Expand Down
26 changes: 10 additions & 16 deletions src/react-component/Anchor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { computed } from "@preact/signals-core";
import { TAnchor } from "../components/canvas/anchors";
import { Graph } from "../graph";
import { useSignal } from "./hooks";
import { useBlockAnchorState } from "./hooks/useBlockAnchorState";
import { useBlockAnchorPosition, useBlockAnchorState } from "./hooks/useBlockAnchorState";
import { AnchorState } from "../store/anchor/Anchor";

import "./Anchor.css";
Expand All @@ -26,22 +26,16 @@ export function GraphBlockAnchor({

const anchorState = useBlockAnchorState(graph, anchor);

useEffect(() => {
if (!container.current) {
return;
useBlockAnchorPosition(anchorState, (position) => {
if (position) {
setCssProps(container.current, {
"--graph-block-anchor-x": `${position.x}px`,
"--graph-block-anchor-y": `${position.y}px`,
});
} else {
removeCssProps(container.current, ["--graph-block-anchor-x", "--graph-block-anchor-y"]);
}
if (position === "absolute") {
const position = anchorState.block.getViewComponent().getAnchorPosition(anchor);
if (position) {
setCssProps(container.current, {
"--graph-block-anchor-x": `${position.x}px`,
"--graph-block-anchor-y": `${position.y}px`,
});
} else {
removeCssProps(container.current, ["--graph-block-anchor-x", "--graph-block-anchor-y"]);
}
}
}, [container, position, anchorState, anchor]);
})

const selectedSignal = useMemo(() => {
return computed(() => {
Expand Down
4 changes: 4 additions & 0 deletions src/react-component/Block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export const GraphBlock = <T extends TBlock>({
}
}, [viewState, containerRef]);

if(!viewState || !state) {
return;
}


return (
<div className={`graph-block-container ${containerClassName}`} ref={containerRef}>
Expand Down
19 changes: 18 additions & 1 deletion src/react-component/hooks/useBlockAnchorState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { useSignal } from "./useSignal";
import { useBlockState } from "./useBlockState";
import { AnchorState } from "../../store/anchor/Anchor";
import { computed } from "@preact/signals-core";
import { useMemo } from "react";
import { useEffect, useMemo, useRef } from "react";
import debounce from "lodash/debounce";

export function useBlockAnchorState(graph: Graph, anchor: TAnchor): AnchorState | undefined {
const blockState = useBlockState(graph, anchor.blockId);
Expand All @@ -13,3 +14,19 @@ export function useBlockAnchorState(graph: Graph, anchor: TAnchor): AnchorState
}, [blockState, anchor]);
return useSignal(signal);
}

export function useBlockAnchorPosition(state: AnchorState | undefined, onUpdate: (position: {x: number, y: number}) => void) {
const fnRef = useRef(onUpdate);
fnRef.current = onUpdate;

useEffect(() => {
if(!state) {
return;
}
return state.block.$geometry.subscribe(debounce(() => {
const position = state.block.getViewComponent().getAnchorPosition(state.state);
fnRef.current(position);
}, 16))
}, [state.block])
}

9 changes: 2 additions & 7 deletions src/services/newConnection/ConnectionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,10 @@ export class ConnectionService extends Emitter {
}

public onMoveNewConnection(event: MouseEvent, point: Point) {
this.emit(EVENTS.NEW_CONNECTION_UPDATE, event);

const newTargetComponent = this.graph.getElementOverPoint(point, [Block, Anchor]);

this.emit(EVENTS.NEW_CONNECTION_UPDATE, { target: newTargetComponent, event });

if (!(newTargetComponent instanceof Block) || !(newTargetComponent instanceof Anchor)) {
return;
}

/* Unset selection on move new selection target-point out of components */
if (!newTargetComponent || !newTargetComponent.connectedState) {
this.targetComponent?.setSelection(false);
this.targetComponent = undefined;
Expand Down
31 changes: 23 additions & 8 deletions src/services/newConnection/NewConnection.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Anchor } from "../../components/canvas/anchors";
import { Block } from "../../components/canvas/blocks/Block";
import { OverLayer, TOverLayerContext } from "../../components/canvas/layers/overLayer/OverLayer";
import { Component } from "../../lib/Component";
import { getXY } from "../../utils/functions";
Expand Down Expand Up @@ -47,13 +49,23 @@ export class NewConnection extends Component {
ctx.roundRect(this.state.tx, this.state.ty - 12, 24, 24, 8);
ctx.fill();
ctx.fillStyle = this.context.colors.canvas.belowLayerBackground;
renderSVG({
path: `M7 0.75C7.41421 0.75 7.75 1.08579 7.75 1.5V6.25H12.5C12.9142 6.25 13.25 6.58579 13.25 7C13.25 7.41421 12.9142 7.75 12.5 7.75H7.75V12.5C7.75 12.9142 7.41421 13.25 7 13.25C6.58579 13.25 6.25 12.9142 6.25 12.5V7.75H1.5C1.08579 7.75 0.75 7.41421 0.75 7C0.75 6.58579 1.08579 6.25 1.5 6.25H6.25V1.5C6.25 1.08579 6.58579 0.75 7 0.75Z`,
width: 14,
height: 14,
iniatialWidth: 14,
initialHeight: 14
}, ctx, { x: this.state.tx, y: this.state.ty - 12, width: 24, height: 24 })
if(!this.target) {
renderSVG({
path: `M7 0.75C7.41421 0.75 7.75 1.08579 7.75 1.5V6.25H12.5C12.9142 6.25 13.25 6.58579 13.25 7C13.25 7.41421 12.9142 7.75 12.5 7.75H7.75V12.5C7.75 12.9142 7.41421 13.25 7 13.25C6.58579 13.25 6.25 12.9142 6.25 12.5V7.75H1.5C1.08579 7.75 0.75 7.41421 0.75 7C0.75 6.58579 1.08579 6.25 1.5 6.25H6.25V1.5C6.25 1.08579 6.58579 0.75 7 0.75Z`,
width: 14,
height: 14,
iniatialWidth: 14,
initialHeight: 14
}, ctx, { x: this.state.tx, y: this.state.ty - 12, width: 24, height: 24 });
} else {
renderSVG({
path: `M15.53 1.53A.75.75 0 0 0 14.47.47l-1.29 1.29a4.24 4.24 0 0 0-5.423.483l-.58.58a.96.96 0 0 0 0 1.354l4.646 4.646a.96.96 0 0 0 1.354 0l.58-.58a4.24 4.24 0 0 0 .484-5.423zm-8.5 4.94a.75.75 0 0 1 0 1.06L5.78 8.78l1.44 1.44 1.25-1.25a.75.75 0 0 1 1.06 1.06l-1.25 1.25.543.543a.96.96 0 0 1 0 1.354l-.58.58a4.24 4.24 0 0 1-5.423.484l-1.29 1.29A.75.75 0 0 1 .47 14.47l1.29-1.29a4.24 4.24 0 0 1 .483-5.423l.58-.58a.96.96 0 0 1 1.354 0l.543.543 1.25-1.25a.75.75 0 0 1 1.06 0M3.5 8.62l-.197.197a2.743 2.743 0 0 0 3.879 3.879l.197-.197zm9.197-1.439-.197.197L8.621 3.5l.197-.197a2.743 2.743 0 0 1 3.879 3.879`,
width: 14,
height: 14,
iniatialWidth: 16,
initialHeight: 16
}, ctx, { x: this.state.tx, y: this.state.ty - 12, width: 24, height: 24 });
}
})
}

Expand All @@ -66,7 +78,10 @@ export class NewConnection extends Component {
});
};

private updateNewConnectionRender = (event: MouseEvent) => {
protected target?: Block | Anchor;

private updateNewConnectionRender = ({target, event}: { target?: Block | Anchor, event: MouseEvent }) => {
this.target = target;
const xy = getXY(this.context.graphCanvas, event);
this.setState({
tx: xy[0],
Expand Down
4 changes: 4 additions & 0 deletions src/store/anchor/Anchor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export class AnchorState {
return this.$state.value.blockId;
}

public get state() {
return this.$state.value
}

public constructor(
public readonly block: BlockState,
anchor: TAnchor
Expand Down
18 changes: 14 additions & 4 deletions src/store/block/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ export class BlockState<T extends TBlock = TBlock> {

public readonly $anchorStates: Signal<AnchorState[]> = signal([]);

public $anchorIndexs = computed(() => {
const typeIndex = {};
return new Map(this.$anchorStates.value?.sort((a, b) => ((a.state.index || 0) - (b.state.index || 0)) ).map((anchorState) => {
if (!typeIndex[anchorState.state.type]) {
typeIndex[anchorState.state.type] = 0;
}
return [anchorState.id, typeIndex[anchorState.state.type]++];
}) || []);
});

public $anchors = computed(() => {
return this.$anchorStates.value?.map((anchorState) => anchorState.asTAnchor()) || [];
});
Expand All @@ -50,8 +60,6 @@ export class BlockState<T extends TBlock = TBlock> {

private blockView: Block;

public readonly dispose;

public constructor(
public readonly store: BlockListStore,
block: T
Expand Down Expand Up @@ -113,7 +121,7 @@ export class BlockState<T extends TBlock = TBlock> {

public updateAnchors(anchors: TAnchor[]) {
const anchorsMap = new Map(this.$anchorStates.value.map((a) => [a.id, a]));
this.$anchorStates.value = anchors.filter((a) => a.blockId === this.id).map((anchor) => {
this.$anchorStates.value = anchors.map((anchor) => {
if (anchorsMap.has(anchor.id)) {
const anchorState = anchorsMap.get(anchor.id);
anchorState.update(anchor);
Expand All @@ -125,7 +133,9 @@ export class BlockState<T extends TBlock = TBlock> {

public updateBlock(block: Partial<TBlock>): void {
this.$state.value = Object.assign({}, this.$state.value, block);
this.updateAnchors(block.anchors);
if (block.anchors) {
this.updateAnchors(block.anchors);
}
this.getViewComponent()?.updateHitBox(this.$geometry.value, true);
}

Expand Down
1 change: 0 additions & 1 deletion src/store/block/BlocksList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ export class BlockListStore {
const selectedBlocks = this.$selectedBlocks.value;
selectedBlocks.forEach((block) => {
this.deleteAllBlockConnections(block.id);
block.dispose();
});
const newBlocks = this.$blocks.value.filter((block) => !selectedBlocks.includes(block));
this.applyBlocksState(newBlocks);
Expand Down
2 changes: 1 addition & 1 deletion src/stories/Playground/Editor/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function defineConigSchema(monaco: Monaco) {
"description": "Anchor index"
}
},
"required": ["id", "blockId", "type", "index"]
"required": ["id", "blockId", "type"]
}
}
},
Expand Down
Loading

0 comments on commit f398f5e

Please sign in to comment.