Skip to content

Commit ed5a169

Browse files
committed
feat(av-cliper): add interactable prop for VisibleSprite
1 parent 8bbbec9 commit ed5a169

File tree

4 files changed

+44
-16
lines changed

4 files changed

+44
-16
lines changed

packages/av-canvas/src/sprites/render-ctrl.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export function renderCtrls(
4343
lastActSprEvtClear = s.on('propsChange', () => {
4444
syncCtrlElPos(s, cvsEl, rectEl, ctrlsEl);
4545
});
46-
rectEl.style.display = '';
4746
});
4847

4948
return () => {
@@ -113,7 +112,7 @@ function syncCtrlElPos(
113112
Object.entries(getRectCtrls(cvsEl, s.rect)).forEach(([k, { x, y, w, h }]) => {
114113
// ctrl 是相对中心点定位的
115114
Object.assign(ctrlsEl[k as TCtrlKey].style, {
116-
display: 'block',
115+
display: s.interactable === 'interactive' ? 'block' : 'none',
117116
left: '50%',
118117
top: '50%',
119118
width: `${w * cvsRatio.w}px`,
@@ -122,4 +121,9 @@ function syncCtrlElPos(
122121
transform: `translate(${x * cvsRatio.w}px, ${y * cvsRatio.h}px)`,
123122
});
124123
});
124+
if (s.interactable === 'disabled') {
125+
rectEl.style.display = 'none';
126+
} else {
127+
rectEl.style.display = '';
128+
}
125129
}

packages/av-canvas/src/sprites/sprite-manager.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class SpriteManager {
2323
}
2424
set activeSprite(s: VisibleSprite | null) {
2525
if (s === this.#activeSprite) return;
26-
if (s && !s.actable) return;
26+
if (s && s.interactable === 'disabled') return;
2727
this.#activeSprite = s;
2828
this.#evtTool.emit(ESpriteManagerEvt.ActiveSpriteChange, s);
2929
}
@@ -33,7 +33,10 @@ export class SpriteManager {
3333
this.getSprites()
3434
// 排在后面的层级更高
3535
.reverse()
36-
.find((s) => s.visible && s.actable && s.rect.checkHit(x, y)) ?? null;
36+
.find(
37+
(s) =>
38+
s.visible && s.interactable !== 'disabled' && s.rect.checkHit(x, y),
39+
) ?? null;
3740
}
3841

3942
async addSprite(vs: VisibleSprite): Promise<void> {

packages/av-canvas/src/sprites/sprite-op.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,14 @@ export function draggabelSprite(
5151

5252
// 移动sprite的处理函数
5353
const onRectMouseDown = (evt: MouseEvent): void => {
54-
if (evt.button !== 0 || sprMng.activeSprite == null) return;
55-
5654
const hitSpr = sprMng.activeSprite;
55+
if (
56+
evt.button !== 0 ||
57+
hitSpr == null ||
58+
hitSpr.interactable !== 'interactive'
59+
)
60+
return;
61+
5762
const { clientX, clientY } = evt;
5863

5964
startRect = hitSpr.rect.clone();
@@ -69,16 +74,22 @@ export function draggabelSprite(
6974

7075
const cvsRatio = getCvsRatio(cvsEl);
7176
const onMouseMove = (evt: MouseEvent): void => {
72-
if (sprMng.activeSprite == null || startRect == null) return;
77+
const hitSpr = sprMng.activeSprite;
78+
if (
79+
hitSpr == null ||
80+
hitSpr.interactable !== 'interactive' ||
81+
startRect == null
82+
)
83+
return;
7384

7485
const { clientX, clientY } = evt;
7586
let expectX = startRect.x + (clientX - startX) / cvsRatio.w;
7687
let expectY = startRect.y + (clientY - startY) / cvsRatio.h;
7788

7889
updateRectWithSafeMargin(
79-
sprMng.activeSprite.rect,
90+
hitSpr.rect,
8091
cvsEl,
81-
refline.magneticEffect(expectX, expectY, sprMng.activeSprite.rect),
92+
refline.magneticEffect(expectX, expectY, hitSpr.rect),
8293
);
8394
};
8495

@@ -116,18 +127,24 @@ function setupCtrlEvents(
116127
ctrlElements.forEach((ctrlEl, index) => {
117128
const ctrlKey = CTRL_KEYS[index];
118129
ctrlEl.addEventListener('pointerdown', (evt: MouseEvent) => {
119-
if (evt.button !== 0 || sprMng.activeSprite == null) return;
130+
const hitSpr = sprMng.activeSprite;
131+
if (
132+
evt.button !== 0 ||
133+
hitSpr == null ||
134+
hitSpr.interactable !== 'interactive'
135+
)
136+
return;
120137

121138
const { clientX, clientY } = evt;
122139

123140
if (ctrlKey === 'rotate') {
124141
rotateRect(
125-
sprMng.activeSprite.rect,
126-
cntMap2Outer(sprMng.activeSprite.rect.center, cvsRatio, cvsEl),
142+
hitSpr.rect,
143+
cntMap2Outer(hitSpr.rect.center, cvsRatio, cvsEl),
127144
);
128145
} else {
129146
scaleRect({
130-
sprRect: sprMng.activeSprite.rect,
147+
sprRect: hitSpr.rect,
131148
ctrlKey,
132149
startX: clientX,
133150
startY: clientY,

packages/av-cliper/src/sprite/visible-sprite.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ export class VisibleSprite extends BaseSprite {
3131
visible = true;
3232

3333
/**
34-
* 元素是否可选中,用于设置元素是否响应画布的选中事件,设置为 false 时不可选中,默认为 true 可选中
34+
* 控制 Sprite 的交互状态
35+
* - 'interactive': 可选中,可进行移动、缩放、旋转等所有交互
36+
* - 'selectable': 仅可选中,但不可进行移动、缩放、旋转等交互
37+
* - 'disabled': 不可选中,也不可交互
38+
* @default 'interactive'
3539
*/
36-
actable = true;
40+
interactable: 'interactive' | 'selectable' | 'disabled' = 'interactive';
3741

3842
constructor(clip: IClip) {
3943
super();
@@ -113,7 +117,7 @@ export class VisibleSprite extends BaseSprite {
113117
super.copyStateTo(target);
114118
if (target instanceof VisibleSprite) {
115119
target.visible = this.visible;
116-
target.actable = this.actable;
120+
target.interactable = this.interactable;
117121
}
118122
}
119123

0 commit comments

Comments
 (0)