Skip to content

Commit

Permalink
Merge pull request #53 from VisActor/feat/component-controller
Browse files Browse the repository at this point in the history
feat: support image shape edit controller
  • Loading branch information
neuqzxy authored Aug 21, 2024
2 parents 105c6b9 + f1940bb commit 372ffa7
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 49 deletions.
94 changes: 66 additions & 28 deletions packages/vstory/demo/src/demos/StoryEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@ import { Story } from '../../../src/story/story';
import { Edit } from '../../../src/edit/edit';
import '../../../src/story/index';
import { cloneDeep } from '@visactor/vutils';
import { CommonEditComponent } from '../../../src/edit/edit-component/common';
import { ChartSelection } from '../../../src/edit/edit-component/chart-selection';
import { BoxSelection } from '../../../src/edit/edit-component/box-selection';
import { TextSelection } from '../../../src/edit/edit-component/text-selection';
import { RichTextSelection } from '../../../src/edit/edit-component/richtext-selection';
import Scene3ChartImage2 from '../assets/scene3/chart-2.png';
import { loadAllSelection } from '../../../src/edit/edit-component';

// Edit.registerEditComponent('common', CommonEditComponent);
Edit.registerEditComponent('chart', ChartSelection);
Edit.registerEditComponent('text', TextSelection);
Edit.registerEditComponent('richtext', RichTextSelection);
Edit.registerEditComponent('box-selection', BoxSelection);
loadAllSelection();

const chartSpec = {
type: 'bar',
Expand Down Expand Up @@ -43,7 +37,7 @@ export const StoryEdit = () => {
characters: [
{
type: 'Rect',
id: 'test-graphics-0',
id: 'rect0',
zIndex: 10,
position: {
top: 40,
Expand All @@ -65,7 +59,7 @@ export const StoryEdit = () => {
},
{
type: 'Rect',
id: 'test-graphics-1',
id: 'rect1',
zIndex: 0,
position: {
top: 40,
Expand All @@ -86,6 +80,66 @@ export const StoryEdit = () => {
shapePoints: []
}
},
{
type: 'Image',
id: 'image0',
zIndex: 0,
position: {
top: 140,
left: 250,
width: 200,
height: 100
},
options: {
graphic: {
image: Scene3ChartImage2
},
text: {
text: 'Image',
fill: 'black'
},
angle: 0,
shapePoints: []
}
},
// {
// type: 'Text',
// id: 'text0',
// zIndex: 0,
// position: {
// top: 140,
// left: 150,
// width: 200,
// height: 100
// },
// options: {
// graphic: {
// fill: 'pink',
// text: 'hahaha'
// },
// angle: 0,
// shapePoints: []
// }
// },
{
type: 'Shape',
id: 'shape0',
zIndex: 0,
position: {
top: 240,
left: 250,
width: 200,
height: 100
},
options: {
graphic: {
fill: 'green',
symbolType: 'star'
},
angle: 0,
shapePoints: []
}
},
{
type: 'VChart',
id: 'test-chart-0',
Expand All @@ -109,23 +163,7 @@ export const StoryEdit = () => {
id: 'scene0',
actions: [
{
characterId: 'test-graphics-0',
characterActions: [
{
startTime: 0,
action: 'appear',
payload: {
animation: {
duration: 100,
easing: 'linear',
effect: 'fadeIn'
} as any
}
}
]
},
{
characterId: 'test-graphics-1',
characterId: ['rect0', 'rect1', 'image0', 'shape0'],
characterActions: [
{
startTime: 0,
Expand Down
3 changes: 3 additions & 0 deletions packages/vstory/src/edit/edit-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ export class EditAction {
// 取消选中
type = EditActionEnum.unSelection;
}
// if (type === EditActionEnum.singleSelection) {
// debugger;
// }
this.dispatchAction({
type: type,
characterId: character?.id,
Expand Down
11 changes: 6 additions & 5 deletions packages/vstory/src/edit/edit-component/image-selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { type IEditComponent } from '../interface';
import { BaseSelection } from './base-selection';
import type { ITransformControl, TransformAttributes } from './edit-control/transform-control';
import { TransformControl } from './edit-control/transform-control';
import { RectSelection } from './rect-selection';

export class ImageSelection extends BaseSelection implements IEditComponent {
export class ImageSelection extends RectSelection implements IEditComponent {
readonly level = 3;
readonly type: string = 'image';
editCharacterType = StoryComponentType.IMAGE;
readonly editCharacterType: string = StoryComponentType.IMAGE;

protected _createLayoutComponent(attributes: Partial<TransformAttributes>): ITransformControl {
return new TransformControl(this, attributes);
}
// protected _createLayoutComponent(attributes: Partial<TransformAttributes>): ITransformControl {
// return new TransformControl(this, attributes);
// }
}
10 changes: 7 additions & 3 deletions packages/vstory/src/edit/edit-component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import { TextSelection } from './text-selection';
import { RichTextSelection } from './richtext-selection';
import { RectSelection } from './rect-selection';
import { Edit } from '../edit';
import { ChartSelection } from './chart-selection';
import { ShapeSelection } from './shape-selection';

export function loadAllSelection() {
// Edit.registerEditComponent('common', CommonEditComponent);
Edit.registerEditComponent('text', TextSelection);
Edit.registerEditComponent('richtext', RichTextSelection);
// Edit.registerEditComponent('text', TextSelection);
// Edit.registerEditComponent('richtext', RichTextSelection);
Edit.registerEditComponent('rect', RectSelection);
Edit.registerEditComponent('image', ImageSelection);
Edit.registerEditComponent('shape', ShapeSelection);
Edit.registerEditComponent('chart', ChartSelection);
Edit.registerEditComponent('box-selection', BoxSelection);
Edit.registerEditComponent('image-selection', ImageSelection);
}
8 changes: 4 additions & 4 deletions packages/vstory/src/edit/edit-component/rect-selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ import { RichTextSelectionCommon } from './richtext-selection-common';
export class RectSelection extends RichTextSelectionCommon implements IEditComponent {
readonly level = 3;
readonly type: string = 'rect';
readonly editCharacterType = StoryComponentType.RECT;
readonly editCharacterType: string = StoryComponentType.RECT;

startEdit(actionInfo: IEditActionInfo) {
super.startEdit(actionInfo);
// @ts-ignore;
const character = this._actionInfo.character;
character.graphic.graphic.addEventListener('pointerdown', this.handlerRectClick);
character.graphic.graphic.addEventListener('pointerdown', this.handlerContentClick);
}
editEnd() {
// @ts-ignore;
const character = this._actionInfo.character;
character.graphic.graphic.removeEventListener('pointerdown', this.handlerRectClick);
character.graphic.graphic.removeEventListener('pointerdown', this.handlerContentClick);
super.editEnd();
}

handlerRectClick = (e: any) => {
handlerContentClick = (e: any) => {
this._layoutComponent.handleDragMouseDown(e);
this.endRichTextEdit();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export interface RichTextSelectionCommon

export class RichTextSelectionCommon extends BaseSelection implements IEditComponent {
readonly level = 3;
readonly type: string = 'rect';
readonly editCharacterType = 'Rect';
readonly type: string;
readonly editCharacterType: string;

protected _getRichText() {
// @ts-ignore
Expand Down
50 changes: 50 additions & 0 deletions packages/vstory/src/edit/edit-component/shape-selection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// import { StoryGraphicType } from '../../dsl/constant';
import { StoryComponentType } from '../../constants/character';
import type { VRenderPointerEvent } from '../../interface/type';
import type { IEditSelectionInfo } from '../interface';
import { type IEditComponent } from '../interface';
import { BaseSelection } from './base-selection';
import type { ITransformControl, IUpdateParams, TransformAttributes } from './edit-control/transform-control';
import { TransformControl } from './edit-control/transform-control';
import { RectSelection } from './rect-selection';

export class ShapeSelection extends RectSelection implements IEditComponent {
readonly level = 3;
readonly type: string = 'shape';
readonly editCharacterType: string = StoryComponentType.SHAPE;

// protected _createLayoutComponent(attributes: Partial<TransformAttributes>): ITransformControl {
// return new TransformControl(this, attributes);
// }

updateComponent() {
const actionInfo = this._actionInfo as IEditSelectionInfo;
if (!(actionInfo && actionInfo.character)) {
return;
}
const symbol = actionInfo.character.graphic.graphic;
const { width, height } = symbol.attribute;
const group = actionInfo.character.getGraphicParent();
const { angle, x, y } = group.attribute;
this._layoutComponent.updateBoundsAndAngle(
{
x1: x,
y1: y,
x2: x + width,
y2: y + height
},
angle
);
}

protected handlerTransformChange(data: IUpdateParams, event?: VRenderPointerEvent): void {
if (this._activeCharacter) {
const { x, y, width, height } = data;
this._activeCharacter.setAttributes({
...data,
x: x + width / 2,
y: y + height / 2
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ export class ComponentGroup extends Group implements IVisactorGraphic {

constructor(attrs: IGroupGraphicAttribute) {
// vstory-component-group没有主题,必须都初始化,否则动画会找不到属性
super({ scaleX: 1, scaleY: 1, x: 0, y: 0, angle: 0, ...attrs });
super({ scaleX: 1, scaleY: 1, x: 0, y: 0, angle: 0, ...attrs, pickable: false });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ import type { Graphic } from '../graphic/graphic';
import { CharacterComponent } from '../character';
import { StoryComponentType } from '../../../../constants/character';
import { GraphicImage } from '../graphic/image';
import type { StoryEvent } from '../../../interface';
import type { ICharacterPickInfo } from '../../runtime-interface';

export class CharacterComponentImage extends CharacterComponent {
readonly graphicType: string = 'image';
protected _createGraphic(): Graphic {
return new GraphicImage(StoryComponentType.IMAGE, this as any);
}

checkEvent(event: StoryEvent): false | ICharacterPickInfo {
const info = super.checkEvent(event);
if (info && event.path[event.path.length - 1] === this._group) {
return false;
}
return info;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,36 @@ import type { Graphic } from '../graphic/graphic';
import { CharacterComponent } from '../character';
import { StoryComponentType } from '../../../../constants/character';
import { GraphicSymbol } from '../graphic/symbol';
import type { StoryEvent } from '../../../interface';
import type { ICharacterPickInfo } from '../../runtime-interface';

export class CharacterComponentShape extends CharacterComponent {
readonly graphicType: string = 'shape';
protected _createGraphic(): Graphic {
return new GraphicSymbol(StoryComponentType.SHAPE, this);
}

setAttributes(attr: Record<string, any>): void {
this.group.setAttributes({
...attr,
x: attr.x - attr.width / 2,
y: attr.y - attr.height / 2
});
this._graphic.setAttributes({
...attr,
x: attr.width / 2,
y: attr.height / 2,
angle: 0,
size: Math.min(attr.width, attr.height)
});
this._text.updateAttribute({});
}

checkEvent(event: StoryEvent): false | ICharacterPickInfo {
const info = super.checkEvent(event);
if (info && event.path[event.path.length - 1] === this._group) {
return false;
}
return info;
}
}
31 changes: 25 additions & 6 deletions packages/vstory/src/story/character/component/graphic/symbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { ISymbol } from '@visactor/vrender';
import { createSymbol } from '@visactor/vrender';
import type { IPointLike } from '@visactor/vutils';
import { Graphic } from './graphic';
import type { IWidgetData } from '../../dsl-interface';
import { getLayoutFromWidget } from '../../../utils/layout';

export class GraphicSymbol extends Graphic {
protected _graphic: ISymbol;
Expand All @@ -23,14 +25,31 @@ export class GraphicSymbol extends Graphic {

init() {
if (!this._graphic) {
this._graphic = createSymbol(
this._transformAttributes({
...this.getInitialAttributes(),
...(this._character.spec.options?.graphic ?? {})
})
);
const attributes = this._transformAttributes({
...this.getInitialAttributes(),
...(this._character.spec.options?.graphic ?? {})
});
this._graphic = createSymbol(attributes);
this._graphic.name = `graphic-symbol-${this._character.id}`;
this._character.getGraphicParent().add(this._graphic);
}
}

applyLayoutData(layoutData: Partial<IWidgetData>): void {
const attributes = this._transformAttributes({
...getLayoutFromWidget(layoutData),
shapePoints: this._character.spec.options.shapePoints
});
attributes.size = Math.min(attributes.width, attributes.height);

this._graphic.setAttributes(attributes);
}

protected _transformAttributes(attributes: any): any {
const data = super._transformAttributes(attributes);
const { width, height } = attributes;
data.x = width / 2;
data.y = height / 2;
return data;
}
}

0 comments on commit 372ffa7

Please sign in to comment.