Skip to content

Commit

Permalink
feat(edgeless): support rotating shapes (toeverything#2931)
Browse files Browse the repository at this point in the history
Co-authored-by: Yifeng Wang <doodlewind@toeverything.info>
  • Loading branch information
fundon and doodlewind authored Jul 3, 2023
1 parent 50f9349 commit feb509b
Show file tree
Hide file tree
Showing 50 changed files with 2,093 additions and 876 deletions.
11 changes: 5 additions & 6 deletions packages/blocks/src/__internal__/clipboard/edgeless-clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,11 @@ export class EdgelessClipboard implements Clipboard {

const { _edgeless } = this;
const { surface } = _edgeless;
const { viewport } = surface;
const { zoom } = viewport;
const { left, top, right, bottom, width, height } = getSelectedRect(
[...notes, ...shapes],
viewport
);
const { zoom } = surface.viewport;
const { left, top, right, bottom, width, height } = getSelectedRect([
...notes,
...shapes,
]);
const min = surface.toModelCoord(left, top);
const max = surface.toModelCoord(right, bottom);
const cx = (min[0] + max[0]) / 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import type {
BrushElement,
ConnectorElement,
ShapeElement,
SurfaceManager,
TextElement,
} from '@blocksuite/phasor';
import type { Page } from '@blocksuite/store';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { join } from 'lit/directives/join.js';
Expand All @@ -24,13 +22,9 @@ import {
} from '../../../../__internal__/utils/common.js';
import { stopPropagation } from '../../../../__internal__/utils/event.js';
import type { TopLevelBlockModel } from '../../../../__internal__/utils/types.js';
import type {
EdgelessPageBlockComponent,
EdgelessSelectionSlots,
} from '../../edgeless-page-block.js';
import type { EdgelessPageBlockComponent } from '../../edgeless-page-block.js';
import { isTopLevelBlock } from '../../utils/query.js';
import type { EdgelessSelectionState } from '../../utils/selection-manager.js';
import type { Selectable } from '../../utils/selection-manager.js';

type CategorizedElements = {
shape: ShapeElement[];
Expand All @@ -44,11 +38,15 @@ type CategorizedElements = {
export class EdgelessComponentToolbar extends LitElement {
static override styles = css`
:host {
display: block;
display: none;
position: absolute;
user-select: none;
}
:host([data-show]) {
display: block;
}
.container {
display: flex;
align-items: center;
Expand All @@ -63,23 +61,27 @@ export class EdgelessComponentToolbar extends LitElement {
}
`;

@property({ attribute: false })
selected: Selectable[] = [];

@property({ type: Object })
selectionState!: EdgelessSelectionState;

@property({ attribute: false })
page!: Page;
edgeless!: EdgelessPageBlockComponent;

@property({ attribute: false })
surface!: SurfaceManager;
get page() {
return this.edgeless.page;
}

@property({ attribute: false })
slots!: EdgelessSelectionSlots;
get selected() {
return this.selectionState.selected;
}

@property({ attribute: false })
edgeless!: EdgelessPageBlockComponent;
get slots() {
return this.edgeless.slots;
}

get surface() {
return this.edgeless.surface;
}

private _groupSelected(): CategorizedElements {
const result = groupBy(this.selected, s => {
Expand All @@ -101,7 +103,7 @@ export class EdgelessComponentToolbar extends LitElement {
.selectionState=${this.selectionState}
>
</edgeless-change-shape-button>`
: null;
: nothing;
return shapeButton;
}

Expand All @@ -115,7 +117,7 @@ export class EdgelessComponentToolbar extends LitElement {
.selectionState=${this.selectionState}
>
</edgeless-change-brush-button>`
: null;
: nothing;
}

private _getConnectorButton(connectorElements?: ConnectorElement[]) {
Expand All @@ -128,7 +130,7 @@ export class EdgelessComponentToolbar extends LitElement {
.selectionState=${this.selectionState}
>
</edgeless-change-connector-button>`
: null;
: nothing;
}

private _getNoteButton(blocks?: TopLevelBlockModel[]) {
Expand All @@ -141,7 +143,7 @@ export class EdgelessComponentToolbar extends LitElement {
.selectionState=${this.selectionState}
>
</edgeless-change-note-button>`
: null;
: nothing;
}

private _getTextButton(textElements: TextElement[]) {
Expand All @@ -154,12 +156,13 @@ export class EdgelessComponentToolbar extends LitElement {
.selectionState=${this.selectionState}
>
</edgeless-change-text-button>`
: null;
: nothing;
}

override render() {
const groupedSelected = this._groupSelected();
const { shape, brush, connector, note: note, text } = groupedSelected;
const { edgeless, selected } = this;
const { shape, brush, connector, note, text } = groupedSelected;

// when selected types more than two, only show `more` button
const selectedAtLeastTwoTypes = atLeastNMatches(
Expand All @@ -178,18 +181,13 @@ export class EdgelessComponentToolbar extends LitElement {
this._getTextButton(text),
].filter(b => !!b);

const divider = !buttons.length
? nothing
: html`<menu-divider .vertical=${true}></menu-divider>`;
const divider = buttons.length
? html`<menu-divider .vertical=${true}></menu-divider>`
: nothing;

return html`<div class="container" @pointerdown=${stopPropagation}>
${join(buttons, () => '')} ${divider}
<edgeless-more-button
.elements=${this.selected}
.page=${this.page}
.surface=${this.surface}
.slots=${this.slots}
.edgeless=${this.edgeless}
>
<edgeless-more-button .elements=${selected} .edgeless=${edgeless}>
</edgeless-more-button>
</div>`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import '../toolbar/shape/shape-menu.js';

import { MoreHorizontalIcon } from '@blocksuite/global/config';
import { WithDisposable } from '@blocksuite/lit';
import type { PhasorElement, SurfaceManager } from '@blocksuite/phasor';
import type { Page } from '@blocksuite/store';
import type { PhasorElement } from '@blocksuite/phasor';
import { css, html, LitElement } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
Expand All @@ -13,10 +12,7 @@ import {
type ReorderingType,
type TopLevelBlockModel,
} from '../../../../__internal__/index.js';
import type {
EdgelessPageBlockComponent,
EdgelessSelectionSlots,
} from '../../edgeless-page-block.js';
import type { EdgelessPageBlockComponent } from '../../edgeless-page-block.js';
import { isTopLevelBlock } from '../../utils/query.js';
import type { Selectable } from '../../utils/selection-manager.js';
import { createButtonPopper } from '../utils.js';
Expand Down Expand Up @@ -104,15 +100,6 @@ export class EdgelessMoreButton extends WithDisposable(LitElement) {
@property({ attribute: false })
elements: Selectable[] = [];

@property({ attribute: false })
page!: Page;

@property({ attribute: false })
surface!: SurfaceManager;

@property({ attribute: false })
slots!: EdgelessSelectionSlots;

@property({ attribute: false })
edgeless!: EdgelessPageBlockComponent;

Expand All @@ -125,6 +112,18 @@ export class EdgelessMoreButton extends WithDisposable(LitElement) {
private _actionsMenuPopper: ReturnType<typeof createButtonPopper> | null =
null;

get page() {
return this.edgeless.page;
}

get slots() {
return this.edgeless.slots;
}

get surface() {
return this.edgeless.surface;
}

private _splitElements(): {
notes: TopLevelBlockModel[];
shapes: PhasorElement[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function EdgelessChildNote(
zIndex: `${index}`,
width: modelW + 'px',
height: modelH + 'px',
transform: `translate(${modelX}px, ${modelY}px)`,
padding: `${EDGELESS_BLOCK_CHILD_PADDING}px`,
border: `2px ${isHiddenNote ? 'dashed' : 'solid'} var(--affine-black-10)`,
borderRadius: '8px',
Expand All @@ -48,7 +49,6 @@ function EdgelessChildNote(
boxShadow: isHiddenNote ? undefined : 'var(--affine-shadow-3)',
pointerEvents: 'all',
overflow: 'hidden',
transform: `translate(${modelX}px, ${modelY}px)`,
transformOrigin: '0 0',
};

Expand Down
Loading

0 comments on commit feb509b

Please sign in to comment.