Skip to content

Commit

Permalink
feat: add basic button render
Browse files Browse the repository at this point in the history
  • Loading branch information
doouding committed Dec 18, 2024
1 parent 91118b8 commit 6be9e2d
Show file tree
Hide file tree
Showing 47 changed files with 1,141 additions and 308 deletions.
5 changes: 2 additions & 3 deletions packages/affine/block-surface/src/commands/auto-align.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import {
ConnectorElementModel,
EdgelessTextBlockModel,
EmbedSyncedDocModel,
MindmapElementModel,
NoteBlockModel,
} from '@blocksuite/affine-model';
import { Bound } from '@blocksuite/global/utils';
import chunk from 'lodash.chunk';

import { LayoutableMindmapElementModel } from '../utils/mindmap/utils.js';

const ALIGN_HEIGHT = 200;
const ALIGN_PADDING = 20;

Expand Down Expand Up @@ -121,7 +120,7 @@ function autoResizeElements(
elements.forEach(ele => {
if (
ele instanceof ConnectorElementModel ||
ele instanceof LayoutableMindmapElementModel
ele instanceof MindmapElementModel
) {
return;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/affine/block-surface/src/element-model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import {
BrushElementModel,
ConnectorElementModel,
GroupElementModel,
MindmapElementModel,
ShapeElementModel,
TextElementModel,
} from '@blocksuite/affine-model';

import { LayoutableMindmapElementModel } from '../utils/mindmap/utils.js';
import { SurfaceElementModel } from './base.js';

export const elementsCtorMap = {
Expand All @@ -15,14 +15,14 @@ export const elementsCtorMap = {
shape: ShapeElementModel,
brush: BrushElementModel,
text: TextElementModel,
mindmap: LayoutableMindmapElementModel,
mindmap: MindmapElementModel,
};

export {
BrushElementModel,
ConnectorElementModel,
GroupElementModel,
LayoutableMindmapElementModel,
MindmapElementModel,
ShapeElementModel,
SurfaceElementModel,
TextElementModel,
Expand All @@ -43,7 +43,7 @@ export type ElementModelMap = {
['connector']: ConnectorElementModel;
['text']: TextElementModel;
['group']: GroupElementModel;
['mindmap']: LayoutableMindmapElementModel;
['mindmap']: MindmapElementModel;
};

export function isCanvasElementType(type: string): type is CanvasElementType {
Expand Down
1 change: 0 additions & 1 deletion packages/affine/block-surface/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export {
NODE_HORIZONTAL_SPACING,
NODE_VERTICAL_SPACING,
} from './utils/mindmap/layout.js';
export { LayoutableMindmapElementModel } from './utils/mindmap/utils.js';
export { RoughCanvas } from './utils/rough/canvas.js';

import {
Expand Down
37 changes: 31 additions & 6 deletions packages/affine/block-surface/src/renderer/canvas-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
GridManager,
LayerManager,
SurfaceBlockModel,
Viewport,
} from '@blocksuite/block-std/gfx';
import type { IBound } from '@blocksuite/global/utils';
Expand Down Expand Up @@ -37,6 +38,7 @@ type RendererOptions = {
onStackingCanvasCreated?: (canvas: HTMLCanvasElement) => void;
elementRenderers: Record<string, ElementRenderer>;
gridManager: GridManager;
surfaceModel: SurfaceBlockModel;
};

export class CanvasRenderer {
Expand Down Expand Up @@ -90,6 +92,8 @@ export class CanvasRenderer {
if (options.enableStackingCanvas) {
this._initStackingCanvas(options.onStackingCanvasCreated);
}

this._watchSurface(options.surfaceModel);
}

/**
Expand Down Expand Up @@ -274,10 +278,9 @@ export class CanvasRenderer {
(this.grid.search(bound, {
filter: ['canvas', 'local'],
}) as SurfaceElementModel[]);
for (const element of elements) {
ctx.save();

const display = element.display ?? true;
for (const element of elements) {
const display = (element.display ?? true) && !element.hidden;
if (display && intersects(getBoundWithRotation(element), bound)) {
const renderFn =
this.elementRenderers[
Expand All @@ -286,18 +289,18 @@ export class CanvasRenderer {

if (!renderFn) {
console.warn(`Cannot find renderer for ${element.type}`);
ctx.restore();
continue;
}

ctx.save();

ctx.globalAlpha = element.opacity ?? 1;
const dx = element.x - bound.x;
const dy = element.y - bound.y;

renderFn(element, ctx, matrix.translate(dx, dy), this, rc, bound);
ctx.restore();
}

ctx.restore();
}

if (overLay) {
Expand All @@ -321,6 +324,28 @@ export class CanvasRenderer {
this.refresh();
}

private _watchSurface(surfaceModel: SurfaceBlockModel) {
const slots = [
'elementAdded',
'elementRemoved',
'localElementAdded',
'localElementDeleted',
'localElementUpdated',
] as const;

slots.forEach(slotName => {
this._disposables.add(surfaceModel[slotName].on(() => this.refresh()));
});

this._disposables.add(
surfaceModel.elementUpdated.on(payload => {
// ignore externalXYWH update cause it's updated by the renderer
if (payload.props['externalXYWH']) return;
this.refresh();
})
);
}

addOverlay(overlay: Overlay) {
overlay.setRenderer(this);
this._overlays.add(overlay);
Expand Down
35 changes: 21 additions & 14 deletions packages/affine/block-surface/src/renderer/elements/mindmap.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { MindmapElementModel } from '@blocksuite/affine-model';
import type {
MindmapElementModel,
MindmapNode,
} from '@blocksuite/affine-model';
import type { GfxModel } from '@blocksuite/block-std/gfx';
import type { IBound } from '@blocksuite/global/utils';

Expand All @@ -21,15 +24,18 @@ export function mindmap(

matrix = matrix.translate(-dx, -dy);

model.traverse((to, from) => {
if (from) {
const connector = model.getConnector(from, to);
if (!connector) return;

const traverse = (node: MindmapNode) => {
const connectors = model.getConnectors(node);
if (!connectors) return;
connectors.reverse().forEach(result => {
const { connector, outdated } = result;
const elementGetter = (id: string) =>
model.surface.getElementById(id) ??
(model.surface.doc.getBlockById(id) as GfxModel);
ConnectorPathGenerator.updatePath(connector, null, elementGetter);

if (outdated) {
ConnectorPathGenerator.updatePath(connector, null, elementGetter);
}

const dx = connector.x - bound.x;
const dy = connector.y - bound.y;
Expand All @@ -45,13 +51,14 @@ export function mindmap(
if (shouldSetGlobalAlpha) {
ctx.globalAlpha = origin;
}
}
});
});

model.extraConnectors.forEach(connector => {
const dx = connector.x - bound.x;
const dy = connector.y - bound.y;
if (node.detail.collapsed) {
return;
} else {
node.children.forEach(traverse);
}
};

renderConnector(connector, ctx, matrix.translate(dx, dy), renderer, rc);
});
model.tree && traverse(model.tree);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { ShapeElementModel } from '@blocksuite/affine-model';
import type {
LocalShapeElementModel,
ShapeElementModel,
} from '@blocksuite/affine-model';

import type { RoughCanvas } from '../../../utils/rough/canvas.js';
import type { CanvasRenderer } from '../../canvas-renderer.js';

import { type Colors, drawGeneralShape } from './utils.js';

export function diamond(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { ShapeElementModel } from '@blocksuite/affine-model';
import type {
LocalShapeElementModel,
ShapeElementModel,
} from '@blocksuite/affine-model';

import type { RoughCanvas } from '../../../utils/rough/canvas.js';
import type { CanvasRenderer } from '../../canvas-renderer.js';

import { type Colors, drawGeneralShape } from './utils.js';

export function ellipse(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand Down
19 changes: 12 additions & 7 deletions packages/affine/block-surface/src/renderer/elements/shape/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { ShapeElementModel, ShapeType } from '@blocksuite/affine-model';
import type {
LocalShapeElementModel,
ShapeElementModel,
ShapeType,
} from '@blocksuite/affine-model';
import type { IBound } from '@blocksuite/global/utils';

import {
Expand Down Expand Up @@ -30,7 +34,7 @@ import { type Colors, horizontalOffset, verticalOffset } from './utils.js';
const shapeRenderers: Record<
ShapeType,
(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand All @@ -45,7 +49,7 @@ const shapeRenderers: Record<
};

export function shape(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand Down Expand Up @@ -76,7 +80,7 @@ export function shape(
}

function renderText(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
{ color }: Colors
) {
Expand All @@ -103,9 +107,10 @@ function renderText(
fontWeight
);
const metrics = getFontMetrics(fontFamily, fontSize, fontWeight);
const lines = deltaInsertsToChunks(
wrapTextDeltas(text, font, w - horPadding * 2)
);
const lines =
typeof text === 'string'
? [text.split('\n').map(line => ({ insert: line }))]
: deltaInsertsToChunks(wrapTextDeltas(text, font, w - horPadding * 2));
const horOffset = horizontalOffset(model.w, model.textAlign, horPadding);
const vertOffset =
verticalOffset(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { ShapeElementModel } from '@blocksuite/affine-model';
import type {
LocalShapeElementModel,
ShapeElementModel,
} from '@blocksuite/affine-model';

import type { RoughCanvas } from '../../../utils/rough/canvas.js';
import type { CanvasRenderer } from '../../canvas-renderer.js';
Expand All @@ -11,7 +14,7 @@ import { type Colors, drawGeneralShape } from './utils.js';
const K_RECT = 1 - 0.5522847498;

export function rect(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { ShapeElementModel } from '@blocksuite/affine-model';
import type {
LocalShapeElementModel,
ShapeElementModel,
} from '@blocksuite/affine-model';

import type { RoughCanvas } from '../../../utils/rough/canvas.js';
import type { CanvasRenderer } from '../../canvas-renderer.js';

import { type Colors, drawGeneralShape } from './utils.js';

export function triangle(
model: ShapeElementModel,
model: ShapeElementModel | LocalShapeElementModel,
ctx: CanvasRenderingContext2D,
matrix: DOMMatrix,
renderer: CanvasRenderer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
LocalShapeElementModel,
ShapeElementModel,
TextAlign,
TextVerticalAlign,
Expand Down Expand Up @@ -28,7 +29,7 @@ export type Colors = {

export function drawGeneralShape(
ctx: CanvasRenderingContext2D,
shapeModel: ShapeElementModel,
shapeModel: ShapeElementModel | LocalShapeElementModel,
renderer: CanvasRenderer,
filled: boolean,
fillColor: string,
Expand Down
18 changes: 1 addition & 17 deletions packages/affine/block-surface/src/surface-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,25 +187,9 @@ export class SurfaceBlockComponent extends BlockComponent<
canvas.className = 'indexable-canvas';
},
elementRenderers: this._edgelessService.elementRenderers,
surfaceModel: this.model,
});

this._disposables.add(
this.model.elementUpdated.on(payload => {
// ignore externalXYWH update cause it's updated by the renderer
if (payload.props['externalXYWH']) return;
this._renderer.refresh();
})
);
this._disposables.add(
this.model.elementAdded.on(() => {
this._renderer.refresh();
})
);
this._disposables.add(
this.model.elementRemoved.on(() => {
this._renderer.refresh();
})
);
this._disposables.add(() => {
this._renderer.dispose();
});
Expand Down
2 changes: 2 additions & 0 deletions packages/affine/block-surface/src/surface-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ import {
} from './adapters/extension.js';
import { commands } from './commands/index.js';
import { SurfaceBlockService } from './surface-service.js';
import { MindMapView } from './view/mindmap.js';

const CommonSurfaceBlockSpec: ExtensionType[] = [
FlavourExtension('affine:surface'),
SurfaceBlockService,
CommandExtension(commands),
HighlightSelectionExtension,
MindMapView,
];

export const PageSurfaceBlockSpec: ExtensionType[] = [
Expand Down
Loading

0 comments on commit 6be9e2d

Please sign in to comment.