跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 请教一个很怪异的 css3 问题,关于 transform
未分類
8 6 月 2020

请教一个很怪异的 css3 问题,关于 transform

请教一个很怪异的 css3 问题,关于 transform

資深大佬 : myCupOfTea 9

演示如下

https://codesandbox.io/s/material-progress-scale-qi4zd

可以点击 refresh 演示

背景

最近写上传动画,用了 material-ui 的 progress,后来写上传组件文档的时候,用例里用 requestAnimationFrame 快速刷新进度条,发现进度条虽然 css 属性变了但是没有动

仔细观察发现了,是 translate 在开了过渡(transition)的情况下高速刷新就不会变化,把过渡关了就可以(当然实际场景中不可能刷新这么快,所以我也不可能关了过渡)

但是我脑子一抽试试用 scale 加上 transform-origin 来模拟 translate 呢,神奇的事情出现了

高速刷新状态下,它正常的动了,艹

问题

为啥 scale 可以,但是 translate 不可以

其他问题

用 setTimeout 模拟的时候发现在 120 左右这个延迟,很容易出现进度条抖动(回弹?),就是偶尔会出现进度条一下回去一点然后又前进呢,有办法解决吗(打印过进度 value 呢,是正常的)

大佬有話說 (13)

  • 主 資深大佬 : myCupOfTea

    好奇,难道没有人遇到过么

  • 資深大佬 : liuhuihao

    用了 JS requestAnimationFrame 控制进度条进度,为什么还要使用 transition 过渡呢?

  • 主 資深大佬 : myCupOfTea

    @liuhuihao requestAnimationFrame 是用来 模拟高速刷新下的 upload 的

  • 主 資深大佬 : myCupOfTea

    @liuhuihao 控制进度条还是用的 transition + (translate/scale/width)

  • 資深大佬 : redbuck

    “`html
    <style>
    .progress {
    border: 1px solid #e5e5e5;
    margin: 10px;
    overflow: hidden;
    }

    .inner {
    transition: transform 0.16s ease;
    height: 5px;
    background-color: yellowgreen;
    transform-origin: 0 50%;
    }
    </style>
    <div class=”progress translate”>
    <div class=”inner”></div>
    </div>
    <div class=”progress scale”>
    <div class=”inner”></div>
    </div>
    <script type=”text/javascript”>
    const sleep = time => new Promise(resolve => setTimeout(resolve, time));
    const frame = () => new Promise(resolve => requestAnimationFrame(resolve)) || sleep(16.7);
    const $ = s => document.querySelector(s);

    let progress = 0;
    const translate = $(“.translate .inner”);
    const scale = $(“.scale .inner”);

    function render() {
    translate.style.transform = `translateX(${progress – 100}%)`;
    scale.style.transform = `scaleX(${progress / 100})`;
    }

    async function update() {
    while (progress <= 100) {
    render();
    // await frame()
    await sleep(50);
    progress++;
    }
    }

    update();
    </script>
    “`

    帮你改个简单版的,排除多余变量.

    问题依然存在.

    但如果调整 sleep 的时间,可以发现时间越长,会稍微缓解一点.

  • 資深大佬 : gaoryrt

    有没有可能是这样的:
    两个 fill 上的 transition 进行的都是 transform 默认值到当前值的补帧,而不是上一个值到当前值的补帧。
    如果 dom 样式的更新时间足够大,transition duration 足够小,你应该能看到每次从头开始到当前值的动画,而非从上一个值到当前值的动画。

  • 主 資深大佬 : myCupOfTea

    @redbuck 是的,这个问题我和 material-ui 官方讨论了下,这种场景下关闭过渡就行了

  • 主 資深大佬 : myCupOfTea

    @gaoryrt 嗯,确实刷新时间变慢了就可以呢,
    我又另外试了一个属性 width 控制,translate 控制都不行
    但是我很好奇 scale 也是加了过渡效果的,但是 scale 是可以的

  • 主 資深大佬 : myCupOfTea

    @redbuck 其实我就是好奇 scale 也是加了过渡效果的,但是 scale 是可以的
    本来这个场景其实基本不会出现来,没有上传会一直刷新这么快的

  • 主 資深大佬 : myCupOfTea

    另外我测试发现 firefox 对 css var 支持不够好(该测试用例在 firefox 上闪烁的很厉害)
    我把 css var 去了写了另外一个例子,防止有人觉得是 css var 的问题
    https://codesandbox.io/s/material-progress-scale-not-css-var-zw5nt

  • 主 資深大佬 : myCupOfTea

    @redbuck
    @gaoryrt 其实这个用例在火狐上是可以的,应该是 chromium 的问题

  • 資深大佬 : gaoryrt

    那应该是 scale 会有类似于视觉残留的效果?
    或者说是 react 针对 style 里面的 calc 进行了优化导致了问题?

  • 主 資深大佬 : myCupOfTea

    @gaoryrt 跟 react 没关系,我仔细观察过了。css 上的属性已经变了,说明已经从虚拟 dom 渲染到真实 dom 呢,上面也有个老哥写了原生的 js,应该就是 chromium 的问题

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具