Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(edgeless): auto-connect indicator and index label #5136

Merged
merged 13 commits into from
Nov 1, 2023
32 changes: 22 additions & 10 deletions packages/blocks/src/_common/icons/edgeless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1099,20 +1099,19 @@ export const TextAlignRightIcon = html`<svg
</svg>`;

export const HiddenIcon = html`<svg
width="16"
height="17"
viewBox="0 0 16 17"
fill="currentColor"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.40665 7.11374C5.37002 7.67894 4.66667 8.77849 4.66667 10.0423C4.66667 11.8833 6.15905 13.3757 8 13.3757C9.26442 13.3757 10.3644 12.6716 10.9294 11.6342M14 10.0423C14 6.72861 11.3137 4.04232 8 4.04232C7.70546 4.04232 7.41587 4.06354 7.13268 4.10454M2 10.0423C2 8.04695 2.97403 6.27907 4.47256 5.18822M2 2.70898L14 14.709"
stroke="currentColor"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.59935 7.54961C4.35059 7.21842 3.88044 7.1516 3.54925 7.40037C3.21805 7.64913 3.15123 8.11928 3.4 8.45047C4.20228 9.51858 5.19941 10.4327 6.3387 11.1399L4.37594 14.084C4.14617 14.4287 4.2393 14.8943 4.58395 15.1241C4.9286 15.3538 5.39425 15.2607 5.62401 14.9161L7.62401 11.9161C7.64028 11.8917 7.65493 11.8667 7.66798 11.8412C8.77636 12.3299 9.98296 12.6369 11.25 12.7243V17.5C11.25 17.9143 11.5858 18.25 12 18.25C12.4142 18.25 12.75 17.9143 12.75 17.5V12.7243C14.017 12.637 15.2237 12.3301 16.3321 11.8415C16.3451 11.8669 16.3597 11.8918 16.3759 11.9161L18.3759 14.9161C18.6057 15.2607 19.0714 15.3538 19.416 15.1241C19.7606 14.8943 19.8538 14.4287 19.624 14.084L17.6615 11.1403C18.8011 10.433 19.7984 9.51878 20.6009 8.45047C20.8496 8.11928 20.7828 7.64913 20.4516 7.40037C20.1204 7.1516 19.6503 7.21842 19.4015 7.54961C17.7127 9.79805 15.0262 11.2501 12.0004 11.2501C8.97464 11.2501 6.28821 9.79805 4.59935 7.54961Z"
fill="#77757D"
/>
</svg>`;
</svg> `;

export const CardIcon = html`<svg
width="17"
Expand Down Expand Up @@ -2581,3 +2580,16 @@ export const ConnectorIcon = html`
/>
</svg>
`;

export const AutoConnectLeftIcon = svg`
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.68689 4.31313C9.88215 4.5084 9.88215 4.82498 9.68689 5.02024L6.70711 8.00002L9.68689 10.9798C9.88215 11.1751 9.88215 11.4916 9.68689 11.6869C9.49162 11.8822 9.17504 11.8822 8.97978 11.6869L5.64645 8.35357C5.45118 8.15831 5.45118 7.84173 5.64645 7.64647L8.97978 4.31313C9.17504 4.11787 9.49162 4.11787 9.68689 4.31313Z" fill="#77757D"/>
</svg>
`;

export const AutoConnectRightIcon = svg`
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.64661 4.31313C5.45135 4.5084 5.45135 4.82498 5.64661 5.02024L8.62639 8.00002L5.64661 10.9798C5.45135 11.1751 5.45135 11.4916 5.64661 11.6869C5.84187 11.8822 6.15845 11.8822 6.35372 11.6869L9.68705 8.35357C9.88231 8.15831 9.88231 7.84173 9.68705 7.64647L6.35372 4.31313C6.15845 4.11787 5.84187 4.11787 5.64661 4.31313Z" fill="#77757D"/>
</svg>

`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { WithDisposable } from '@blocksuite/lit';
import { css, LitElement, nothing, svg } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';

import { EdgelessBlockType } from '../../../../surface-block/edgeless-types.js';
import { Bound, type IVec, Vec } from '../../../../surface-block/index.js';
import type { SurfaceBlockComponent } from '../../../../surface-block/surface-block.js';
import { isNoteBlock } from '../../utils/query.js';

const { NOTE } = EdgelessBlockType;

@customElement('edgeless-auto-connect-line')
export class EdgelessAutoConnectLine extends WithDisposable(LitElement) {
static override styles = css`
:host {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
`;
@property({ attribute: false })
surface!: SurfaceBlockComponent;

@property({ attribute: false })
show = false;

protected override firstUpdated(): void {
const { _disposables, surface } = this;
_disposables.add(
surface.viewport.slots.viewportUpdated.on(() => {
this.requestUpdate();
})
);

_disposables.add(
surface.page.slots.blockUpdated.on(({ type, id }) => {
if (type === 'update' && isNoteBlock(surface.pickById(id))) {
this.requestUpdate();
}
})
);
}

protected override render() {
if (!this.show) return nothing;

const { viewport } = this.surface;
const notes = this.surface.getBlocks(NOTE).filter(note => !note.hidden);
const points: [IVec, IVec][] = [];
for (let i = 1; i < notes.length; i++) {
const last = notes[i - 1];
const current = notes[i];
const lastBound = Bound.deserialize(last.xywh);
const currentBound = Bound.deserialize(current.xywh);
const start = viewport.toViewCoord(lastBound.center[0], lastBound.maxY);
const end = viewport.toViewCoord(
currentBound.center[0],
currentBound.maxY
);
points.push([start, end]);
}
const expand = 20;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a const defined in top level of this module?


return repeat(
points,
(_, index) => index,
([start, end]) => {
const width = Math.abs(start[0] - end[0]);
const height = Math.abs(start[1] - end[1]);
const style = styleMap({
position: 'absolute',
transform: `translate(${Math.min(start[0], end[0]) - expand / 2}px, ${
Math.min(start[1], end[1]) - expand / 2
}px)`,
});
const lineStart = [0, 0];
const lineEnd = [width, height];
if (start[0] > end[0]) {
lineStart[0] = width;
lineEnd[0] = 0;
} else {
lineStart[0] = 0;
lineEnd[0] = width;
}

if (start[1] > end[1]) {
lineStart[1] = height;
lineEnd[1] = 0;
} else {
lineStart[1] = 0;
lineEnd[1] = height;
}

const newWidth = width + expand;
const newHeight = height + expand;

const newStart = Vec.add(Vec.pointOffset(lineStart, lineEnd, 16), [
expand / 2,
expand / 2,
]);
const newEnd = Vec.add(Vec.pointOffset(lineEnd, lineStart, 16), [
expand / 2,
expand / 2,
]);

return svg`
<svg style=${style} width="${newWidth}px" height="${newHeight}px" viewBox="0 0 ${newWidth} ${newHeight}" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker
id="arrow"
refX="10"
refY="10"
markerWidth="10"
markerHeight="20"
orient="auto"
>
<path d="M 2 2 L 10 10 L 2 18" fill="none" stroke="var(--affine-black-10)" stroke-linecap="round" stroke-linejoin="round" />
</marker>
</defs>

<line
x1="${newStart[0]}"
y1="${newStart[1]}"
x2="${newEnd[0]}"
y2="${newEnd[1]}"
stroke="var(--affine-black-10)"
stroke-width="2"
marker-end="url(#arrow)"
/>
</svg>
`;
}
);
}
}
Loading
Loading