Skip to content

fix: 视频单元格宽度异常#3340

Merged
Alexzjt merged 1 commit intonextfrom
fix/video-render-cell-width
Apr 28, 2026
Merged

fix: 视频单元格宽度异常#3340
Alexzjt merged 1 commit intonextfrom
fix/video-render-cell-width

Conversation

@xxxxZ-zhang
Copy link
Copy Markdown
Collaborator

👀 PR includes

✨ Feature

  • New feature

🎨 Enhance

  • Code style optimization
  • Refactoring
  • Change the UI
  • Improve the performance
  • Type optimization

🐛 Bugfix

  • Solve the issue and close

🔧 Chore

  • Test case
  • Docs / demos update
  • CI / workflow
  • Release version
  • Other ()

📝 Description

  1. 单元格渲染视频时未保持视频的宽高比
  2. 单元格渲染视频时宽度撑满了单元格,导致同单元格的icon无法渲染
  3. 视频单元格,点击空白区域仍然触发了视频播放

🖼️ Screenshot

Before After
image image

⚠️ Breaking Changes

  • Yes
  • No

🔗 Related issue link

🔍 Self-Check before the merge

  • Add or update relevant docs.
  • Add or update relevant demos.
  • Add or update test case.
  • Add or update relevant TypeScript definitions.

@github-actions github-actions Bot added the next 2.0-next 版本的问题 label Apr 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

你好 @xxxxZ-zhang,非常感谢你的贡献.
为了让代码更健壮, 请根据 贡献指南 补充相应单元测试 (文档改动或其他特殊场景除外), 如果有 API 改动, 请修改 相应的文档.
同时请检查 linttest 相关 CI 是否通过, 如果失败, 请点击 [Details] 按钮查看, 并根据日志修复.

Hello, @xxxxZ-zhang, Thanks for your contribution. In order to make the code more robust, please add the corresponding unit tests, and update the docs if there are API changes.
At the same time, please check whether the CI related to lint and test passes. If the CI fails, please click [Details] button to check and repair according to the log.

@github-actions github-actions Bot added the pr(fix) bug fix label Apr 28, 2026
@github-actions github-actions Bot requested a review from Alexzjt April 28, 2026 02:05
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.65%. Comparing base (ecdc9c8) to head (d4807e0).
⚠️ Report is 801 commits behind head on next.

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #3340      +/-   ##
==========================================
+ Coverage   75.77%   78.65%   +2.88%     
==========================================
  Files         257      224      -33     
  Lines       11994    12518     +524     
  Branches     2464     2843     +379     
==========================================
+ Hits         9088     9846     +758     
+ Misses       1398      961     -437     
- Partials     1508     1711     +203     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces video rendering support, featuring a new VideoRenderer that handles aspect ratio calculations and first-frame display, alongside updates to the PreviewClick interaction for video detection. It also includes a suite of tests for various sheet configurations. The review feedback highlights opportunities to improve test reliability by replacing sleep calls with event-based waiting, enhance type safety by avoiding any casts, and improve maintainability by replacing a magic number with a named constant.

Comment thread packages/s2-core/__tests__/spreadsheet/video-render-spec.ts Outdated
Comment thread packages/s2-core/__tests__/spreadsheet/video-render-spec.ts Outdated
Comment thread packages/s2-core/__tests__/spreadsheet/video-render-spec.ts Outdated
Comment thread packages/s2-core/src/interaction/base-interaction/click/preview-click.ts Outdated
Comment thread packages/s2-core/src/renderer/VideoRenderer.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

Size Change: +144 B (+0.02%)

Total Size: 744 kB

📦 View Changed
Filename Size Change
packages/s2-core/dist/s2-extends.min.js 209 kB +78 B (+0.04%)
packages/s2-core/dist/s2.min.js 311 kB +66 B (+0.02%)
ℹ️ View Unchanged
Filename Size
packages/s2-core/dist/s2.min.css 583 B
packages/s2-react-components/dist/s2-react-components.min.css 2.55 kB
packages/s2-react-components/dist/s2-react-components.min.js 123 kB
packages/s2-react/dist/s2-react.min.css 1.3 kB
packages/s2-react/dist/s2-react.min.js 38.5 kB
packages/s2-vue/dist/s2-vue.min.css 3.8 kB
packages/s2-vue/dist/s2-vue.min.js 54.2 kB

compressed-size-action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

你好, @xxxxZ-zhang CI 执行失败, 请点击 [Details] 按钮查看, 并根据日志修复。

Hello, @xxxxZ-zhang CI run failed, please click the [Details] button for detailed log information and fix it.

@github-actions github-actions Bot added the 🚨 test failed 单元测试挂了 label Apr 28, 2026
@xxxxZ-zhang xxxxZ-zhang force-pushed the fix/video-render-cell-width branch from 048edec to c7360fd Compare April 28, 2026 02:48
@github-actions github-actions Bot added 🚨 test failed 单元测试挂了 and removed 🚨 test failed 单元测试挂了 labels Apr 28, 2026
@xxxxZ-zhang xxxxZ-zhang force-pushed the fix/video-render-cell-width branch 2 times, most recently from 0d5edae to 051c0b3 Compare April 28, 2026 03:35
@github-actions github-actions Bot added 🚨 test failed 单元测试挂了 and removed 🚨 test failed 单元测试挂了 labels Apr 28, 2026
@xxxxZ-zhang xxxxZ-zhang force-pushed the fix/video-render-cell-width branch from 051c0b3 to d4807e0 Compare April 28, 2026 05:43
@github-actions github-actions Bot removed the 🚨 test failed 单元测试挂了 label Apr 28, 2026
@xxxxZ-zhang
Copy link
Copy Markdown
Collaborator Author

  1. 默认配置变更 (L11-21)

autoplay: true → autoplay: false
新增: preload: 'auto'

原来:视频创建后自动播放,单元格里的视频一直在动。

现在:不自动播放,只展示首帧静态画面。preload: 'auto' 告诉浏览器主动加载视频数据(否则 autoplay:
false 时某些浏览器不会预加载)。

  1. 首帧解码 (L55-58)

video.pause();
video.currentTime = VIDEO_PREVIEW_FRAME_TIME; // 0.001

onloadeddata 触发时视频数据已到位,但部分浏览器(尤其 Chromium)在 autoplay: false
时不会主动解码第一帧用于渲染。pause() 确保停止播放,currentTime = 0.001 强制浏览器 seek
到起始位置并解码该帧,这样 pattern fill 就能拿到画面。

  1. generateConfig 的计算逻辑 (L76-123)

这是核心变更,解决两个问题:宽高比拉伸 和 icon 溢出。

3.1 可用宽度计算 (L81-82)

const { y, height } = cell.getBBoxByType(CellClipBox.CONTENT_BOX);
const availableWidth = Math.max(cell.getMaxTextWidth(), 0);

原始代码直接用 contentBox.width 作为视频宽度。但 contentBox.width 是整个内容区宽度,没有扣除 icon
占用的空间。

getMaxTextWidth() 在 DataCell 中的实现是 contentBox.width - iconWidth,已经扣除了条件格式 icon
的宽度。这是文本系统用来限制文字宽度的同一个 API,视频复用它来获取真正可用的宽度。

3.2 等比缩放 (L87-106)

if (element instanceof HTMLVideoElement) {
const calculated = calculateImageSize(
availableWidth, height, // 容器:可用宽 × 内容区高
element.videoWidth, element.videoHeight // 原始:视频原始宽高
);
videoWidth = calculated.width;
videoHeight = calculated.height;

calculateImageSize 的逻辑:

widthRatio = availableWidth / videoWidth // 宽方向缩放比
heightRatio = height / videoHeight // 高方向缩放比
scale = min(widthRatio, heightRatio) // 取小值,保证不溢出
结果 = floor(原始尺寸 × scale) // 向下取整避免亚像素模糊

举例:可用宽 220px,内容高 180px,视频原始 1920×1080:

  • widthRatio = 220/1920 ≈ 0.1146
  • heightRatio = 180/1080 ≈ 0.1667
  • scale = 0.1146(宽受限)
  • 结果:220 × 124px,保持 16:9 比例

原始代码独立计算 scaleX = width/videoWidth、scaleY =
height/videoHeight,两个方向用不同缩放比,导致视频被拉伸。

3.3 pattern fill 的 transform (L98-105)

const scaleX = videoWidth / element.videoWidth;
const scaleY = videoHeight / element.videoHeight;
fill = {
image: element,
repetition: 'no-repeat',
transform: scale(${scaleX}, ${scaleY}),
};

@antv/g 的 pattern fill 用原始视频帧作为贴图源。Rect 尺寸是 videoWidth ×
videoHeight(已等比缩放后的),pattern 的 transform 把视频原始像素缩放到 Rect 尺寸。因为
calculateImageSize 保证了等比,这里 scaleX ≈ scaleY(仅 floor 取整的微小差异)。

3.4 fallback 处理 (L85)

let fill: RectStyleProps['fill'] = 'transparent';

当视频加载失败时 element 是 fallback 字符串,不进入 if 分支,fill 保持
'transparent'。原始代码把空字符串传给 fill.image,@antv/g 会尝试把 { image: '' } 当颜色解析,触发
colorStr.indexOf is not a function 崩溃。

3.5 定位 (L108-111)

const { x: videoX } = cell.getContentPosition({ contentWidth: videoWidth });
const videoY = y + (height - videoHeight) / 2;

  • 水平:getContentPosition 把 videoWidth 当作"文本宽度"传入,内部的 getHorizontalTextIconPosition
    会把 video + icon 一起布局(左对齐/居中/右对齐),返回 video 应该放置的 x 坐标。因为 videoWidth
    已经扣除了 icon 宽度,所以 icon + video 不会超出 contentBox。
  • 垂直:内容区中心对齐,(height - videoHeight) / 2 是上方留白。
  1. render 方法变更 (L126-152)

4.1 命名标识 (L130)

const rect = new Rect({ ...config, name: VIDEO_RECT_NAME });

给视频 Rect 加 name: 'videoRect',用于 preview-click.ts 中区分点击目标——只有点击视频 Rect
本身才触发预览,点击单元格空白或 icon 不触发。

4.2 Play 图标居中于视频区域 (L131-148)

const { x, y, width, height } = config.style;

原始代码用 this.getCellInfo(cell) 获取整个内容区的 x/y/width/height,Play
图标居中在整个内容区。现在从 config.style 取值——这是等比缩放后的视频 Rect 实际尺寸和位置,Play
图标精确居中在视频画面上。

@Alexzjt Alexzjt merged commit 8e42aff into next Apr 28, 2026
9 checks passed
@Alexzjt Alexzjt deleted the fix/video-render-cell-width branch April 28, 2026 08:15
@Alexzjt
Copy link
Copy Markdown
Contributor

Alexzjt commented Apr 28, 2026

🎉 This PR is included in version @antv/s2-v2.7.1-alpha.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

next 2.0-next 版本的问题 pr(fix) bug fix released on @alpha

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants