mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-24 18:02:47 +08:00
feat(editor): gfx note package (#11088)
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import type { NoteBlockComponent } from '@blocksuite/affine-block-note';
|
||||
import { isNoteBlock } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
EdgelessLegacySlotIdentifier,
|
||||
getSurfaceComponent,
|
||||
isNoteBlock,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
type NoteBlockModel,
|
||||
@@ -18,7 +22,7 @@ import { state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block';
|
||||
import type { EdgelessSelectedRectWidget } from '../rects/edgeless-selected-rect';
|
||||
|
||||
const DIVIDING_LINE_OFFSET = 4;
|
||||
const NEW_NOTE_GAP = 40;
|
||||
@@ -96,10 +100,7 @@ const styles = css`
|
||||
|
||||
export const NOTE_SLICER_WIDGET = 'note-slicer';
|
||||
|
||||
export class NoteSlicer extends WidgetComponent<
|
||||
RootBlockModel,
|
||||
EdgelessRootBlockComponent
|
||||
> {
|
||||
export class NoteSlicer extends WidgetComponent<RootBlockModel> {
|
||||
static override styles = styles;
|
||||
|
||||
private _divingLinePositions: Point[] = [];
|
||||
@@ -143,7 +144,10 @@ export class NoteSlicer extends WidgetComponent<
|
||||
}
|
||||
|
||||
get selectedRectEle() {
|
||||
return this.block?.selectedRectWidget;
|
||||
return this.host.view.getWidget(
|
||||
'edgeless-selected-rect',
|
||||
this.host.id
|
||||
) as EdgelessSelectedRectWidget | null;
|
||||
}
|
||||
|
||||
private _sliceNote() {
|
||||
@@ -262,22 +266,20 @@ export class NoteSlicer extends WidgetComponent<
|
||||
override connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
const { disposables, std, block, gfx } = this;
|
||||
const { disposables, std, gfx } = this;
|
||||
|
||||
this._updateDivingLineAndBlockIds();
|
||||
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
const slots = std.get(EdgelessLegacySlotIdentifier);
|
||||
|
||||
disposables.add(
|
||||
block.slots.elementResizeStart.subscribe(() => {
|
||||
slots.elementResizeStart.subscribe(() => {
|
||||
this._isResizing = true;
|
||||
})
|
||||
);
|
||||
|
||||
disposables.add(
|
||||
block.slots.elementResizeEnd.subscribe(() => {
|
||||
slots.elementResizeEnd.subscribe(() => {
|
||||
this._isResizing = false;
|
||||
})
|
||||
);
|
||||
@@ -311,7 +313,7 @@ export class NoteSlicer extends WidgetComponent<
|
||||
);
|
||||
|
||||
disposables.add(
|
||||
block.slots.toggleNoteSlicer.subscribe(() => {
|
||||
slots.toggleNoteSlicer.subscribe(() => {
|
||||
this._enableNoteSlicer = !this._enableNoteSlicer;
|
||||
|
||||
if (this.selectedRectEle && this._enableNoteSlicer) {
|
||||
@@ -320,9 +322,9 @@ export class NoteSlicer extends WidgetComponent<
|
||||
})
|
||||
);
|
||||
|
||||
const { surface } = block;
|
||||
requestAnimationFrame(() => {
|
||||
if (surface.isConnected && std.event) {
|
||||
const surface = getSurfaceComponent(std);
|
||||
if (surface?.isConnected && std.event) {
|
||||
disposables.add(
|
||||
std.event.add('click', ctx => {
|
||||
const event = ctx.get('pointerState');
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { svg } from 'lit';
|
||||
|
||||
export const toShapeNotToAdapt = svg`<svg width="44" height="5" viewBox="0 0 44 5" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M43.9013 1.45752V1.94112H42.5034V1.45752H43.9013ZM42.8208 0.901367H43.4646V3.06551C43.4646 3.12496 43.4737 3.1713 43.4918 3.20455C43.5099 3.23679 43.5351 3.25946 43.5674 3.27256C43.6006 3.28565 43.6389 3.2922 43.6822 3.2922C43.7124 3.2922 43.7427 3.28968 43.7729 3.28465C43.8031 3.2786 43.8263 3.27407 43.8424 3.27105L43.9437 3.75012C43.9114 3.76019 43.8661 3.77178 43.8076 3.78488C43.7492 3.79898 43.6782 3.80755 43.5946 3.81057C43.4394 3.81662 43.3034 3.79596 43.1865 3.74861C43.0706 3.70126 42.9805 3.62771 42.916 3.52796C42.8515 3.42822 42.8198 3.30228 42.8208 3.15014V0.901367Z" fill="currentColor"/>
|
||||
<path d="M39.9741 4.64977V1.45796H40.6089V1.84787H40.6376C40.6658 1.7854 40.7066 1.72193 40.76 1.65745C40.8144 1.59196 40.8849 1.53755 40.9716 1.49423C41.0592 1.4499 41.168 1.42773 41.298 1.42773C41.4673 1.42773 41.6234 1.47207 41.7665 1.56073C41.9096 1.64838 42.0239 1.78087 42.1096 1.95819C42.1952 2.13451 42.238 2.35566 42.238 2.62164C42.238 2.88057 42.1962 3.0992 42.1126 3.27753C42.03 3.45486 41.9171 3.58936 41.774 3.68104C41.632 3.77172 41.4728 3.81706 41.2965 3.81706C41.1716 3.81706 41.0653 3.79641 40.9776 3.7551C40.891 3.71379 40.8199 3.6619 40.7645 3.59944C40.7091 3.53596 40.6668 3.47199 40.6376 3.4075H40.6179V4.64977H39.9741ZM40.6043 2.61862C40.6043 2.75665 40.6235 2.87705 40.6618 2.97981C40.7 3.08258 40.7555 3.16268 40.828 3.22011C40.9005 3.27653 40.9887 3.30474 41.0925 3.30474C41.1972 3.30474 41.2859 3.27602 41.3584 3.21859C41.431 3.16016 41.4859 3.07956 41.5232 2.97679C41.5615 2.87302 41.5806 2.75363 41.5806 2.61862C41.5806 2.48462 41.562 2.36674 41.5247 2.26498C41.4874 2.16322 41.4325 2.08363 41.36 2.0262C41.2874 1.96877 41.1983 1.94006 41.0925 1.94006C40.9877 1.94006 40.899 1.96776 40.8265 2.02318C40.7549 2.07859 40.7 2.15718 40.6618 2.25894C40.6235 2.36069 40.6043 2.48059 40.6043 2.61862Z" fill="currentColor"/>
|
||||
<path d="M38.1667 3.8231C38.0186 3.8231 37.8867 3.79741 37.7708 3.74603C37.6549 3.69364 37.5632 3.61656 37.4957 3.5148C37.4292 3.41204 37.396 3.28408 37.396 3.13094C37.396 3.00198 37.4197 2.89367 37.467 2.80602C37.5144 2.71836 37.5789 2.64784 37.6605 2.59444C37.7421 2.54104 37.8348 2.50074 37.9385 2.47354C38.0433 2.44633 38.1531 2.42719 38.268 2.41611C38.403 2.402 38.5118 2.38891 38.5944 2.37681C38.6771 2.36372 38.737 2.34457 38.7743 2.31939C38.8116 2.2942 38.8302 2.25692 38.8302 2.20755V2.19848C38.8302 2.10277 38.8 2.02872 38.7395 1.97633C38.6801 1.92394 38.5954 1.89774 38.4856 1.89774C38.3698 1.89774 38.2776 1.92343 38.2091 1.97482C38.1406 2.02519 38.0952 2.08867 38.073 2.16524L37.4776 2.11688C37.5078 1.97582 37.5673 1.85391 37.6559 1.75115C37.7446 1.64737 37.8589 1.56778 37.999 1.51237C38.14 1.45594 38.3033 1.42773 38.4886 1.42773C38.6176 1.42773 38.741 1.44285 38.8589 1.47307C38.9778 1.5033 39.0831 1.55015 39.1748 1.61362C39.2675 1.67709 39.3405 1.7587 39.3939 1.85845C39.4473 1.95718 39.474 2.07557 39.474 2.2136V3.77928H38.8634V3.45738H38.8453C38.808 3.52992 38.7582 3.59389 38.6957 3.64931C38.6332 3.70371 38.5582 3.74653 38.4705 3.77777C38.3829 3.80799 38.2816 3.8231 38.1667 3.8231ZM38.3511 3.37879C38.4458 3.37879 38.5295 3.36015 38.602 3.32287C38.6745 3.28459 38.7315 3.2332 38.7728 3.16872C38.8141 3.10424 38.8347 3.0312 38.8347 2.94959V2.70325C38.8146 2.71635 38.7869 2.72844 38.7516 2.73952C38.7174 2.7496 38.6786 2.75917 38.6352 2.76823C38.5919 2.7763 38.5486 2.78385 38.5053 2.7909C38.4619 2.79695 38.4227 2.80249 38.3874 2.80753C38.3118 2.81861 38.2458 2.83624 38.1894 2.86042C38.133 2.8846 38.0892 2.91735 38.0579 2.95866C38.0267 2.99896 38.0111 3.04933 38.0111 3.10978C38.0111 3.19744 38.0428 3.26444 38.1063 3.31078C38.1708 3.35612 38.2524 3.37879 38.3511 3.37879Z" fill="currentColor"/>
|
||||
<path d="M35.6544 3.81647C35.4781 3.81647 35.3184 3.77113 35.1753 3.68045C35.0333 3.58877 34.9204 3.45426 34.8368 3.27694C34.7542 3.09861 34.7129 2.87998 34.7129 2.62105C34.7129 2.35506 34.7557 2.13391 34.8413 1.9576C34.927 1.78028 35.0408 1.64779 35.1829 1.56013C35.326 1.47147 35.4826 1.42714 35.6529 1.42714C35.7829 1.42714 35.8912 1.44931 35.9778 1.49364C36.0655 1.53696 36.136 1.59137 36.1894 1.65685C36.2438 1.72134 36.2851 1.78481 36.3133 1.84728H36.333V0.683594H36.9753V3.77868H36.3405V3.40691H36.3133C36.2831 3.47139 36.2403 3.53537 36.1849 3.59884C36.1305 3.66131 36.0594 3.7132 35.9718 3.7545C35.8851 3.79581 35.7793 3.81647 35.6544 3.81647ZM35.8584 3.30414C35.9622 3.30414 36.0499 3.27593 36.1214 3.21951C36.1939 3.16208 36.2494 3.08199 36.2876 2.97922C36.3269 2.87645 36.3466 2.75605 36.3466 2.61803C36.3466 2.48 36.3274 2.3601 36.2891 2.25834C36.2509 2.15658 36.1955 2.078 36.1229 2.02258C36.0504 1.96717 35.9622 1.93946 35.8584 1.93946C35.7526 1.93946 35.6635 1.96818 35.5909 2.02561C35.5184 2.08303 35.4635 2.16263 35.4262 2.26439C35.3889 2.36615 35.3703 2.48403 35.3703 2.61803C35.3703 2.75303 35.3889 2.87242 35.4262 2.9762C35.4645 3.07896 35.5194 3.15957 35.5909 3.218C35.6635 3.27543 35.7526 3.30414 35.8584 3.30414Z" fill="currentColor"/>
|
||||
<path d="M32.9929 3.82213C32.8448 3.82213 32.7128 3.79644 32.597 3.74505C32.4811 3.69266 32.3894 3.61559 32.3219 3.51383C32.2554 3.41106 32.2222 3.28311 32.2222 3.12996C32.2222 3.001 32.2458 2.89269 32.2932 2.80504C32.3406 2.71739 32.405 2.64686 32.4866 2.59346C32.5682 2.54006 32.6609 2.49976 32.7647 2.47256C32.8695 2.44536 32.9793 2.42621 33.0942 2.41513C33.2292 2.40103 33.338 2.38793 33.4206 2.37584C33.5032 2.36274 33.5632 2.3436 33.6005 2.31841C33.6377 2.29322 33.6564 2.25594 33.6564 2.20658V2.19751C33.6564 2.10179 33.6261 2.02774 33.5657 1.97535C33.5062 1.92296 33.4216 1.89676 33.3118 1.89676C33.1959 1.89676 33.1037 1.92246 33.0352 1.97384C32.9667 2.02422 32.9214 2.08769 32.8992 2.16426L32.3038 2.1159C32.334 1.97485 32.3934 1.85294 32.4821 1.75017C32.5708 1.6464 32.6851 1.5668 32.8252 1.51139C32.9662 1.45497 33.1294 1.42676 33.3148 1.42676C33.4438 1.42676 33.5672 1.44187 33.6851 1.4721C33.804 1.50232 33.9093 1.54917 34.0009 1.61264C34.0936 1.67612 34.1667 1.75773 34.2201 1.85747C34.2735 1.95621 34.3002 2.07459 34.3002 2.21262V3.7783H33.6896V3.4564H33.6715C33.6342 3.52894 33.5843 3.59292 33.5219 3.64833C33.4594 3.70274 33.3843 3.74556 33.2967 3.77679C33.209 3.80702 33.1078 3.82213 32.9929 3.82213ZM33.1773 3.37781C33.272 3.37781 33.3556 3.35917 33.4282 3.3219C33.5007 3.28361 33.5576 3.23223 33.5989 3.16775C33.6402 3.10327 33.6609 3.03022 33.6609 2.94861V2.70227C33.6408 2.71537 33.613 2.72746 33.5778 2.73854C33.5435 2.74862 33.5047 2.75819 33.4614 2.76726C33.4181 2.77532 33.3748 2.78287 33.3314 2.78993C33.2881 2.79597 33.2488 2.80151 33.2136 2.80655C33.138 2.81763 33.072 2.83527 33.0156 2.85945C32.9592 2.88363 32.9153 2.91637 32.8841 2.95768C32.8529 2.99798 32.8373 3.04836 32.8373 3.10881C32.8373 3.19646 32.869 3.26346 32.9325 3.30981C32.9969 3.35514 33.0786 3.37781 33.1773 3.37781Z" fill="currentColor"/>
|
||||
<path d="M29.7856 3.82364C29.5508 3.82364 29.3478 3.77377 29.1765 3.67402C29.0063 3.57327 28.8748 3.43323 28.7821 3.25389C28.6894 3.07354 28.6431 2.86448 28.6431 2.62671C28.6431 2.38692 28.6894 2.17736 28.7821 1.99802C28.8748 1.81767 29.0063 1.67763 29.1765 1.57789C29.3478 1.47713 29.5508 1.42676 29.7856 1.42676C30.0203 1.42676 30.2229 1.47713 30.3931 1.57789C30.5644 1.67763 30.6964 1.81767 30.7891 1.99802C30.8818 2.17736 30.9281 2.38692 30.9281 2.62671C30.9281 2.86448 30.8818 3.07354 30.7891 3.25389C30.6964 3.43323 30.5644 3.57327 30.3931 3.67402C30.2229 3.77377 30.0203 3.82364 29.7856 3.82364ZM29.7886 3.32492C29.8954 3.32492 29.9846 3.29469 30.0561 3.23424C30.1276 3.17278 30.1815 3.08916 30.2178 2.98337C30.2551 2.87758 30.2737 2.75718 30.2737 2.62218C30.2737 2.48717 30.2551 2.36677 30.2178 2.26098C30.1815 2.15519 30.1276 2.07157 30.0561 2.01011C29.9846 1.94865 29.8954 1.91792 29.7886 1.91792C29.6808 1.91792 29.5901 1.94865 29.5166 2.01011C29.444 2.07157 29.3891 2.15519 29.3519 2.26098C29.3156 2.36677 29.2974 2.48717 29.2974 2.62218C29.2974 2.75718 29.3156 2.87758 29.3519 2.98337C29.3891 3.08916 29.444 3.17278 29.5166 3.23424C29.5901 3.29469 29.6808 3.32492 29.7886 3.32492Z" fill="currentColor"/>
|
||||
<path d="M28.3413 1.45752V1.94112H26.9434V1.45752H28.3413ZM27.2607 0.901367H27.9045V3.06551C27.9045 3.12496 27.9136 3.1713 27.9317 3.20455C27.9499 3.23679 27.9751 3.25946 28.0073 3.27256C28.0405 3.28565 28.0788 3.2922 28.1222 3.2922C28.1524 3.2922 28.1826 3.28968 28.2128 3.28465C28.2431 3.2786 28.2662 3.27407 28.2823 3.27105L28.3836 3.75012C28.3514 3.76019 28.306 3.77178 28.2476 3.78488C28.1892 3.79898 28.1181 3.80755 28.0345 3.81057C27.8793 3.81662 27.7433 3.79596 27.6265 3.74861C27.5106 3.70126 27.4204 3.62771 27.3559 3.52796C27.2915 3.42822 27.2597 3.30228 27.2607 3.15014V0.901367Z" fill="currentColor"/>
|
||||
<path d="M25.7007 1.45752V1.94112H24.3027V1.45752H25.7007ZM24.6201 0.901367H25.2639V3.06551C25.2639 3.12496 25.273 3.1713 25.2911 3.20455C25.3092 3.23679 25.3344 3.25946 25.3667 3.27256C25.3999 3.28565 25.4382 3.2922 25.4815 3.2922C25.5118 3.2922 25.542 3.28968 25.5722 3.28465C25.6024 3.2786 25.6256 3.27407 25.6417 3.27105L25.743 3.75012C25.7107 3.76019 25.6654 3.77178 25.607 3.78488C25.5485 3.79898 25.4775 3.80755 25.3939 3.81057C25.2387 3.81662 25.1027 3.79596 24.9858 3.74861C24.87 3.70126 24.7798 3.62771 24.7153 3.52796C24.6508 3.42822 24.6191 3.30228 24.6201 3.15014V0.901367Z" fill="currentColor"/>
|
||||
<path d="M22.9062 3.82462C22.6714 3.82462 22.4684 3.77474 22.2972 3.675C22.1269 3.57425 21.9954 3.4342 21.9027 3.25487C21.81 3.07452 21.7637 2.86546 21.7637 2.62769C21.7637 2.3879 21.81 2.17833 21.9027 1.999C21.9954 1.81865 22.1269 1.67861 22.2972 1.57886C22.4684 1.47811 22.6714 1.42773 22.9062 1.42773C23.1409 1.42773 23.3435 1.47811 23.5137 1.57886C23.685 1.67861 23.817 1.81865 23.9097 1.999C24.0024 2.17833 24.0487 2.3879 24.0487 2.62769C24.0487 2.86546 24.0024 3.07452 23.9097 3.25487C23.817 3.4342 23.685 3.57425 23.5137 3.675C23.3435 3.77474 23.1409 3.82462 22.9062 3.82462ZM22.9092 3.3259C23.016 3.3259 23.1052 3.29567 23.1767 3.23522C23.2482 3.17376 23.3021 3.09014 23.3384 2.98435C23.3757 2.87856 23.3943 2.75816 23.3943 2.62315C23.3943 2.48815 23.3757 2.36775 23.3384 2.26196C23.3021 2.15617 23.2482 2.07254 23.1767 2.01109C23.1052 1.94963 23.016 1.9189 22.9092 1.9189C22.8014 1.9189 22.7107 1.94963 22.6372 2.01109C22.5646 2.07254 22.5097 2.15617 22.4725 2.26196C22.4362 2.36775 22.4181 2.48815 22.4181 2.62315C22.4181 2.75816 22.4362 2.87856 22.4725 2.98435C22.5097 3.09014 22.5646 3.17376 22.6372 3.23522C22.7107 3.29567 22.8014 3.3259 22.9092 3.3259Z" fill="currentColor"/>
|
||||
<path d="M19.8538 2.43727V3.77928H19.21V1.45796H19.8235V1.86752H19.8507C19.9021 1.73251 19.9883 1.62571 20.1092 1.54712C20.2301 1.46753 20.3767 1.42773 20.549 1.42773C20.7102 1.42773 20.8507 1.463 20.9706 1.53352C21.0905 1.60405 21.1837 1.7048 21.2502 1.83578C21.3167 1.96575 21.3499 2.12091 21.3499 2.30125V3.77928H20.7061V2.41611C20.7071 2.27405 20.6709 2.16322 20.5973 2.08363C20.5238 2.00303 20.4225 1.96273 20.2935 1.96273C20.2069 1.96273 20.1303 1.98136 20.0638 2.01864C19.9983 2.05592 19.947 2.11033 19.9097 2.18186C19.8734 2.25239 19.8548 2.33752 19.8538 2.43727Z" fill="currentColor"/>
|
||||
<path d="M16.7385 3.82364C16.4997 3.82364 16.2942 3.77528 16.1219 3.67856C15.9506 3.58083 15.8186 3.4428 15.726 3.26447C15.6333 3.08513 15.5869 2.87305 15.5869 2.62822C15.5869 2.38944 15.6333 2.17988 15.726 1.99953C15.8186 1.81919 15.9491 1.67864 16.1174 1.57789C16.2866 1.47713 16.4851 1.42676 16.7128 1.42676C16.866 1.42676 17.0085 1.45144 17.1405 1.50081C17.2735 1.54917 17.3894 1.62222 17.4881 1.71995C17.5878 1.81767 17.6654 1.94059 17.7208 2.0887C17.7762 2.23579 17.804 2.40808 17.804 2.60555V2.78237H15.8438V2.38339H17.1979C17.1979 2.2907 17.1778 2.20859 17.1375 2.13706C17.0972 2.06552 17.0413 2.00961 16.9697 1.96931C16.8992 1.928 16.8171 1.90734 16.7234 1.90734C16.6257 1.90734 16.539 1.93001 16.4635 1.97535C16.3889 2.01968 16.3305 2.07963 16.2881 2.15519C16.2458 2.22975 16.2242 2.31287 16.2232 2.40455V2.78388C16.2232 2.89874 16.2443 2.99798 16.2866 3.0816C16.33 3.16523 16.3909 3.22971 16.4695 3.27505C16.5481 3.32038 16.6413 3.34305 16.7491 3.34305C16.8206 3.34305 16.8861 3.33298 16.9455 3.31283C17.005 3.29268 17.0559 3.26245 17.0982 3.22215C17.1405 3.18185 17.1727 3.13248 17.1949 3.07405L17.7904 3.11334C17.7601 3.25641 17.6982 3.38134 17.6045 3.48814C17.5118 3.59393 17.3919 3.67654 17.2448 3.73599C17.0987 3.79442 16.9299 3.82364 16.7385 3.82364Z" fill="currentColor"/>
|
||||
<path d="M12.9878 4.64977V1.45796H13.6225V1.84787H13.6512C13.6795 1.7854 13.7203 1.72193 13.7737 1.65745C13.8281 1.59196 13.8986 1.53755 13.9852 1.49423C14.0729 1.4499 14.1817 1.42773 14.3117 1.42773C14.4809 1.42773 14.6371 1.47207 14.7802 1.56073C14.9232 1.64838 15.0376 1.78087 15.1232 1.95819C15.2089 2.13451 15.2517 2.35566 15.2517 2.62164C15.2517 2.88057 15.2099 3.0992 15.1262 3.27753C15.0436 3.45486 14.9308 3.58936 14.7877 3.68104C14.6457 3.77172 14.4865 3.81706 14.3102 3.81706C14.1852 3.81706 14.0789 3.79641 13.9913 3.7551C13.9046 3.71379 13.8336 3.6619 13.7782 3.59944C13.7228 3.53596 13.6805 3.47199 13.6512 3.4075H13.6316V4.64977H12.9878ZM13.618 2.61862C13.618 2.75665 13.6371 2.87705 13.6754 2.97981C13.7137 3.08258 13.7691 3.16268 13.8417 3.22011C13.9142 3.27653 14.0024 3.30474 14.1061 3.30474C14.2109 3.30474 14.2996 3.27602 14.3721 3.21859C14.4447 3.16016 14.4996 3.07956 14.5368 2.97679C14.5751 2.87302 14.5943 2.75363 14.5943 2.61862C14.5943 2.48462 14.5756 2.36674 14.5384 2.26498C14.5011 2.16322 14.4462 2.08363 14.3736 2.0262C14.3011 1.96877 14.2119 1.94006 14.1061 1.94006C14.0014 1.94006 13.9127 1.96776 13.8402 2.02318C13.7686 2.07859 13.7137 2.15718 13.6754 2.25894C13.6371 2.36069 13.618 2.48059 13.618 2.61862Z" fill="currentColor"/>
|
||||
<path d="M11.1814 3.82213C11.0333 3.82213 10.9013 3.79644 10.7854 3.74505C10.6696 3.69266 10.5779 3.61559 10.5104 3.51383C10.4439 3.41106 10.4106 3.28311 10.4106 3.12996C10.4106 3.001 10.4343 2.89269 10.4817 2.80504C10.529 2.71739 10.5935 2.64686 10.6751 2.59346C10.7567 2.54006 10.8494 2.49976 10.9532 2.47256C11.058 2.44536 11.1678 2.42621 11.2827 2.41513C11.4177 2.40103 11.5265 2.38793 11.6091 2.37584C11.6917 2.36274 11.7516 2.3436 11.7889 2.31841C11.8262 2.29322 11.8448 2.25594 11.8448 2.20658V2.19751C11.8448 2.10179 11.8146 2.02774 11.7542 1.97535C11.6947 1.92296 11.6101 1.89676 11.5003 1.89676C11.3844 1.89676 11.2922 1.92246 11.2237 1.97384C11.1552 2.02422 11.1099 2.08769 11.0877 2.16426L10.4923 2.1159C10.5225 1.97485 10.5819 1.85294 10.6706 1.75017C10.7592 1.6464 10.8736 1.5668 11.0136 1.51139C11.1547 1.45497 11.3179 1.42676 11.5033 1.42676C11.6323 1.42676 11.7557 1.44187 11.8736 1.4721C11.9924 1.50232 12.0977 1.54917 12.1894 1.61264C12.2821 1.67612 12.3552 1.75773 12.4085 1.85747C12.4619 1.95621 12.4886 2.07459 12.4886 2.21262V3.7783H11.8781V3.4564H11.86C11.8227 3.52894 11.7728 3.59292 11.7103 3.64833C11.6479 3.70274 11.5728 3.74556 11.4852 3.77679C11.3975 3.80702 11.2963 3.82213 11.1814 3.82213ZM11.3658 3.37781C11.4605 3.37781 11.5441 3.35917 11.6166 3.3219C11.6892 3.28361 11.7461 3.23223 11.7874 3.16775C11.8287 3.10327 11.8494 3.03022 11.8494 2.94861V2.70227C11.8292 2.71537 11.8015 2.72746 11.7663 2.73854C11.732 2.74862 11.6932 2.75819 11.6499 2.76726C11.6066 2.77532 11.5632 2.78287 11.5199 2.78993C11.4766 2.79597 11.4373 2.80151 11.402 2.80655C11.3265 2.81763 11.2605 2.83527 11.2041 2.85945C11.1476 2.88363 11.1038 2.91637 11.0726 2.95768C11.0413 2.99798 11.0257 3.04836 11.0257 3.10881C11.0257 3.19646 11.0575 3.26346 11.1209 3.30981C11.1854 3.35514 11.267 3.37781 11.3658 3.37781Z" fill="currentColor"/>
|
||||
<path d="M8.50757 2.43667V3.77868H7.86377V0.683594H8.48944V1.86692H8.51664C8.56903 1.7299 8.65366 1.6226 8.77053 1.54502C8.88741 1.46643 9.034 1.42714 9.21032 1.42714C9.37152 1.42714 9.51207 1.4624 9.63196 1.53293C9.75286 1.60245 9.84656 1.7027 9.91306 1.83367C9.98056 1.96364 10.0138 2.1193 10.0128 2.30066V3.77868H9.369V2.41551C9.37001 2.27245 9.33374 2.16112 9.26019 2.08152C9.18765 2.00193 9.08589 1.96213 8.95491 1.96213C8.86726 1.96213 8.78968 1.98077 8.72217 2.01805C8.65568 2.05533 8.60329 2.10973 8.565 2.18127C8.52772 2.25179 8.50858 2.33693 8.50757 2.43667Z" fill="currentColor"/>
|
||||
<path d="M7.40576 2.1199L6.81636 2.15617C6.80629 2.10579 6.78462 2.06045 6.75138 2.02015C6.71813 1.97885 6.6743 1.9461 6.61989 1.92192C6.5665 1.89673 6.50252 1.88414 6.42796 1.88414C6.32822 1.88414 6.24409 1.9053 6.17558 1.94761C6.10707 1.98892 6.07281 2.04433 6.07281 2.11385C6.07281 2.16927 6.09498 2.21612 6.13931 2.2544C6.18364 2.29269 6.25971 2.32342 6.36751 2.34659L6.78765 2.43122C7.01333 2.47757 7.18159 2.55212 7.29241 2.65489C7.40324 2.75766 7.45865 2.89266 7.45865 3.05991C7.45865 3.21205 7.41382 3.34554 7.32415 3.4604C7.23549 3.57526 7.11358 3.66492 6.95842 3.72941C6.80427 3.79288 6.62644 3.82462 6.42494 3.82462C6.11765 3.82462 5.87282 3.76064 5.69046 3.63268C5.50911 3.50372 5.40282 3.32841 5.37158 3.10676L6.00481 3.07351C6.02395 3.16721 6.07029 3.23875 6.14384 3.28811C6.21739 3.33647 6.31159 3.36065 6.42645 3.36065C6.53929 3.36065 6.62997 3.33899 6.69848 3.29567C6.768 3.25134 6.80326 3.19441 6.80427 3.1249C6.80326 3.06646 6.77858 3.0186 6.73022 2.98132C6.68186 2.94304 6.6073 2.91382 6.50655 2.89367L6.10455 2.81357C5.87786 2.76823 5.7091 2.68965 5.59827 2.57781C5.48845 2.46598 5.43354 2.32342 5.43354 2.15012C5.43354 2.00101 5.47384 1.87255 5.55445 1.76475C5.63606 1.65694 5.75041 1.57382 5.89751 1.51539C6.04561 1.45695 6.2189 1.42773 6.41738 1.42773C6.71057 1.42773 6.94129 1.4897 7.10955 1.61362C7.27881 1.73755 7.37755 1.9063 7.40576 2.1199Z" fill="currentColor"/>
|
||||
<path d="M2.92866 3.82364C2.69391 3.82364 2.49089 3.77377 2.31961 3.67402C2.14934 3.57327 2.01786 3.43323 1.92517 3.25389C1.83248 3.07354 1.78613 2.86448 1.78613 2.62671C1.78613 2.38692 1.83248 2.17736 1.92517 1.99802C2.01786 1.81767 2.14934 1.67763 2.31961 1.57789C2.49089 1.47713 2.69391 1.42676 2.92866 1.42676C3.16341 1.42676 3.36592 1.47713 3.53619 1.57789C3.70747 1.67763 3.83945 1.81767 3.93214 1.99802C4.02483 2.17736 4.07118 2.38692 4.07118 2.62671C4.07118 2.86448 4.02483 3.07354 3.93214 3.25389C3.83945 3.43323 3.70747 3.57327 3.53619 3.67402C3.36592 3.77377 3.16341 3.82364 2.92866 3.82364ZM2.93168 3.32492C3.03848 3.32492 3.12764 3.29469 3.19917 3.23424C3.27071 3.17278 3.32461 3.08916 3.36088 2.98337C3.39816 2.87758 3.4168 2.75718 3.4168 2.62218C3.4168 2.48717 3.39816 2.36677 3.36088 2.26098C3.32461 2.15519 3.27071 2.07157 3.19917 2.01011C3.12764 1.94865 3.03848 1.91792 2.93168 1.91792C2.82387 1.91792 2.7332 1.94865 2.65965 2.01011C2.58711 2.07157 2.5322 2.15519 2.49492 2.26098C2.45865 2.36677 2.44051 2.48717 2.44051 2.62218C2.44051 2.75718 2.45865 2.87758 2.49492 2.98337C2.5322 3.08916 2.58711 3.17278 2.65965 3.23424C2.7332 3.29469 2.82387 3.32492 2.93168 3.32492Z" fill="currentColor"/>
|
||||
<path d="M1.48533 1.45752V1.94112H0.0874023L0.0874023 1.45752H1.48533ZM0.40477 0.901367H1.04857V3.06551C1.04857 3.12496 1.05764 3.1713 1.07578 3.20455C1.09391 3.23679 1.1191 3.25946 1.15134 3.27256C1.18459 3.28565 1.22287 3.2922 1.2662 3.2922C1.29642 3.2922 1.32665 3.28968 1.35687 3.28465C1.3871 3.2786 1.41027 3.27407 1.42639 3.27105L1.52765 3.75012C1.49541 3.76019 1.45007 3.77178 1.39163 3.78488C1.3332 3.79898 1.26217 3.80755 1.17854 3.81057C1.02339 3.81662 0.88737 3.79596 0.770499 3.74861C0.654634 3.70126 0.564461 3.62771 0.49998 3.52796C0.435499 3.42822 0.403763 3.30228 0.40477 3.15014V0.901367Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
`;
|
||||
@@ -1,151 +0,0 @@
|
||||
import {
|
||||
BulletedListIcon,
|
||||
CheckBoxIcon,
|
||||
CodeBlockIcon,
|
||||
DividerIcon,
|
||||
Heading1Icon,
|
||||
Heading2Icon,
|
||||
Heading3Icon,
|
||||
Heading4Icon,
|
||||
Heading5Icon,
|
||||
Heading6Icon,
|
||||
NumberedListIcon,
|
||||
QuoteIcon,
|
||||
TextIcon,
|
||||
} from '@blocksuite/affine-components/icons';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import type { TemplateResult } from 'lit';
|
||||
|
||||
export const BUTTON_GROUP_LENGTH = 10;
|
||||
|
||||
export type NoteMenuItem = {
|
||||
icon: TemplateResult<1>;
|
||||
tooltip: string;
|
||||
childFlavour: NoteChildrenFlavour;
|
||||
childType: string | null;
|
||||
};
|
||||
|
||||
const LIST_ITEMS = [
|
||||
{
|
||||
flavour: 'affine:list',
|
||||
type: 'bulleted',
|
||||
name: 'Bulleted List',
|
||||
description: 'A simple bulleted list.',
|
||||
icon: BulletedListIcon,
|
||||
tooltip: 'Drag/Click to insert Bulleted List',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:list',
|
||||
type: 'numbered',
|
||||
name: 'Numbered List',
|
||||
description: 'A list with numbering.',
|
||||
icon: NumberedListIcon,
|
||||
tooltip: 'Drag/Click to insert Numbered List',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:list',
|
||||
type: 'todo',
|
||||
name: 'To-do List',
|
||||
description: 'Track tasks with a to-do list.',
|
||||
icon: CheckBoxIcon,
|
||||
tooltip: 'Drag/Click to insert To-do List',
|
||||
},
|
||||
];
|
||||
|
||||
const TEXT_ITEMS = [
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'text',
|
||||
name: 'Text',
|
||||
description: 'Start typing with plain text.',
|
||||
icon: TextIcon,
|
||||
tooltip: 'Drag/Click to insert Text block',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h1',
|
||||
name: 'Heading 1',
|
||||
description: 'Headings in the largest font.',
|
||||
icon: Heading1Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 1',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h2',
|
||||
name: 'Heading 2',
|
||||
description: 'Headings in the 2nd font size.',
|
||||
icon: Heading2Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 2',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h3',
|
||||
name: 'Heading 3',
|
||||
description: 'Headings in the 3rd font size.',
|
||||
icon: Heading3Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 3',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h4',
|
||||
name: 'Heading 4',
|
||||
description: 'Heading in the 4th font size.',
|
||||
icon: Heading4Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 4',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h5',
|
||||
name: 'Heading 5',
|
||||
description: 'Heading in the 5th font size.',
|
||||
icon: Heading5Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 5',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'h6',
|
||||
name: 'Heading 6',
|
||||
description: 'Heading in the 6th font size.',
|
||||
icon: Heading6Icon,
|
||||
tooltip: 'Drag/Click to insert Heading 6',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:code',
|
||||
type: 'code',
|
||||
name: 'Code Block',
|
||||
description: 'Capture a code snippet.',
|
||||
icon: CodeBlockIcon,
|
||||
tooltip: 'Drag/Click to insert Code Block',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:paragraph',
|
||||
type: 'quote',
|
||||
name: 'Quote',
|
||||
description: 'Capture a quote.',
|
||||
icon: QuoteIcon,
|
||||
tooltip: 'Drag/Click to insert Quote',
|
||||
},
|
||||
{
|
||||
flavour: 'affine:divider',
|
||||
type: null,
|
||||
name: 'Divider',
|
||||
description: 'A visual divider.',
|
||||
icon: DividerIcon,
|
||||
tooltip: 'A visual divider',
|
||||
},
|
||||
];
|
||||
|
||||
// TODO: add image, bookmark, database blocks
|
||||
export const NOTE_MENU_ITEMS = TEXT_ITEMS.concat(LIST_ITEMS)
|
||||
.filter(item => item.name !== 'Divider')
|
||||
.map(item => {
|
||||
return {
|
||||
icon: item.icon,
|
||||
tooltip:
|
||||
item.type !== 'text'
|
||||
? item.tooltip.replace('Drag/Click to insert ', '')
|
||||
: 'Text',
|
||||
childFlavour: item.flavour as NoteChildrenFlavour,
|
||||
childType: item.type,
|
||||
} as NoteMenuItem;
|
||||
});
|
||||
@@ -1,208 +0,0 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmark';
|
||||
import { addImages, LoadedImageIcon } from '@blocksuite/affine-block-image';
|
||||
import { AttachmentIcon, LinkIcon } from '@blocksuite/affine-components/icons';
|
||||
import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
getImageFilesFromLocal,
|
||||
openFileOrFiles,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import type { NoteToolOption } from '../../../gfx-tool/note-tool.js';
|
||||
import { NOTE_MENU_ITEMS } from './note-menu-config.js';
|
||||
|
||||
export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
z-index: -1;
|
||||
}
|
||||
.menu-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.button-group-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
fill: var(--affine-icon-color);
|
||||
}
|
||||
.button-group-container svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.divider {
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background: var(--affine-border-color);
|
||||
transform: scaleX(0.5);
|
||||
margin: 0 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'affine:note';
|
||||
|
||||
private async _addImages() {
|
||||
this._imageLoading = true;
|
||||
const imageFiles = await getImageFilesFromLocal();
|
||||
const ids = await addImages(this.edgeless.std, imageFiles, {
|
||||
maxWidth: MAX_IMAGE_WIDTH,
|
||||
});
|
||||
this._imageLoading = false;
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.selection.set({ elements: ids });
|
||||
}
|
||||
|
||||
private _onHandleLinkButtonClick() {
|
||||
const [_, { insertedLinkType }] = this.edgeless.service.std.command.exec(
|
||||
insertLinkByQuickSearchCommand
|
||||
);
|
||||
|
||||
insertedLinkType
|
||||
?.then(type => {
|
||||
const flavour = type?.flavour;
|
||||
if (!flavour) return;
|
||||
|
||||
this.edgeless.std
|
||||
.getOptional(TelemetryProvider)
|
||||
?.track('CanvasElementAdded', {
|
||||
control: 'toolbar:general',
|
||||
page: 'whiteboard editor',
|
||||
module: 'toolbar',
|
||||
type: flavour.split(':')[1],
|
||||
});
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
override disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
this.disposables.add(
|
||||
effect(() => {
|
||||
const tool = this.gfx.tool.currentToolOption$.value;
|
||||
|
||||
if (tool?.type !== 'affine:note') return;
|
||||
this.childFlavour = tool.childFlavour;
|
||||
this.childType = tool.childType;
|
||||
this.tip = tool.tip;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override render() {
|
||||
const { childType } = this;
|
||||
|
||||
return html`
|
||||
<edgeless-slide-menu>
|
||||
<div class="menu-content">
|
||||
<!-- add to edgeless -->
|
||||
<div class="button-group-container">
|
||||
<edgeless-tool-icon-button
|
||||
.activeMode=${'background'}
|
||||
.tooltip=${'Image'}
|
||||
@click=${this._addImages}
|
||||
.disabled=${this._imageLoading}
|
||||
>
|
||||
${LoadedImageIcon}
|
||||
</edgeless-tool-icon-button>
|
||||
|
||||
<edgeless-tool-icon-button
|
||||
.activeMode=${'background'}
|
||||
.tooltip=${html`<affine-tooltip-content-with-shortcut
|
||||
data-tip="${'Link'}"
|
||||
data-shortcut="${'@'}"
|
||||
></affine-tooltip-content-with-shortcut>`}
|
||||
@click=${() => {
|
||||
this._onHandleLinkButtonClick();
|
||||
}}
|
||||
>
|
||||
${LinkIcon}
|
||||
</edgeless-tool-icon-button>
|
||||
|
||||
<edgeless-tool-icon-button
|
||||
.activeMode=${'background'}
|
||||
.tooltip=${'File'}
|
||||
@click=${async () => {
|
||||
const file = await openFileOrFiles();
|
||||
if (!file) return;
|
||||
await addAttachments(this.edgeless.std, [file]);
|
||||
this.gfx.tool.setTool('default');
|
||||
this.edgeless.std
|
||||
.getOptional(TelemetryProvider)
|
||||
?.track('CanvasElementAdded', {
|
||||
control: 'toolbar:general',
|
||||
page: 'whiteboard editor',
|
||||
module: 'toolbar',
|
||||
segment: 'toolbar',
|
||||
type: 'attachment',
|
||||
});
|
||||
}}
|
||||
>
|
||||
${AttachmentIcon}
|
||||
</edgeless-tool-icon-button>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<!-- add to note -->
|
||||
<div class="button-group-container">
|
||||
${repeat(
|
||||
NOTE_MENU_ITEMS,
|
||||
item => item.childFlavour,
|
||||
item => html`
|
||||
<edgeless-tool-icon-button
|
||||
.active=${childType === item.childType}
|
||||
.activeMode=${'background'}
|
||||
.tooltip=${item.tooltip}
|
||||
@click=${() =>
|
||||
this.onChange({
|
||||
childFlavour: item.childFlavour,
|
||||
childType: item.childType,
|
||||
tip: item.tooltip,
|
||||
})}
|
||||
>
|
||||
${item.icon}
|
||||
</edgeless-tool-icon-button>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</edgeless-slide-menu>
|
||||
`;
|
||||
}
|
||||
|
||||
@state()
|
||||
private accessor _imageLoading = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor childFlavour!: NoteChildrenFlavour;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor childType!: string | null;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onChange!: (
|
||||
props: Partial<{
|
||||
childFlavour: NoteToolOption['childFlavour'];
|
||||
childType: string | null;
|
||||
tip: string;
|
||||
}>
|
||||
) => void;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor tip!: string;
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
import {
|
||||
Heading1Icon,
|
||||
LinkIcon,
|
||||
TextIcon,
|
||||
} from '@blocksuite/affine-components/icons';
|
||||
import {
|
||||
EditPropsStore,
|
||||
ThemeProvider,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { SignalWatcher } from '@blocksuite/global/lit';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
|
||||
import type { NoteToolOption } from '../../../gfx-tool/note-tool.js';
|
||||
import { toShapeNotToAdapt } from './icon.js';
|
||||
|
||||
export class EdgelessNoteSeniorButton extends EdgelessToolbarToolMixin(
|
||||
SignalWatcher(LitElement)
|
||||
) {
|
||||
static override styles = css`
|
||||
:host,
|
||||
.edgeless-note-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
:host * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.note-root[data-app-theme='light'] {
|
||||
--paper-border-color: var(--affine-pure-white);
|
||||
--paper-foriegn-color: rgba(0, 0, 0, 0.1);
|
||||
--paper-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25);
|
||||
--icon-card-bg: #fff;
|
||||
--icon-card-shadow:
|
||||
0px 2px 4px rgba(0, 0, 0, 0.22), inset 0px -2px 1px rgba(0, 0, 0, 0.14);
|
||||
}
|
||||
.note-root[data-app-theme='dark'] {
|
||||
--paper-border-color: var(--affine-divider-color);
|
||||
--paper-foriegn-color: rgba(255, 255, 255, 0.12);
|
||||
--paper-shadow: 0px 2px 6px rgba(0, 0, 0, 0.8);
|
||||
--icon-card-bg: #343434;
|
||||
--icon-card-shadow:
|
||||
0px 2px 4px rgba(0, 0, 0, 0.6),
|
||||
inset 0px -2px 1px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.note-root {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
background: transparent;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
.paper {
|
||||
--y: 20px;
|
||||
--r: 4.42deg;
|
||||
width: 60px;
|
||||
height: 72px;
|
||||
background: var(--paper-bg);
|
||||
border: 1px solid var(--paper-border-color);
|
||||
position: absolute;
|
||||
transform: translateY(var(--y)) rotate(var(--r));
|
||||
color: var(--paper-foriegn-color);
|
||||
box-shadow: var(--paper-shadow);
|
||||
padding-top: 32px;
|
||||
padding-left: 3px;
|
||||
transition: transform 0.4s ease;
|
||||
}
|
||||
.edgeless-toolbar-note-icon {
|
||||
position: absolute;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--affine-icon-secondary);
|
||||
background: var(--icon-card-bg);
|
||||
box-shadow: var(--icon-card-shadow);
|
||||
bottom: 12px;
|
||||
transition: transform 0.4s ease;
|
||||
transform: translateX(var(--x)) translateY(var(--y)) rotate(var(--r));
|
||||
}
|
||||
.edgeless-toolbar-note-icon.link {
|
||||
--x: -22px;
|
||||
--y: -5px;
|
||||
--r: -6deg;
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
.edgeless-toolbar-note-icon.text {
|
||||
--r: 4deg;
|
||||
--x: 0px;
|
||||
--y: 0px;
|
||||
}
|
||||
.edgeless-toolbar-note-icon.heading {
|
||||
--x: 21px;
|
||||
--y: -7px;
|
||||
--r: 8deg;
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.note-root:hover .paper {
|
||||
--y: 15px;
|
||||
}
|
||||
.note-root:hover .link {
|
||||
--x: -25px;
|
||||
--y: -5px;
|
||||
--r: -9.5deg;
|
||||
}
|
||||
.note-root:hover .text {
|
||||
--y: -10px;
|
||||
}
|
||||
.note-root:hover .heading {
|
||||
--x: 23px;
|
||||
--y: -8px;
|
||||
--r: 15deg;
|
||||
}
|
||||
`;
|
||||
|
||||
private readonly _noteBg$ = computed(() => {
|
||||
return this.edgeless.std
|
||||
.get(ThemeProvider)
|
||||
.generateColorProperty(
|
||||
this.edgeless.std.get(EditPropsStore).lastProps$.value['affine:note']
|
||||
.background
|
||||
);
|
||||
});
|
||||
|
||||
private readonly _states = ['childFlavour', 'childType', 'tip'] as const;
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
override type = 'affine:note' as const;
|
||||
|
||||
private _toggleNoteMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
|
||||
const { edgeless, childFlavour, childType, tip } = this;
|
||||
|
||||
this.setEdgelessTool({
|
||||
type: 'affine:note',
|
||||
childFlavour,
|
||||
childType,
|
||||
tip,
|
||||
});
|
||||
const menu = this.createPopper('edgeless-note-menu', this);
|
||||
|
||||
Object.assign(menu.element, {
|
||||
edgeless,
|
||||
childFlavour,
|
||||
childType,
|
||||
tip,
|
||||
onChange: (
|
||||
props: Partial<{
|
||||
childFlavour: NoteToolOption['childFlavour'];
|
||||
childType: string | null;
|
||||
tip: string;
|
||||
}>
|
||||
) => {
|
||||
this._states.forEach(key => {
|
||||
// oxlint-disable-next-line eqeqeq
|
||||
if (props[key] != undefined) {
|
||||
Object.assign(this, { [key]: props[key] });
|
||||
}
|
||||
});
|
||||
this.setEdgelessTool({
|
||||
type: 'affine:note',
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
override render() {
|
||||
const appTheme = this.edgeless.std.get(ThemeProvider).app$.value;
|
||||
|
||||
return html`<edgeless-toolbar-button
|
||||
class="edgeless-note-button"
|
||||
.tooltip=${this.popper
|
||||
? ''
|
||||
: html`<affine-tooltip-content-with-shortcut
|
||||
data-tip="${'Note'}"
|
||||
data-shortcut="${'N'}"
|
||||
></affine-tooltip-content-with-shortcut>`}
|
||||
.tooltipOffset=${5}
|
||||
>
|
||||
<div
|
||||
class="note-root"
|
||||
data-app-theme=${appTheme}
|
||||
@click=${this._toggleNoteMenu}
|
||||
style="--paper-bg: ${this._noteBg$.value}"
|
||||
>
|
||||
<div class="paper">${toShapeNotToAdapt}</div>
|
||||
<div class="edgeless-toolbar-note-icon link">${LinkIcon}</div>
|
||||
<div class="edgeless-toolbar-note-icon heading">${Heading1Icon}</div>
|
||||
<div class="edgeless-toolbar-note-icon text">${TextIcon}</div>
|
||||
</div>
|
||||
</edgeless-toolbar-button>`;
|
||||
}
|
||||
|
||||
// TODO: better to extract these states outside of component?
|
||||
@state()
|
||||
accessor childFlavour: NoteToolOption['childFlavour'] = 'affine:paragraph';
|
||||
|
||||
@state()
|
||||
accessor childType = 'text';
|
||||
|
||||
@state()
|
||||
accessor tip = 'Note';
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
import {
|
||||
createPopper,
|
||||
type MenuPopper,
|
||||
QuickToolMixin,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
|
||||
import { PageIcon } from '@blocksuite/icons/lit';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
|
||||
import type { NoteToolOption } from '../../../gfx-tool/note-tool.js';
|
||||
import type { EdgelessNoteMenu } from './note-menu.js';
|
||||
|
||||
export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
}
|
||||
`;
|
||||
|
||||
private _noteMenu: MenuPopper<EdgelessNoteMenu> | null = null;
|
||||
|
||||
private readonly _states = ['childFlavour', 'childType', 'tip'] as const;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'affine:note';
|
||||
|
||||
private _disposeMenu() {
|
||||
this._noteMenu?.dispose();
|
||||
this._noteMenu = null;
|
||||
}
|
||||
|
||||
private _toggleNoteMenu() {
|
||||
if (this._noteMenu) {
|
||||
this._disposeMenu();
|
||||
this.requestUpdate();
|
||||
} else {
|
||||
this.gfx.tool.setTool('affine:note', {
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
});
|
||||
this._noteMenu = createPopper('edgeless-note-menu', this);
|
||||
|
||||
this._noteMenu.element.edgeless = this.edgeless;
|
||||
this._noteMenu.element.childFlavour = this.childFlavour;
|
||||
this._noteMenu.element.childType = this.childType;
|
||||
this._noteMenu.element.tip = this.tip;
|
||||
this._noteMenu.element.onChange = (
|
||||
props: Partial<{
|
||||
childFlavour: NoteToolOption['childFlavour'];
|
||||
childType: string | null;
|
||||
tip: string;
|
||||
}>
|
||||
) => {
|
||||
this._states.forEach(key => {
|
||||
// oxlint-disable-next-line eqeqeq
|
||||
if (props[key] != undefined) {
|
||||
Object.assign(this, { [key]: props[key] });
|
||||
}
|
||||
});
|
||||
this.gfx.tool.setTool('affine:note', {
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._disposables.add(
|
||||
effect(() => {
|
||||
const value = this.gfx.tool.currentToolName$.value;
|
||||
if (value !== 'affine:note') {
|
||||
this._disposeMenu();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override disconnectedCallback() {
|
||||
this._disposeMenu();
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
override render() {
|
||||
const { active } = this;
|
||||
return html`
|
||||
<edgeless-tool-icon-button
|
||||
class="edgeless-note-button"
|
||||
.tooltip=${this._noteMenu
|
||||
? ''
|
||||
: html`<affine-tooltip-content-with-shortcut
|
||||
data-tip="${'Note'}"
|
||||
data-shortcut="${'N'}"
|
||||
></affine-tooltip-content-with-shortcut>`}
|
||||
.tooltipOffset=${17}
|
||||
.active=${active}
|
||||
.iconContainerPadding=${6}
|
||||
.iconSize=${'24px'}
|
||||
@click=${() => {
|
||||
this._toggleNoteMenu();
|
||||
}}
|
||||
>
|
||||
${PageIcon()}
|
||||
<toolbar-arrow-up-icon></toolbar-arrow-up-icon>
|
||||
</edgeless-tool-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
@state()
|
||||
accessor childFlavour: NoteToolOption['childFlavour'] = 'affine:paragraph';
|
||||
|
||||
@state()
|
||||
accessor childType = 'text';
|
||||
|
||||
@state()
|
||||
accessor tip = 'Text';
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { frameQuickTool } from '@blocksuite/affine-block-frame';
|
||||
import { noteSeniorTool } from '@blocksuite/affine-gfx-note';
|
||||
import { shapeSeniorTool } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
QuickToolExtension,
|
||||
@@ -35,15 +36,6 @@ const linkQuickTool = QuickToolExtension('link', ({ block, gfx }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const noteSeniorTool = SeniorToolExtension('note', ({ block }) => {
|
||||
return {
|
||||
name: 'Note',
|
||||
content: html`<edgeless-note-senior-button
|
||||
.edgeless=${block}
|
||||
></edgeless-note-senior-button>`,
|
||||
};
|
||||
});
|
||||
|
||||
const penSeniorTool = SeniorToolExtension('pen', ({ block }) => {
|
||||
return {
|
||||
name: 'Pen',
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
PresentTool,
|
||||
} from '@blocksuite/affine-block-frame';
|
||||
import { ConnectionOverlay } from '@blocksuite/affine-block-surface';
|
||||
import { NoteTool } from '@blocksuite/affine-gfx-note';
|
||||
import { ShapeTool } from '@blocksuite/affine-gfx-shape';
|
||||
import { TextTool } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
@@ -24,7 +25,6 @@ import { DefaultTool } from './gfx-tool/default-tool.js';
|
||||
import { EmptyTool } from './gfx-tool/empty-tool.js';
|
||||
import { EraserTool } from './gfx-tool/eraser-tool.js';
|
||||
import { LassoTool } from './gfx-tool/lasso-tool.js';
|
||||
import { NoteTool } from './gfx-tool/note-tool.js';
|
||||
import { PanTool } from './gfx-tool/pan-tool.js';
|
||||
import { TemplateTool } from './gfx-tool/template-tool.js';
|
||||
import { EditPropsMiddlewareBuilder } from './middlewares/base.js';
|
||||
|
||||
@@ -4,6 +4,5 @@ export { DefaultTool } from './default-tool.js';
|
||||
export { EmptyTool } from './empty-tool.js';
|
||||
export { EraserTool } from './eraser-tool.js';
|
||||
export { LassoTool, type LassoToolOption } from './lasso-tool.js';
|
||||
export { NoteTool, type NoteToolOption } from './note-tool.js';
|
||||
export { PanTool, type PanToolOption } from './pan-tool.js';
|
||||
export { TemplateTool } from './template-tool.js';
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
import type { SurfaceBlockComponent } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
addNote,
|
||||
EXCLUDING_MOUSE_OUT_CLASS_LIST,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import { hasClassNameInList } from '@blocksuite/affine-shared/utils';
|
||||
import type { PointerEventState } from '@blocksuite/block-std';
|
||||
import { BaseTool } from '@blocksuite/block-std/gfx';
|
||||
import { Point } from '@blocksuite/global/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
import { DraggingNoteOverlay, NoteOverlay } from '../utils/tool-overlay.js';
|
||||
|
||||
export type NoteToolOption = {
|
||||
childFlavour: NoteChildrenFlavour;
|
||||
childType: string | null;
|
||||
tip: string;
|
||||
};
|
||||
|
||||
export class NoteTool extends BaseTool<NoteToolOption> {
|
||||
static override toolName = 'affine:note';
|
||||
|
||||
private _draggingNoteOverlay: DraggingNoteOverlay | null = null;
|
||||
|
||||
private _noteOverlay: NoteOverlay | null = null;
|
||||
|
||||
// Ensure clear overlay before adding a new note
|
||||
private _clearOverlay() {
|
||||
this._noteOverlay = this._disposeOverlay(this._noteOverlay);
|
||||
this._draggingNoteOverlay = this._disposeOverlay(this._draggingNoteOverlay);
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
|
||||
}
|
||||
|
||||
private _disposeOverlay(overlay: NoteOverlay | null) {
|
||||
if (!overlay) return null;
|
||||
|
||||
overlay.dispose();
|
||||
(
|
||||
this.gfx.surfaceComponent as SurfaceBlockComponent
|
||||
)?.renderer.removeOverlay(overlay);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Should hide overlay when mouse is out of viewport or on menu and toolbar
|
||||
private _hideOverlay() {
|
||||
if (!this._noteOverlay) return;
|
||||
|
||||
this._noteOverlay.globalAlpha = 0;
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent)?.refresh();
|
||||
}
|
||||
|
||||
private _resize(shift = false) {
|
||||
const { _draggingNoteOverlay } = this;
|
||||
if (!_draggingNoteOverlay) return;
|
||||
|
||||
const draggingArea = this.controller.draggingArea$.peek();
|
||||
const { startX, startY } = draggingArea;
|
||||
let { endX, endY } = this.controller.draggingArea$.peek();
|
||||
|
||||
if (shift) {
|
||||
const w = Math.abs(endX - startX);
|
||||
const h = Math.abs(endY - startY);
|
||||
const m = Math.max(w, h);
|
||||
endX = startX + (endX > startX ? m : -m);
|
||||
endY = startY + (endY > startY ? m : -m);
|
||||
}
|
||||
|
||||
_draggingNoteOverlay.slots.draggingNoteUpdated.next({
|
||||
xywh: [
|
||||
Math.min(startX, endX),
|
||||
Math.min(startY, endY),
|
||||
Math.abs(startX - endX),
|
||||
Math.abs(startY - endY),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private _updateOverlayPosition(x: number, y: number) {
|
||||
if (!this._noteOverlay) return;
|
||||
this._noteOverlay.x = x;
|
||||
this._noteOverlay.y = y;
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
|
||||
}
|
||||
|
||||
override activate() {
|
||||
const attributes =
|
||||
this.std.get(EditPropsStore).lastProps$.value['affine:note'];
|
||||
const background = attributes.background;
|
||||
this._noteOverlay = new NoteOverlay(this.gfx, background);
|
||||
this._noteOverlay.text = this.activatedOption.tip;
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).renderer.addOverlay(
|
||||
this._noteOverlay
|
||||
);
|
||||
}
|
||||
|
||||
override click(e: PointerEventState): void {
|
||||
this._clearOverlay();
|
||||
|
||||
const { childFlavour, childType } = this.activatedOption;
|
||||
const options = {
|
||||
childFlavour,
|
||||
childType,
|
||||
collapse: false,
|
||||
};
|
||||
const point = new Point(e.point.x, e.point.y);
|
||||
addNote(this.std, point, options);
|
||||
}
|
||||
|
||||
override deactivate() {
|
||||
this._clearOverlay();
|
||||
}
|
||||
|
||||
override dragEnd() {
|
||||
if (!this._draggingNoteOverlay) return;
|
||||
|
||||
const { x, y, width, height } = this._draggingNoteOverlay;
|
||||
|
||||
this._disposeOverlay(this._draggingNoteOverlay);
|
||||
|
||||
const { childFlavour, childType } = this.activatedOption;
|
||||
|
||||
const options = {
|
||||
childFlavour,
|
||||
childType,
|
||||
collapse: true,
|
||||
};
|
||||
|
||||
const [viewX, viewY] = this.gfx.viewport.toViewCoord(x, y);
|
||||
|
||||
const point = new Point(viewX, viewY);
|
||||
|
||||
this.doc.captureSync();
|
||||
|
||||
addNote(
|
||||
this.std,
|
||||
point,
|
||||
options,
|
||||
Math.max(width, DEFAULT_NOTE_WIDTH),
|
||||
Math.max(height, DEFAULT_NOTE_HEIGHT)
|
||||
);
|
||||
}
|
||||
|
||||
override dragMove(e: PointerEventState) {
|
||||
if (!this._draggingNoteOverlay) return;
|
||||
|
||||
this._resize(e.keys.shift || this.gfx.keyboard.shiftKey$.peek());
|
||||
}
|
||||
|
||||
override dragStart() {
|
||||
this._clearOverlay();
|
||||
|
||||
const attributes =
|
||||
this.std.get(EditPropsStore).lastProps$.value['affine:note'];
|
||||
const background = attributes.background;
|
||||
this._draggingNoteOverlay = new DraggingNoteOverlay(this.gfx, background);
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).renderer.addOverlay(
|
||||
this._draggingNoteOverlay
|
||||
);
|
||||
}
|
||||
|
||||
override mounted() {
|
||||
this.disposable.add(
|
||||
effect(() => {
|
||||
const shiftPressed = this.gfx.keyboard.shiftKey$.value;
|
||||
|
||||
if (!this._draggingNoteOverlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._resize(shiftPressed);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override pointerMove(e: PointerEventState) {
|
||||
if (!this._noteOverlay) return;
|
||||
|
||||
// if mouse is in viewport and move, update overlay pointion and show overlay
|
||||
if (this._noteOverlay.globalAlpha === 0) this._noteOverlay.globalAlpha = 1;
|
||||
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
||||
this._updateOverlayPosition(x, y);
|
||||
}
|
||||
|
||||
override pointerOut(e: PointerEventState) {
|
||||
// should not hide the overlay when pointer on the area of other notes
|
||||
if (
|
||||
e.raw.relatedTarget &&
|
||||
hasClassNameInList(
|
||||
e.raw.relatedTarget as Element,
|
||||
EXCLUDING_MOUSE_OUT_CLASS_LIST
|
||||
)
|
||||
)
|
||||
return;
|
||||
this._hideOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@blocksuite/block-std/gfx' {
|
||||
interface GfxToolsMap {
|
||||
'affine:note': NoteTool;
|
||||
}
|
||||
|
||||
interface GfxToolsOption {
|
||||
'affine:note': NoteToolOption;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,3 @@
|
||||
export const NOTE_OVERLAY_OFFSET_X = 6;
|
||||
export const NOTE_OVERLAY_OFFSET_Y = 6;
|
||||
export const NOTE_OVERLAY_WIDTH = 100;
|
||||
export const NOTE_OVERLAY_HEIGHT = 50;
|
||||
export const NOTE_OVERLAY_CORNER_RADIUS = 6;
|
||||
export const NOTE_OVERLAY_STOKE_COLOR = '--affine-border-color';
|
||||
export const NOTE_OVERLAY_TEXT_COLOR = '--affine-icon-color';
|
||||
export const NOTE_OVERLAY_LIGHT_BACKGROUND_COLOR = 'rgba(252, 252, 253, 1)';
|
||||
export const NOTE_OVERLAY_DARK_BACKGROUND_COLOR = 'rgb(32, 32, 32)';
|
||||
|
||||
export const DEFAULT_NOTE_CHILD_FLAVOUR = 'affine:paragraph';
|
||||
export const DEFAULT_NOTE_CHILD_TYPE = 'text';
|
||||
export const DEFAULT_NOTE_TIP = 'Text';
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import {
|
||||
type SurfaceBlockComponent,
|
||||
ToolOverlay,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { type Color, DefaultTheme } from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { GfxController, GfxToolsMap } from '@blocksuite/block-std/gfx';
|
||||
import type { XYWH } from '@blocksuite/global/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import {
|
||||
NOTE_OVERLAY_CORNER_RADIUS,
|
||||
NOTE_OVERLAY_HEIGHT,
|
||||
NOTE_OVERLAY_OFFSET_X,
|
||||
NOTE_OVERLAY_OFFSET_Y,
|
||||
NOTE_OVERLAY_STOKE_COLOR,
|
||||
NOTE_OVERLAY_TEXT_COLOR,
|
||||
NOTE_OVERLAY_WIDTH,
|
||||
} from '../utils/consts.js';
|
||||
|
||||
export class NoteOverlay extends ToolOverlay {
|
||||
backgroundColor = 'transparent';
|
||||
|
||||
text = '';
|
||||
|
||||
constructor(gfx: GfxController, background: Color) {
|
||||
super(gfx);
|
||||
this.globalAlpha = 0;
|
||||
this.backgroundColor = gfx.std
|
||||
.get(ThemeProvider)
|
||||
.getColorValue(background, DefaultTheme.noteBackgrounColor, true);
|
||||
this.disposables.add(
|
||||
effect(() => {
|
||||
// when change note child type, update overlay text
|
||||
if (this.gfx.tool.currentToolName$.value !== 'affine:note') return;
|
||||
const tool =
|
||||
this.gfx.tool.currentTool$.peek() as GfxToolsMap['affine:note'];
|
||||
this.text = this._getOverlayText(tool.activatedOption.tip);
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _getOverlayText(text: string): string {
|
||||
return text[0].toUpperCase() + text.slice(1);
|
||||
}
|
||||
|
||||
override render(ctx: CanvasRenderingContext2D): void {
|
||||
ctx.globalAlpha = this.globalAlpha;
|
||||
const overlayX = this.x + NOTE_OVERLAY_OFFSET_X;
|
||||
const overlayY = this.y + NOTE_OVERLAY_OFFSET_Y;
|
||||
ctx.strokeStyle = this.gfx.std
|
||||
.get(ThemeProvider)
|
||||
.getCssVariableColor(NOTE_OVERLAY_STOKE_COLOR);
|
||||
// Draw the overlay rectangle
|
||||
ctx.fillStyle = this.backgroundColor;
|
||||
ctx.lineWidth = 4;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(overlayX + NOTE_OVERLAY_CORNER_RADIUS, overlayY);
|
||||
ctx.lineTo(
|
||||
overlayX + NOTE_OVERLAY_WIDTH - NOTE_OVERLAY_CORNER_RADIUS,
|
||||
overlayY
|
||||
);
|
||||
ctx.quadraticCurveTo(
|
||||
overlayX + NOTE_OVERLAY_WIDTH,
|
||||
overlayY,
|
||||
overlayX + NOTE_OVERLAY_WIDTH,
|
||||
overlayY + NOTE_OVERLAY_CORNER_RADIUS
|
||||
);
|
||||
ctx.lineTo(
|
||||
overlayX + NOTE_OVERLAY_WIDTH,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT - NOTE_OVERLAY_CORNER_RADIUS
|
||||
);
|
||||
ctx.quadraticCurveTo(
|
||||
overlayX + NOTE_OVERLAY_WIDTH,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT,
|
||||
overlayX + NOTE_OVERLAY_WIDTH - NOTE_OVERLAY_CORNER_RADIUS,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT
|
||||
);
|
||||
ctx.lineTo(
|
||||
overlayX + NOTE_OVERLAY_CORNER_RADIUS,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT
|
||||
);
|
||||
ctx.quadraticCurveTo(
|
||||
overlayX,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT,
|
||||
overlayX,
|
||||
overlayY + NOTE_OVERLAY_HEIGHT - NOTE_OVERLAY_CORNER_RADIUS
|
||||
);
|
||||
ctx.lineTo(overlayX, overlayY + NOTE_OVERLAY_CORNER_RADIUS);
|
||||
ctx.quadraticCurveTo(
|
||||
overlayX,
|
||||
overlayY,
|
||||
overlayX + NOTE_OVERLAY_CORNER_RADIUS,
|
||||
overlayY
|
||||
);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
ctx.fill();
|
||||
|
||||
// Draw the overlay text
|
||||
ctx.fillStyle = this.gfx.std
|
||||
.get(ThemeProvider)
|
||||
.getCssVariableColor(NOTE_OVERLAY_TEXT_COLOR);
|
||||
let fontSize = 16;
|
||||
ctx.font = `${fontSize}px Arial`;
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
|
||||
// measure the width of the text
|
||||
// if the text is wider than the rectangle, reduce the maximum width of the text
|
||||
while (ctx.measureText(this.text).width > NOTE_OVERLAY_WIDTH - 20) {
|
||||
fontSize -= 1;
|
||||
ctx.font = `${fontSize}px Arial`;
|
||||
}
|
||||
|
||||
ctx.fillText(this.text, overlayX + 10, overlayY + NOTE_OVERLAY_HEIGHT / 2);
|
||||
}
|
||||
}
|
||||
|
||||
export class DraggingNoteOverlay extends NoteOverlay {
|
||||
height: number;
|
||||
|
||||
slots: {
|
||||
draggingNoteUpdated: Subject<{ xywh: XYWH }>;
|
||||
};
|
||||
|
||||
width: number;
|
||||
|
||||
constructor(gfx: GfxController, background: Color) {
|
||||
super(gfx, background);
|
||||
this.slots = {
|
||||
draggingNoteUpdated: new Subject<{
|
||||
xywh: XYWH;
|
||||
}>(),
|
||||
};
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.disposables.add(
|
||||
this.slots.draggingNoteUpdated.subscribe(({ xywh }) => {
|
||||
[this.x, this.y, this.width, this.height] = xywh;
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override render(ctx: CanvasRenderingContext2D): void {
|
||||
// draw a rounded rectangle with provided background color and xywh
|
||||
ctx.globalAlpha = 0.8;
|
||||
ctx.fillStyle = this.backgroundColor;
|
||||
ctx.strokeStyle = 'rgba(0, 0, 0, 0.10)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.roundRect(this.x, this.y, this.width, this.height, 4);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { effects as gfxNoteEffects } from '@blocksuite/affine-gfx-note/effects';
|
||||
import { effects as gfxShapeEffects } from '@blocksuite/affine-gfx-shape/effects';
|
||||
import { effects as gfxCanvasTextEffects } from '@blocksuite/affine-gfx-text/effects';
|
||||
import { effects as widgetEdgelessToolbarEffects } from '@blocksuite/affine-widget-edgeless-toolbar/effects';
|
||||
@@ -41,9 +42,6 @@ import { EdgelessLinkToolButton } from './edgeless/components/toolbar/link/link-
|
||||
import { MindMapPlaceholder } from './edgeless/components/toolbar/mindmap/mindmap-importing-placeholder.js';
|
||||
import { EdgelessMindmapMenu } from './edgeless/components/toolbar/mindmap/mindmap-menu.js';
|
||||
import { EdgelessMindmapToolButton } from './edgeless/components/toolbar/mindmap/mindmap-tool-button.js';
|
||||
import { EdgelessNoteMenu } from './edgeless/components/toolbar/note/note-menu.js';
|
||||
import { EdgelessNoteSeniorButton } from './edgeless/components/toolbar/note/note-senior-button.js';
|
||||
import { EdgelessNoteToolButton } from './edgeless/components/toolbar/note/note-tool-button.js';
|
||||
import { EdgelessFrameOrderButton } from './edgeless/components/toolbar/present/frame-order-button.js';
|
||||
import { EdgelessFrameOrderMenu } from './edgeless/components/toolbar/present/frame-order-menu.js';
|
||||
import { EdgelessNavigatorSettingButton } from './edgeless/components/toolbar/present/navigator-setting-button.js';
|
||||
@@ -120,6 +118,7 @@ function registerRootComponents() {
|
||||
function registerGfxEffects() {
|
||||
gfxCanvasTextEffects();
|
||||
gfxShapeEffects();
|
||||
gfxNoteEffects();
|
||||
}
|
||||
|
||||
function registerWidgets() {
|
||||
@@ -161,14 +160,12 @@ function registerEdgelessToolbarComponents() {
|
||||
'edgeless-mindmap-tool-button',
|
||||
EdgelessMindmapToolButton
|
||||
);
|
||||
customElements.define('edgeless-note-tool-button', EdgelessNoteToolButton);
|
||||
customElements.define('edgeless-template-button', EdgelessTemplateButton);
|
||||
|
||||
// Menus
|
||||
customElements.define('edgeless-brush-menu', EdgelessBrushMenu);
|
||||
customElements.define('edgeless-connector-menu', EdgelessConnectorMenu);
|
||||
customElements.define('edgeless-mindmap-menu', EdgelessMindmapMenu);
|
||||
customElements.define('edgeless-note-menu', EdgelessNoteMenu);
|
||||
customElements.define('edgeless-slide-menu', EdgelessSlideMenu);
|
||||
|
||||
// Toolbar components
|
||||
@@ -185,10 +182,6 @@ function registerEdgelessToolbarComponents() {
|
||||
EdgelessNavigatorSettingButton
|
||||
);
|
||||
customElements.define('edgeless-present-button', EdgelessPresentButton);
|
||||
customElements.define(
|
||||
'edgeless-note-senior-button',
|
||||
EdgelessNoteSeniorButton
|
||||
);
|
||||
}
|
||||
|
||||
function registerEdgelessPanelComponents() {
|
||||
@@ -302,8 +295,6 @@ declare global {
|
||||
'mindmap-import-placeholder': MindMapPlaceholder;
|
||||
'edgeless-mindmap-menu': EdgelessMindmapMenu;
|
||||
'edgeless-mindmap-tool-button': EdgelessMindmapToolButton;
|
||||
'edgeless-note-menu': EdgelessNoteMenu;
|
||||
'edgeless-note-tool-button': EdgelessNoteToolButton;
|
||||
'edgeless-frame-order-menu': EdgelessFrameOrderMenu;
|
||||
'edgeless-navigator-setting-button': EdgelessNavigatorSettingButton;
|
||||
'edgeless-present-button': EdgelessPresentButton;
|
||||
|
||||
Reference in New Issue
Block a user