diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/icons.ts b/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/icons.ts
deleted file mode 100644
index 0881074304..0000000000
--- a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/icons.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { html } from 'lit';
-
-export const LassoFreeHandIcon = html`
-
-`;
-
-export const LassoPolygonalIcon = html`
-
-`;
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-dense-menu.ts b/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-dense-menu.ts
deleted file mode 100644
index ca82117540..0000000000
--- a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-dense-menu.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { menu } from '@blocksuite/affine-components/context-menu';
-import { LassoMode } from '@blocksuite/affine-shared/types';
-import type { DenseMenuBuilder } from '@blocksuite/affine-widget-edgeless-toolbar';
-
-import { LassoFreeHandIcon, LassoPolygonalIcon } from './icons.js';
-
-export const buildLassoDenseMenu: DenseMenuBuilder = (_, gfx) => {
- // TODO: active state
- // const prevMode =
- // edgeless.service.editPropsStore.getLastProps('lasso').mode ??
- // LassoMode.FreeHand;
-
- const isActive = gfx.tool.currentToolName$.peek() === 'lasso';
-
- const createSelect = (mode: LassoMode) => () => {
- gfx.tool.setTool('lasso', { mode });
- };
-
- return menu.subMenu({
- name: 'Lasso',
- prefix: LassoFreeHandIcon,
- select: createSelect(LassoMode.FreeHand),
- isSelected: isActive,
- options: {
- items: [
- menu.action({
- prefix: LassoFreeHandIcon,
- name: 'Free',
- select: createSelect(LassoMode.FreeHand),
- // isSelected: isActive && prevMode === LassoMode.FreeHand,
- }),
- menu.action({
- prefix: LassoPolygonalIcon,
- name: 'Polygonal',
- select: createSelect(LassoMode.Polygonal),
- // isSelected: isActive && prevMode === LassoMode.Polygonal,
- }),
- ],
- },
- });
-};
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-tool-button.ts b/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-tool-button.ts
deleted file mode 100644
index 76a673b3d7..0000000000
--- a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/lasso/lasso-tool-button.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { LassoMode } from '@blocksuite/affine-shared/types';
-import { QuickToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
-import { WithDisposable } from '@blocksuite/global/lit';
-import { effect } from '@preact/signals-core';
-import { css, html, LitElement } from 'lit';
-import { query, state } from 'lit/decorators.js';
-
-import { LassoFreeHandIcon, LassoPolygonalIcon } from './icons.js';
-
-export class EdgelessLassoToolButton extends QuickToolMixin(
- WithDisposable(LitElement)
-) {
- static override styles = css`
- .current-icon {
- transition: 100ms;
- width: 24px;
- height: 24px;
- }
- .current-icon > svg {
- display: block;
- }
- `;
-
- private readonly _changeTool = () => {
- const tool = this.edgelessTool;
- if (tool.type !== 'lasso') {
- this.setEdgelessTool({ type: 'lasso', mode: this.curMode });
- return;
- }
-
- this._fadeOut();
- setTimeout(() => {
- this.curMode === LassoMode.FreeHand
- ? this.setEdgelessTool({ type: 'lasso', mode: LassoMode.Polygonal })
- : this.setEdgelessTool({ type: 'lasso', mode: LassoMode.FreeHand });
- this._fadeIn();
- }, 100);
- };
-
- override type = 'lasso' as const;
-
- private _fadeIn() {
- this.currentIcon.style.opacity = '1';
- this.currentIcon.style.transform = `translateY(0px)`;
- }
-
- private _fadeOut() {
- this.currentIcon.style.opacity = '0';
- this.currentIcon.style.transform = `translateY(-5px)`;
- }
-
- override connectedCallback(): void {
- super.connectedCallback();
-
- this.disposables.add(
- effect(() => {
- const tool = this.gfx.tool.currentToolOption$.value;
-
- if (tool?.type === 'lasso') {
- const { mode } = tool;
- this.curMode = mode;
- }
- })
- );
- }
-
- override render() {
- const type = this.edgelessTool?.type;
- const mode = this.curMode === LassoMode.FreeHand ? 'freehand' : 'polygonal';
-
- return html`
- `}
- .tooltipOffset=${17}
- .active=${type === 'lasso'}
- .iconContainerPadding=${6}
- .iconSize=${'24px'}
- @click=${this._changeTool}
- >
-
- ${this.curMode === LassoMode.FreeHand
- ? LassoFreeHandIcon
- : LassoPolygonalIcon}
-
-
-
- `;
- }
-
- @state()
- accessor curMode: LassoMode = LassoMode.FreeHand;
-
- @query('.current-icon')
- accessor currentIcon!: HTMLInputElement;
-}
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-builtin-spec.ts b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-builtin-spec.ts
index aa3613559a..90b8ed768f 100644
--- a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-builtin-spec.ts
+++ b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-builtin-spec.ts
@@ -29,7 +29,6 @@ import { DblClickAddEdgelessText } from './element-transform/dblclick-add-edgele
import { SnapExtension } from './element-transform/snap-manager.js';
import { DefaultTool } from './gfx-tool/default-tool.js';
import { EmptyTool } from './gfx-tool/empty-tool.js';
-import { LassoTool } from './gfx-tool/lasso-tool.js';
import { PanTool } from './gfx-tool/pan-tool.js';
import { TemplateTool } from './gfx-tool/template-tool.js';
import { EditPropsMiddlewareBuilder } from './middlewares/base.js';
@@ -47,7 +46,6 @@ export const EdgelessToolExtension: ExtensionType[] = [
TemplateTool,
EmptyTool,
FrameTool,
- LassoTool,
PresentTool,
HighlighterTool,
];
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-keyboard.ts b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-keyboard.ts
index 4a7dc143c0..1df0ce912d 100644
--- a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-keyboard.ts
+++ b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-keyboard.ts
@@ -26,10 +26,8 @@ import {
} from '@blocksuite/affine-model';
import {
EditPropsStore,
- FeatureFlagService,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
-import { LassoMode } from '@blocksuite/affine-shared/types';
import { matchModels } from '@blocksuite/affine-shared/utils';
import { IS_MAC } from '@blocksuite/global/env';
import { Bound, getCommonBound } from '@blocksuite/global/gfx';
@@ -44,7 +42,6 @@ import {
import { PageKeyboardManager } from '../keyboard/keyboard-manager.js';
import type { EdgelessRootBlockComponent } from './edgeless-root-block.js';
-import { LassoTool } from './gfx-tool/lasso-tool.js';
import {
DEFAULT_NOTE_CHILD_FLAVOUR,
DEFAULT_NOTE_CHILD_TYPE,
@@ -76,40 +73,6 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
});
this._setEdgelessTool('connector', { mode });
},
- l: () => {
- if (
- !rootComponent.doc
- .get(FeatureFlagService)
- .getFlag('enable_lasso_tool')
- ) {
- return;
- }
-
- this._setEdgelessTool('lasso', {
- mode: LassoMode.Polygonal,
- });
- },
- 'Shift-l': () => {
- if (
- !rootComponent.doc
- .get(FeatureFlagService)
- .getFlag('enable_lasso_tool')
- ) {
- return;
- }
- // toggle between lasso modes
- const edgeless = rootComponent;
- const cur = edgeless.gfx.tool.currentTool$.peek();
-
- this._setEdgelessTool('lasso', {
- mode:
- cur?.toolName === 'lasso'
- ? (cur as LassoTool).activatedOption.mode === LassoMode.FreeHand
- ? LassoMode.Polygonal
- : LassoMode.FreeHand
- : LassoMode.FreeHand,
- });
- },
h: () => {
this._setEdgelessTool('pan', {
panning: false,
@@ -324,11 +287,6 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
this._delete();
},
Escape: () => {
- const currentTool = this.rootComponent.gfx.tool.currentTool$.peek();
- if (currentTool instanceof LassoTool && currentTool.isSelecting) {
- currentTool.abort();
- }
-
if (!this.rootComponent.service.selection.empty) {
rootComponent.selection.clear();
}
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/index.ts b/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/index.ts
index b703333308..54c30e114a 100644
--- a/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/index.ts
+++ b/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/index.ts
@@ -1,5 +1,4 @@
export { DefaultTool } from './default-tool.js';
export { EmptyTool } from './empty-tool.js';
-export { LassoTool, type LassoToolOption } from './lasso-tool.js';
export { PanTool, type PanToolOption } from './pan-tool.js';
export { TemplateTool } from './template-tool.js';
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/lasso-tool.ts b/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/lasso-tool.ts
deleted file mode 100644
index 3d1658d3ec..0000000000
--- a/blocksuite/affine/blocks/block-root/src/edgeless/gfx-tool/lasso-tool.ts
+++ /dev/null
@@ -1,326 +0,0 @@
-import {
- Overlay,
- type SurfaceBlockComponent,
-} from '@blocksuite/affine-block-surface';
-import { ThemeProvider } from '@blocksuite/affine-shared/services';
-import { LassoMode } from '@blocksuite/affine-shared/types';
-import type { IPoint, IVec } from '@blocksuite/global/gfx';
-import {
- Bound,
- getBoundFromPoints,
- getPolygonPathFromPoints,
- getSvgPathFromStroke,
- linePolygonIntersects,
- pointInPolygon,
- rotatePoints,
- Vec,
-} from '@blocksuite/global/gfx';
-import type { PointerEventState } from '@blocksuite/std';
-import { BaseTool } from '@blocksuite/std/gfx';
-
-class LassoOverlay extends Overlay {
- d = '';
-
- startPoint: IVec | null = null;
-
- render(ctx: CanvasRenderingContext2D): void {
- const path = new Path2D(this.d);
- const zoom = this._renderer?.viewport.zoom ?? 1.0;
- ctx.save();
- const primaryColor = this.gfx.std
- .get(ThemeProvider)
- .getCssVariableColor('--affine-primary-color');
- const strokeColor = this.gfx.std
- .get(ThemeProvider)
- .getCssVariableColor('--affine-secondary-color');
- if (this.startPoint) {
- const [x, y] = this.startPoint;
- ctx.beginPath();
- ctx.arc(x, y, 2 / zoom, 0, Math.PI * 2);
- ctx.fillStyle = primaryColor;
- ctx.fill();
- }
-
- ctx.strokeStyle = strokeColor;
- ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
- ctx.lineWidth = 2 / zoom;
- ctx.lineJoin = 'round';
- ctx.lineCap = 'round';
- ctx.setLineDash([2, 5]);
- ctx.fill(path);
- ctx.stroke(path);
- ctx.restore();
- }
-}
-
-export type LassoToolOption = {
- mode: LassoMode;
-};
-export class LassoTool extends BaseTool {
- static override toolName: string = 'lasso';
-
- private _currentSelectionState = new Set();
-
- private _isSelecting = false;
-
- private _lassoPoints: IVec[] = [];
-
- private _lastPoint: IVec = [0, 0];
-
- private readonly _loop = () => {
- const path =
- this.activatedOption.mode === LassoMode.FreeHand
- ? getSvgPathFromStroke(this._lassoPoints)
- : getPolygonPathFromPoints(this._lassoPoints);
-
- this._overlay.d = path;
- (this.gfx.surfaceComponent as SurfaceBlockComponent)?.refresh?.();
- this._raf = requestAnimationFrame(this._loop);
- };
-
- private readonly _overlay = new LassoOverlay(this.gfx);
-
- private _raf = 0;
-
- get isSelecting() {
- return this._isSelecting;
- }
-
- get selection() {
- return this.gfx.selection;
- }
-
- get surfaceComponent() {
- return this.gfx.surfaceComponent as SurfaceBlockComponent;
- }
-
- private _clearLastSelection() {
- if (this.selection.empty) {
- this.selection.clearLast();
- }
- }
-
- private _getElementsInsideLasso() {
- const lassoBounds = getBoundFromPoints(this._lassoPoints);
- return this.gfx
- .getElementsByBound(lassoBounds)
- .filter(e =>
- this.isInsideLassoSelection(Bound.deserialize(e.xywh), e.rotate)
- );
- }
-
- private _getSelectionMode(ev: PointerEventState): 'add' | 'sub' | 'set' {
- const shiftKey = ev.keys.shift ?? this.gfx.keyboard.shiftKey$.peek();
- const altKey = ev.keys.alt ?? false;
- if (shiftKey) return 'add';
- else if (altKey) return 'sub';
- else {
- return 'set';
- }
- }
-
- private _reset() {
- cancelAnimationFrame(this._raf);
- (
- this.gfx.surfaceComponent as SurfaceBlockComponent
- )?.renderer.removeOverlay(this._overlay);
- this._overlay.d = '';
- this._overlay.startPoint = null;
-
- const elements = this._getElementsInsideLasso();
-
- this._currentSelectionState = new Set([
- ...Array.from(this._currentSelectionState),
- ...elements.map(el => el.id),
- ]);
-
- this._lassoPoints = [];
- this._isSelecting = false;
- }
-
- private _setSelectionState(elements: string[], editing: boolean) {
- this.selection.set({
- elements,
- editing,
- });
- }
-
- private _updateSelection(e: PointerEventState) {
- // elements inside the lasso selection
- const elements = this._getElementsInsideLasso()
- .filter(el => !el.isLocked())
- .map(el => el.id);
-
- // current selections
- const selection = this.selection.selectedElements.map(el => el.id);
-
- const selectionMode = this._getSelectionMode(e);
- let set!: Set;
- switch (selectionMode) {
- case 'add':
- set = new Set([
- ...elements,
- ...selection.filter(elId => this._currentSelectionState.has(elId)),
- ]);
- break;
- case 'sub': {
- const toRemove = new Set(elements);
- set = new Set(
- Array.from(this._currentSelectionState).filter(
- el => !toRemove.has(el)
- )
- );
- break;
- }
- case 'set':
- set = new Set(elements);
- break;
- }
-
- this._setSelectionState(Array.from(set), false);
- }
-
- private isInsideLassoSelection(bound: Bound, rotate: number): boolean {
- const { points, center } = bound;
-
- const firstPoint = this._lassoPoints[0];
- const lassoPoints = this._lassoPoints.concat(
- firstPoint ? [firstPoint] : []
- );
-
- const elPoly = rotatePoints(points, center, rotate);
- const lassoLen = lassoPoints.length;
- return (
- elPoly.some(point => pointInPolygon(point, lassoPoints)) ||
- lassoPoints.some((point, i, points) => {
- return linePolygonIntersects(point, points[(i + 1) % lassoLen], elPoly);
- })
- );
- }
-
- private toModelCoord(p: IPoint): IVec {
- return this.gfx.viewport.toModelCoord(p.x, p.y);
- }
-
- abort() {
- this._reset();
- }
-
- override activate(): void {
- this._currentSelectionState = new Set(
- this.selection.selectedElements.map(el => el.id)
- );
- this._reset();
- }
-
- override deactivate() {
- this._clearLastSelection();
- }
-
- override dragEnd(e: PointerEventState): void {
- if (this.activatedOption.mode !== LassoMode.FreeHand) return;
-
- this._updateSelection(e);
-
- this._reset();
- }
-
- override dragMove(e: PointerEventState): void {
- if (this.activatedOption.mode !== LassoMode.FreeHand) return;
-
- const { point } = e;
- const [x, y] = this.toModelCoord(point);
- this._lassoPoints.push([x, y]);
-
- this._updateSelection(e);
- }
-
- // For Freehand Mode =
- override dragStart(e: PointerEventState): void {
- if (this.activatedOption.mode !== LassoMode.FreeHand) return;
- const { alt, shift } = e.keys;
-
- if (!shift && !alt) {
- this._currentSelectionState.clear();
- this.selection.clear();
- }
-
- this._currentSelectionState = new Set(
- this.selection.selectedElements.map(el => el.id)
- );
-
- this._isSelecting = true;
-
- const { point } = e;
- const [x, y] = this.toModelCoord(point);
- this._lassoPoints = [[x, y]];
- this._raf = requestAnimationFrame(this._loop);
- this._overlay.startPoint = this._lassoPoints[0];
- this.surfaceComponent.renderer.addOverlay(this._overlay);
- }
-
- override pointerDown(e: PointerEventState): void {
- const { mode } = this.activatedOption;
- if (mode !== LassoMode.Polygonal) return;
-
- const { alt, shift } = e.keys;
- if (!shift && !alt) {
- this._currentSelectionState.clear();
- this.selection.clear();
- }
-
- this._isSelecting = true;
-
- const { point } = e;
- const [x, y] = this.toModelCoord(point);
- if (this._lassoPoints.length < 2) {
- this._currentSelectionState = new Set(
- this.selection.selectedElements.map(el => el.id)
- );
-
- const a: IVec = [x, y];
- const b: IVec = [x, y];
- this._lassoPoints = [a, b];
- this._lastPoint = b;
- this._overlay.startPoint = a;
- this._raf = requestAnimationFrame(this._loop);
- this.surfaceComponent.renderer.addOverlay(this._overlay);
- } else {
- const firstPoint = this._lassoPoints[0];
- const lastPoint = this._lastPoint;
- const dx = lastPoint[0] - firstPoint[0];
- const dy = lastPoint[1] - firstPoint[1];
- if (Vec.len2([dx, dy]) < 20 ** 2) {
- this._updateSelection(e);
-
- return this._reset();
- }
-
- this._lastPoint = [x, y];
- this._lassoPoints.push(this._lastPoint);
- }
- }
-
- override pointerMove(e: PointerEventState): void {
- if (this.activatedOption.mode !== LassoMode.Polygonal || !this._isSelecting)
- return;
-
- const lastPoint = this._lastPoint;
- const [x, y] = this.toModelCoord(e.point);
- if (lastPoint) {
- lastPoint[0] = x;
- lastPoint[1] = y;
- }
- this._updateSelection(e);
- }
-}
-
-declare module '@blocksuite/std/gfx' {
- interface GfxToolsMap {
- lasso: LassoTool;
- }
-
- interface GfxToolsOption {
- lasso: LassoToolOption;
- }
-}
diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/utils/query.ts b/blocksuite/affine/blocks/block-root/src/edgeless/utils/query.ts
index 357bc696f5..f5b750c5e5 100644
--- a/blocksuite/affine/blocks/block-root/src/edgeless/utils/query.ts
+++ b/blocksuite/affine/blocks/block-root/src/edgeless/utils/query.ts
@@ -222,7 +222,6 @@ export function getCursorMode(edgelessTool: GfxToolsFullOptionValue | null) {
case 'shape':
case 'connector':
case 'frame':
- case 'lasso':
return 'crosshair';
case 'text':
return 'text';
diff --git a/blocksuite/affine/blocks/block-root/src/effects.ts b/blocksuite/affine/blocks/block-root/src/effects.ts
index f5c9eb20cd..b1275d763f 100644
--- a/blocksuite/affine/blocks/block-root/src/effects.ts
+++ b/blocksuite/affine/blocks/block-root/src/effects.ts
@@ -25,7 +25,6 @@ import {
import { EdgelessSlideMenu } from './edgeless/components/toolbar/common/slide-menu.js';
import { ToolbarArrowUpIcon } from './edgeless/components/toolbar/common/toolbar-arrow-up-icon.js';
import { EdgelessDefaultToolButton } from './edgeless/components/toolbar/default/default-tool-button.js';
-import { EdgelessLassoToolButton } from './edgeless/components/toolbar/lasso/lasso-tool-button.js';
import { EdgelessLinkToolButton } from './edgeless/components/toolbar/link/link-tool-button.js';
import {
AffineModalWidget,
@@ -121,7 +120,6 @@ function registerEdgelessToolbarComponents() {
EdgelessDefaultToolButton
);
customElements.define('edgeless-link-tool-button', EdgelessLinkToolButton);
- customElements.define('edgeless-lasso-tool-button', EdgelessLassoToolButton);
// Menus
customElements.define('edgeless-slide-menu', EdgelessSlideMenu);
@@ -181,7 +179,6 @@ declare global {
'edgeless-slide-menu': EdgelessSlideMenu;
'toolbar-arrow-up-icon': ToolbarArrowUpIcon;
'edgeless-default-tool-button': EdgelessDefaultToolButton;
- 'edgeless-lasso-tool-button': EdgelessLassoToolButton;
'edgeless-link-tool-button': EdgelessLinkToolButton;
'affine-page-root': PageRootBlockComponent;
'zoom-bar-toggle-button': ZoomBarToggleButton;
diff --git a/blocksuite/affine/shared/src/services/feature-flag-service.ts b/blocksuite/affine/shared/src/services/feature-flag-service.ts
index ed72544ece..075092141a 100644
--- a/blocksuite/affine/shared/src/services/feature-flag-service.ts
+++ b/blocksuite/affine/shared/src/services/feature-flag-service.ts
@@ -6,7 +6,6 @@ export interface BlockSuiteFlags {
enable_database_attachment_note: boolean;
enable_database_full_width: boolean;
enable_block_query: boolean;
- enable_lasso_tool: boolean;
enable_edgeless_text: boolean;
enable_ai_onboarding: boolean;
enable_ai_chat_block: boolean;
@@ -29,7 +28,6 @@ export class FeatureFlagService extends StoreExtension {
enable_database_attachment_note: false,
enable_database_full_width: false,
enable_block_query: false,
- enable_lasso_tool: false,
enable_edgeless_text: true,
enable_ai_onboarding: true,
enable_ai_chat_block: true,
diff --git a/blocksuite/affine/shared/src/types/index.ts b/blocksuite/affine/shared/src/types/index.ts
index 996b7edb89..b52238fc7b 100644
--- a/blocksuite/affine/shared/src/types/index.ts
+++ b/blocksuite/affine/shared/src/types/index.ts
@@ -13,11 +13,6 @@ export interface EditingState {
rect: DOMRect;
}
-export enum LassoMode {
- FreeHand,
- Polygonal,
-}
-
export type NoteChildrenFlavour =
| 'affine:paragraph'
| 'affine:list'
diff --git a/tests/blocksuite/e2e/edgeless/lasso.spec.ts b/tests/blocksuite/e2e/edgeless/lasso.spec.ts
deleted file mode 100644
index 4f19aae0d7..0000000000
--- a/tests/blocksuite/e2e/edgeless/lasso.spec.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-import { sleep } from '@blocksuite/global/utils';
-import { expect } from '@playwright/test';
-
-import {
- addBasicRectShapeElement,
- assertEdgelessTool,
- edgelessCommonSetup as commonSetup,
- setEdgelessTool,
-} from '../utils/actions/edgeless.js';
-import {
- dragBetweenCoords,
- selectAllByKeyboard,
-} from '../utils/actions/index.js';
-import {
- assertEdgelessNonSelectedRect,
- assertEdgelessSelectedRect,
-} from '../utils/asserts.js';
-import { test } from '../utils/playwright.js';
-
-test.skip('lasso tool should deselect when dragging in an empty area', async ({
- page,
-}) => {
- await commonSetup(page);
-
- const start = { x: 100, y: 100 };
- const end = { x: 200, y: 200 };
- await addBasicRectShapeElement(page, start, end);
- await assertEdgelessSelectedRect(page, [100, 100, 100, 100]);
-
- await setEdgelessTool(page, 'lasso');
- await assertEdgelessTool(page, 'lasso');
-
- await dragBetweenCoords(page, { x: 10, y: 10 }, { x: 15, y: 15 });
-
- await assertEdgelessNonSelectedRect(page);
-});
-
-test.skip('freehand lasso basic test', async ({ page }) => {
- await commonSetup(page);
-
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
-
- await page.mouse.click(10, 10); // deselect
-
- await setEdgelessTool(page, 'lasso');
- await assertEdgelessTool(page, 'lasso');
-
- await assertEdgelessNonSelectedRect(page);
-
- // simulate a basic lasso selection to select both the rects
- const points: [number, number][] = [
- [500, 100],
- [500, 500],
- [90, 500],
- ];
- await page.mouse.move(90, 90);
- await page.mouse.down();
- for (const point of points) await page.mouse.move(...point);
- await page.mouse.up();
-
- await assertEdgelessSelectedRect(page, [100, 100, 200, 200]);
-});
-
-test.skip('freehand lasso add to selection', async ({ page }) => {
- await commonSetup(page);
-
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
-
- await page.mouse.click(10, 10); // deselect
-
- await setEdgelessTool(page, 'lasso');
- await assertEdgelessTool(page, 'lasso');
- await assertEdgelessNonSelectedRect(page);
-
- // some random selection covering the rectangle
- let points: [number, number][] = [
- [250, 90],
- [250, 300],
- [10, 300],
- ];
- await page.mouse.move(90, 90);
- await page.mouse.down();
- for (const point of points) await page.mouse.move(...point);
- await page.mouse.up();
-
- await assertEdgelessSelectedRect(page, [100, 100, 100, 100]);
-
- points = [
- [400, 250],
- [400, 450],
- [250, 450],
- ];
-
- await page.keyboard.down('Shift'); // addition selection
- await page.mouse.move(250, 250);
- await page.mouse.down();
- for (const point of points) await page.mouse.move(...point);
- await page.mouse.up();
-
- await assertEdgelessSelectedRect(page, [100, 100, 200, 200]);
-});
-
-test.skip('freehand lasso subtract from selection', async ({ page }) => {
- await commonSetup(page);
-
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
- await setEdgelessTool(page, 'default');
-
- await selectAllByKeyboard(page);
-
- await setEdgelessTool(page, 'lasso');
-
- const points: [number, number][] = [
- [410, 290],
- [410, 410],
- [290, 410],
- ];
-
- await page.keyboard.down('Alt');
-
- await page.mouse.move(290, 290);
- await page.mouse.down();
- for (const point of points) await page.mouse.move(...point);
- await page.mouse.up();
-
- await assertEdgelessSelectedRect(page, [100, 100, 100, 100]); // only the first rectangle should be selected
-});
-
-test.skip('polygonal lasso basic test', async ({ page }) => {
- await commonSetup(page);
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
- await page.mouse.click(10, 10); // deselect
-
- await assertEdgelessNonSelectedRect(page);
-
- await setEdgelessTool(page, 'lasso');
- await setEdgelessTool(page, 'lasso'); // switch to polygonal lasso
- await sleep(100);
-
- const points: [number, number][] = [
- [90, 90],
- [500, 90],
- [500, 500],
- [90, 500],
- [90, 90],
- ];
-
- for (const point of points) {
- await page.mouse.click(...point);
- }
-
- await assertEdgelessSelectedRect(page, [100, 100, 200, 200]);
-});
-
-test.skip('polygonal lasso add to selection by holding Shift Key', async ({
- page,
-}) => {
- await commonSetup(page);
-
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
-
- await page.mouse.click(10, 10); // deselect
- await assertEdgelessNonSelectedRect(page);
-
- await setEdgelessTool(page, 'lasso');
- await setEdgelessTool(page, 'lasso');
- await sleep(100);
-
- let points: [number, number][] = [
- [90, 90],
- [150, 90],
- [150, 150],
- [90, 150],
- [90, 90],
- ];
-
- // select the first rectangle
- for (const point of points) await page.mouse.click(...point);
-
- points = [
- [290, 290],
- [350, 290],
- [350, 350],
- [290, 350],
- [290, 290],
- ];
-
- await page.keyboard.down('Shift'); // add to selection
- // selects the second rectangle
- for (const point of points) await page.mouse.click(...point);
-
- // by the end both of the rects should be selected
- await assertEdgelessSelectedRect(page, [100, 100, 200, 200]);
-});
-
-test.skip('polygonal lasso subtract from selection by holding Alt', async ({
- page,
-}) => {
- await commonSetup(page);
-
- await addBasicRectShapeElement(page, { x: 100, y: 100 }, { x: 200, y: 200 });
- await addBasicRectShapeElement(page, { x: 300, y: 300 }, { x: 400, y: 400 });
-
- await selectAllByKeyboard(page);
-
- const points: [number, number][] = [
- [290, 290],
- [350, 290],
- [350, 350],
- [290, 350],
- [290, 290],
- ];
-
- // switch to polygonal lasso tool
- await setEdgelessTool(page, 'lasso');
- await setEdgelessTool(page, 'lasso');
- await sleep(100);
-
- await page.keyboard.down('Alt'); // subtract from selection
- for (const point of points) await page.mouse.click(...point);
-
- // By the end the second rectangle must be deselected leaving the first rect selection
- await assertEdgelessSelectedRect(page, [100, 100, 100, 100]);
-});
-
-test.skip('polygonal lasso should complete selection when clicking the last point', async ({
- page,
-}) => {
- await commonSetup(page);
-
- // switch to polygonal lasso
- await setEdgelessTool(page, 'lasso');
- await setEdgelessTool(page, 'lasso');
- await sleep(100);
-
- const lassoPoints: [number, number][] = [
- [100, 100],
- [200, 200],
- [250, 150],
- [100, 100],
- ];
-
- for (const point of lassoPoints) await page.mouse.click(...point);
-
- const isSelecting = await page.evaluate(() => {
- const edgeless = document.querySelector('affine-edgeless-root');
- if (!edgeless) throw new Error('Missing edgless root block');
-
- const curController = edgeless.gfx.tool.currentTool$.peek();
- if (curController?.toolName !== 'lasso')
- throw new Error('expected lasso tool controller');
-
- return (curController as any)['_isSelecting'];
- });
-
- expect(isSelecting).toBe(false);
-});
diff --git a/tests/blocksuite/e2e/edgeless/lock.spec.ts b/tests/blocksuite/e2e/edgeless/lock.spec.ts
index 13e130a41f..9f80c54912 100644
--- a/tests/blocksuite/e2e/edgeless/lock.spec.ts
+++ b/tests/blocksuite/e2e/edgeless/lock.spec.ts
@@ -122,7 +122,7 @@ test.describe('lock', () => {
expect(await getSelectedIds(page)).toHaveLength(1);
});
- test('locked element should not be selectable by dragging default tool or lasso tool. unlocking will recover', async ({
+ test('locked element should not be selectable by dragging default tool. unlocking will recover', async ({
page,
}) => {
await edgelessCommonSetup(page);
diff --git a/tests/blocksuite/e2e/edgeless/shortcut.spec.ts b/tests/blocksuite/e2e/edgeless/shortcut.spec.ts
index 0f125649cd..1bf73d3956 100644
--- a/tests/blocksuite/e2e/edgeless/shortcut.spec.ts
+++ b/tests/blocksuite/e2e/edgeless/shortcut.spec.ts
@@ -65,33 +65,6 @@ test('shortcut', async ({ page }) => {
await page.keyboard.press('c');
const connectorButton = await locatorEdgelessToolButton(page, 'connector');
await expect(connectorButton).toHaveAttribute('active', '');
-
- // await page.keyboard.press('l');
- // const lassoButton = await locatorEdgelessToolButton(page, 'lasso');
- // await expect(lassoButton).toHaveAttribute('active', '');
-});
-
-test.skip('toggle lasso tool modes', async ({ page }) => {
- await enterPlaygroundRoom(page);
- await initEmptyEdgelessState(page);
- await switchEditorMode(page);
- await page.mouse.click(100, 100);
-
- const lassoButton = await locatorEdgelessToolButton(page, 'lasso', false);
-
- const isLassoMode = async (type: 'freehand' | 'polygonal') => {
- const classes = (await lassoButton.getAttribute('class'))?.split(' ') ?? [];
- return classes.includes(type);
- };
-
- await page.keyboard.press('Shift+l');
- expect(await isLassoMode('freehand')).toBe(true);
-
- await page.keyboard.press('Shift+l');
- expect(await isLassoMode('polygonal')).toBe(true);
-
- await page.keyboard.press('Shift+l');
- expect(await isLassoMode('freehand')).toBe(true);
});
test('toggle shapes shortcut', async ({ page }) => {
diff --git a/tests/blocksuite/e2e/utils/actions/edgeless.ts b/tests/blocksuite/e2e/utils/actions/edgeless.ts
index 5f6143245a..f1785d07e2 100644
--- a/tests/blocksuite/e2e/utils/actions/edgeless.ts
+++ b/tests/blocksuite/e2e/utils/actions/edgeless.ts
@@ -52,11 +52,6 @@ export enum Shape {
Triangle = 'Triangle',
}
-export enum LassoMode {
- FreeHand = 'freehand',
- Polygonal = 'polygonal',
-}
-
export enum ConnectorMode {
Straight,
Orthogonal,
@@ -166,8 +161,7 @@ type EdgelessTool =
| 'text'
| 'connector'
| 'frame'
- | 'frameNavigator'
- | 'lasso';
+ | 'frameNavigator';
type ZoomToolType = 'zoomIn' | 'zoomOut' | 'fitToScreen';
type ComponentToolType = 'shape' | 'thin' | 'thick' | 'brush' | 'more';
@@ -211,7 +205,6 @@ export async function locatorEdgelessToolButton(
note: '.edgeless-note-button',
frame: '.edgeless-frame-button',
frameNavigator: '.edgeless-frame-navigator-button',
- lasso: '.edgeless-lasso-button',
}[type];
let buttonType;
@@ -362,7 +355,6 @@ export async function setEdgelessTool(
break;
}
- case 'lasso':
case 'note':
case 'eraser':
case 'frame':
@@ -438,20 +430,6 @@ export async function assertEdgelessConnectorToolMode(
expect(tool.mode).toEqual(mode);
}
-export async function assertEdgelessLassoToolMode(page: Page, mode: LassoMode) {
- const tool = await page.evaluate(() => {
- const container = document.querySelector('affine-edgeless-root');
- if (!container) {
- throw new Error('Missing edgeless page');
- }
- return container.gfx.tool.currentToolOption$.peek();
- });
- if (tool.type !== 'lasso') {
- throw new Error('Expected lasso tool');
- }
- expect(tool.mode).toEqual(mode === LassoMode.FreeHand ? 0 : 1);
-}
-
export async function getEdgelessBlockChild(page: Page) {
const block = page.locator('affine-edgeless-note');
const blockBox = await block.boundingBox();
diff --git a/tests/kit/src/utils/editor.ts b/tests/kit/src/utils/editor.ts
index f0ca99071b..a048c1bd79 100644
--- a/tests/kit/src/utils/editor.ts
+++ b/tests/kit/src/utils/editor.ts
@@ -237,8 +237,7 @@ type EdgelessTool =
| 'text'
| 'connector'
| 'frame'
- | 'frameNavigator'
- | 'lasso';
+ | 'frameNavigator';
/**
* @param type the type of the tool in the toolbar
@@ -265,7 +264,6 @@ export async function locateEdgelessToolButton(
note: '.edgeless-note-button',
frame: '.edgeless-frame-button',
frameNavigator: '.edgeless-frame-navigator-button',
- lasso: '.edgeless-lasso-button',
}[type];
let buttonType;
@@ -391,7 +389,6 @@ export async function setEdgelessTool(
break;
}
- case 'lasso':
case 'note':
case 'eraser':
case 'frame':