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

如果元素设置为culling在切换页面时会出现不渲染的情况 #1095

Open
xiaotusi opened this issue Oct 1, 2024 · 1 comment

Comments

@xiaotusi
Copy link

xiaotusi commented Oct 1, 2024

问题描述

前置条件

  • 使用了Angular页面缓存
  • 使用了ResizeObserver监听zrender宿主dom尺寸,如果尺寸发生变化则调用zrenderIns.resize()
  • 元素设置了culling: true
  • 路由A: zrender绘制页面,路由B: 常规配置页面

复现步骤

2024-10-01.08.12.31.mov
  1. 第一次页面加载路由A,渲染没有问题
  2. 切换至路由B
  3. 切回路由A
  4. 绘制元素消失

问题分析

refresh执行中会判断元素如果设置为culling则会判断是否在可视区域中,不在则不会渲染。而之前切换页面时会导致zrender宿主dom的尺寸变为长宽为0, 所以无论如何判断元素都不会渲染
而调用resize函数后, 源码确实会计算当前视窗尺寸但是没有设置_width 和 _height 这两个私有属性

if (this._width !== width || height !== this._height) {
domRoot.style.width = width + 'px';
domRoot.style.height = height + 'px';
for (let id in this._layers) {
if (this._layers.hasOwnProperty(id)) {
this._layers[id].resize(width, height);
}
}
this.refresh(true);
}
this._width = width;
this._height = height;

这段代码会使用_width和_height
const repaint = (repaintRect?: BoundingRect) => {
const scope: BrushScope = {
inHover: false,
allClipped: false,
prevEl: null,
viewWidth: this._width,
viewHeight: this._height
};
for (i = start; i < layer.__endIndex; i++) {
const el = list[i];
if (el.__inHover) {
needsRefreshHover = true;
}
this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1);
if (useTimer) {
// Date.now can be executed in 13,025,305 ops/second.
const dTime = Date.now() - startTime;
// Give 15 millisecond to draw.
// The rest elements will be drawn in the next frame.
if (dTime > 15) {
break;
}
}
}

Line 215 永真
if (
this.ignore
// Ignore invisible element
|| this.invisible
// Ignore transparent element
|| this.style.opacity === 0
// Ignore culled element
|| (this.culling
&& isDisplayableCulled(this, viewWidth, viewHeight)
)
// Ignore scale 0 element, in some environment like node-canvas
// Draw a scale 0 element can cause all following draw wrong
// And setTransform with scale 0 will cause set back transform failed.
|| (m && !m[0] && !m[3])
) {
return false;

可能方案

前置

this._width = width;
this._height = height;

临时方案

再调用一遍refrsh(true)进行全部刷新 😭
(this.zrenderIns.painter.refresh as EtSafeAny)(true); Ts 语法还报错 可以的话这玩意也修复下

@Ovilia
Copy link
Member

Ovilia commented Oct 17, 2024

切换页面应该要 dispose 掉的,回到该页面重新初始化

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@Ovilia @xiaotusi and others