Skip to content

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

@xuaic

Description

@xuaic

问题描述

前置条件

  • 使用了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 语法还报错 可以的话这玩意也修复下

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions