Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/richtext edit bugfix #1691

Merged
merged 11 commits into from
Jan 26, 2025
10 changes: 8 additions & 2 deletions packages/vrender-core/src/graphic/graphic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import type {
import { EventTarget, CustomEvent } from '../event';
import { DefaultTransform } from './config';
import { application } from '../application';
import { Animate, DefaultStateAnimateConfig } from '../animate';
import { Animate, DefaultStateAnimateConfig, defaultTimeline } from '../animate';
import { interpolateColor } from '../color-string/interpolate';
import { CustomPath2D } from '../common/custom-path2d';
import { ResourceLoader } from '../resource-loader/loader';
Expand Down Expand Up @@ -823,6 +823,7 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
}
this.animates.set(animate.id, animate);
animate.onRemove(() => {
animate.stop();
this.animates.delete(animate.id);
});

Expand Down Expand Up @@ -1214,9 +1215,12 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
this.layer = layer;
this.setStageToShadowRoot(stage, layer);
if (this.animates && this.animates.size) {
// 设置timeline为所属的stage上的timeline,但如果timeline并不是默认的timeline,就不用覆盖
const timeline = stage.getTimeline();
this.animates.forEach(a => {
a.setTimeline(timeline);
if (a.timeline === defaultTimeline) {
a.setTimeline(timeline);
}
});
}
this._onSetStage && this._onSetStage(this, stage, layer);
Expand Down Expand Up @@ -1437,6 +1441,7 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
detachShadow() {
if (this.shadowRoot) {
this.addUpdateBoundTag();
this.shadowRoot.release(true);
this.shadowRoot = null;
}
}
Expand Down Expand Up @@ -1565,6 +1570,7 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr

release(): void {
this.releaseStatus = 'released';
this.stopAnimates();
application.graphicService.onRelease(this);
}

Expand Down
13 changes: 13 additions & 0 deletions packages/vrender-core/src/graphic/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ export class Group extends Graphic<IGroupGraphicAttribute> implements IGroup {
const bounds = this.doUpdateAABBBounds();
this.addUpdateLayoutTag();
application.graphicService.afterUpdateAABBBounds(this, this.stage, this._AABBBounds, this, selfChange);
// 直接返回空Bounds,但是前面的流程还是要走
if (this.attribute.boundsMode === 'empty') {
bounds.clear();
}
return bounds;
}

Expand Down Expand Up @@ -410,6 +414,15 @@ export class Group extends Graphic<IGroupGraphicAttribute> implements IGroup {
getNoWorkAnimateAttr(): Record<string, number> {
return Group.NOWORK_ANIMATE_ATTR;
}

release(all?: boolean) {
if (all) {
this.forEachChildren((g: IGraphic) => {
g.release(all);
});
}
super.release();
}
}

export function createGroup(attributes: IGroupGraphicAttribute): IGroup {
Expand Down
11 changes: 11 additions & 0 deletions packages/vrender-core/src/graphic/richtext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,19 @@ export class RichText extends Graphic<IRichTextGraphicAttribute> implements IRic
);
}

static splitEmoji(text: string) {
// 👈🏻这种emoji用Array.from还处理不了,所以得兼容一下
return [...new (Intl as any).Segmenter().segment(text)].map(x => x.segment);
}

static splitText(text: string) {
// 😁这种emoji长度算两个,所以得处理一下
try {
const arr = this.splitEmoji(text);
return arr;
} catch (e) {
// do nothing
}
return Array.from(text);
}

Expand Down
36 changes: 35 additions & 1 deletion packages/vrender-core/src/graphic/richtext/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,46 @@ export default class Line {
}

// 绘制背景
// 属性相同的背景,合并绘制
let fillStyle = '';
let globalAlpha = -1;
let currBgList: {
fillStyle: string;
globalAlpha: number;
left: number;
top: number;
right: number;
bottom: number;
}[] = [];
const bgList = [currBgList];
this.paragraphs.forEach((paragraph, index) => {
if (paragraph instanceof RichTextIcon) {
return;
}
paragraph.drawBackground(ctx, y, this.ascent, x, index === 0, this.textAlign, this.height);
const data = paragraph.drawBackground(ctx, y, this.ascent, x, index === 0, this.textAlign, this.height);
if (!data) {
return;
}
if (!(fillStyle === data.fillStyle && globalAlpha === data.globalAlpha)) {
currBgList = [];
bgList.push(currBgList);
fillStyle = data.fillStyle;
globalAlpha = data.globalAlpha;
}
currBgList.push(data);
});
// 绘制背景
bgList.forEach(bg => {
if (bg.length === 0) {
return;
}
const data = bg[0];
const end = bg[bg.length - 1];
ctx.fillStyle = data.fillStyle;
ctx.globalAlpha = data.globalAlpha;
ctx.fillRect(data.left, data.top, end.right - data.left, end.bottom - data.top);
});

// 正常绘制
this.paragraphs.forEach((paragraph, index) => {
if (paragraph instanceof RichTextIcon) {
Expand Down
53 changes: 15 additions & 38 deletions packages/vrender-core/src/graphic/richtext/paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ function getFixedLRTB(left: number, right: number, top: number, bottom: number)
const topInt = Math.round(top);
const rightInt = Math.round(right);
const bottomInt = Math.round(bottom);
const _left = left > leftInt ? leftInt : leftInt - 0.5;
const _top = top > topInt ? topInt : topInt - 0.5;
const _right = rightInt > right ? rightInt : rightInt + 0.5;
const _bottom = bottomInt > bottom ? bottomInt : bottomInt + 0.5;
// 会导致背景色重叠
// const _left = left > leftInt ? leftInt : leftInt - 0.5;
// const _top = top > topInt ? topInt : topInt - 0.5;
// const _right = rightInt > right ? rightInt : rightInt + 0.5;
// const _bottom = bottomInt > bottom ? bottomInt : bottomInt + 0.5;
return {
left: _left,
top: _top,
right: _right,
bottom: _bottom
left: leftInt,
top: topInt,
right: rightInt,
bottom: bottomInt
};
}

Expand Down Expand Up @@ -210,40 +211,16 @@ export default class Paragraph {
}
}
}

// prepareContext(ctx);
switch (this.character.script) {
case 'super':
baseline -= this.ascent * (1 / 3);
break;
case 'sub':
baseline += this.descent / 2;
break;
}

// 处理旋转
if (direction === 'vertical') {
ctx.save();
ctx.rotateAbout(Math.PI / 2, left, baseline);
ctx.translate(-(this.heightOrigin as number) || -this.lineHeight / 2, -this.descent / 2);
ctx.translate(left, baseline);
left = 0;
baseline = 0;
}

const fillStyle = ctx.fillStyle;
const globalAlpha = ctx.globalAlpha;
ctx.fillStyle = this.character.background;
if (this.character.backgroundOpacity !== void 0) {
ctx.globalAlpha = this.character.backgroundOpacity;
}
// 背景稍微扩充一些buf,否则会出现白线
const right = left + (this.widthOrigin || this.width);
const bottom = top + lineHeight;
const lrtb = getFixedLRTB(left, right, top, bottom);
ctx.fillRect(lrtb.left, lrtb.top, lrtb.right - lrtb.left, lrtb.bottom - lrtb.top);
ctx.fillStyle = fillStyle;
ctx.globalAlpha = globalAlpha;

return {
...lrtb,
fillStyle: this.character.background,
globalAlpha: this.character.backgroundOpacity
};
}

draw(
Expand Down
1 change: 1 addition & 0 deletions packages/vrender-core/src/interface/graphic/richText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { ITextGraphicAttribute } from './text';

export type IRichTextEditOptionsType = {
placeholder?: string;
syncPlaceHolderToTextConfig?: boolean;
placeholderColor?: string;
placeholderFontSize?: number;
placeholderFontFamily?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export class EditModule {
const textList: string[] = text ? Array.from(text.toString()) : [];
for (let i = 0; i < textList.length; i++) {
textConfig.splice(i + configIdx, 0, {
...getDefaultCharacterConfig(this.currRt.attribute),
fill: 'black',
...lastConfig,
isComposing: false,
Expand Down
Loading
Loading