fix: fix resource update process for image, svg and html Element

This commit is contained in:
chenshenhai 2025-05-11 20:51:05 +08:00
parent 5c6ea6dd6c
commit f225d9aa58
6 changed files with 67 additions and 19 deletions

View file

@ -1,6 +1,6 @@
{
"private": false,
"version": "0.4.0-beta.42",
"version": "0.4.0-beta.43",
"workspaces": [
"packages/*"
],

View file

@ -114,11 +114,17 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
this.#board.resetMiddlewareConfig(middleware, config);
}
setData(data: Data) {
#resetData(data: Data) {
validateElements(data?.elements || []);
this.#board.setData(data);
}
setData(data: Data) {
const loader = this.#board.getRenderer().getLoader();
loader.reset();
this.#resetData(data);
}
getData(): Data | null {
return this.#board.getData();
}
@ -220,9 +226,10 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
const before = toFlattenElement(beforeElem);
const updatedElement = updateElementInListByPosition(position, element, data.elements, { strict: true }) as Element;
const after = toFlattenElement(updatedElement);
this.setData(data);
const loader = this.#board.getRenderer().getLoader();
loader.resetElementAsset(element);
this.#resetData(data);
this.refresh();
const modifyRecord: ModifyRecord<'updateElement'> = {
type: 'updateElement',
time: Date.now(),
@ -246,7 +253,9 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
beforeElement: beforeElem
});
updateElementInListByPosition(position, restElement, data.elements) as Element;
this.setData(data);
const loader = this.#board.getRenderer().getLoader();
loader.resetElementAsset({ ...element, type: beforeElem.type });
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -292,7 +301,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
}
};
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -317,7 +326,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
time: Date.now(),
content: { method: 'addElement', uuid: element.uuid, position, element: deepClone(element) }
};
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -331,8 +340,12 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
time: Date.now(),
content: { method: 'deleteElement', uuid, position, element: element ? deepClone(element) : null }
};
if (element) {
const loader = this.#board.getRenderer().getLoader();
loader.resetElementAsset(element);
}
deleteElementInList(uuid, data.elements);
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -348,7 +361,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
};
const { elements: list } = moveElementPosition(data.elements, { from, to });
data.elements = list;
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -369,7 +382,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
if (data.layout) {
modifyRecord.content.before = toFlattenLayout(data.layout);
delete data['layout'];
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
} else {
@ -399,7 +412,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
modifyRecord.content.after = after;
mergeLayout(data.layout as DataLayout, layout) as DataLayout;
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}
@ -420,7 +433,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
if (data.global) {
modifyRecord.content.before = toFlattenGlobal(data.global);
delete data['global'];
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
} else {
@ -445,7 +458,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
modifyRecord.content.after = after;
mergeGlobal(data.global as DataGlobal, global) as DataGlobal;
this.setData(data);
this.#resetData(data);
this.refresh();
return modifyRecord;
}

View file

@ -50,7 +50,7 @@ export function modifyElement(
if (!data) {
return;
}
core.trigger(coreEventKeys.CHANGE, { data, type: 'updateElement', modifyRecord });
core.trigger(coreEventKeys.CHANGE, { data, type: 'modifyElement', modifyRecord });
}
export function addElement(

View file

@ -4,8 +4,8 @@ import { getOpacity } from './box';
export function drawHTML(ctx: ViewContext2D, elem: Element<'html'>, opts: RendererDrawElementOptions) {
const content = opts.loader.getContent(elem);
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
const { viewScaleInfo, parentOpacity } = opts;
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
rotateElement(ctx, { x, y, w, h, angle }, () => {
if (!content && !opts.loader.isDestroyed()) {
opts.loader.load(elem as Element<'html'>, opts.elementAssets || {});

View file

@ -4,8 +4,8 @@ import { getOpacity } from './box';
export function drawSVG(ctx: ViewContext2D, elem: Element<'svg'>, opts: RendererDrawElementOptions) {
const content = opts.loader.getContent(elem);
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
const { viewScaleInfo, parentOpacity } = opts;
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
rotateElement(ctx, { x, y, w, h, angle }, () => {
if (!content && !opts.loader.isDestroyed()) {
opts.loader.load(elem as Element<'svg'>, opts.elementAssets || {});

View file

@ -7,7 +7,8 @@ import type {
LoadItemMap,
LoadElementType,
Element,
ElementAssets
ElementAssets,
RecursivePartial
} from '@idraw/types';
import { loadImage, loadHTML, loadSVG, EventEmitter, createAssetId, isAssetId, createUUID } from '@idraw/util';
@ -75,6 +76,40 @@ export class Loader extends EventEmitter<LoaderEventMap> implements RendererLoad
return this.#hasDestroyed;
}
reset() {
if (this.#hasDestroyed === true) {
return;
}
this.#currentLoadItemMap = {};
this.#storageLoadItemMap = {};
}
resetElementAsset(element: Element<LoadElementType> | RecursivePartial<Element>) {
if (supportElementTypes.includes((element as Element<LoadElementType>).type)) {
let assetId: string | null = null;
let resource: string | null = null;
if (element.type === 'image' && typeof (element as Element<'image'>).detail.src === 'string') {
resource = (element as Element<'image'>).detail.src;
} else if (element.type === 'svg' && typeof (element as Element<'svg'>).detail.svg === 'string') {
resource = (element as Element<'svg'>).detail.svg;
} else if (element.type === 'html' && typeof (element as Element<'html'>).detail.html === 'string') {
resource = (element as Element<'html'>).detail.html;
}
if (typeof resource === 'string') {
this.load(element as Element<LoadElementType>, {});
if (isAssetId(resource)) {
assetId = resource;
} else if (element.uuid) {
assetId = createAssetId(resource, element.uuid);
}
}
if (assetId && isAssetId(assetId)) {
delete this.#storageLoadItemMap[assetId];
delete this.#currentLoadItemMap[assetId];
}
}
}
destroy() {
this.#hasDestroyed = true;
this.clear();