首页 > 解决方案 > Chromium 不更新转换原点

问题描述

在基于 Chromium 的浏览器中使用 React 渲染微调器时,该transform-origin属性仅在以下任一情况后更新:

微调器是使用helper 构建styled-componentskeyframes,但由于它在 Safari 和 Firefox 中工作,我不太确定这毕竟是一个 React 问题。

请参阅以下 GIF(为马铃薯质量道歉):

对不起土豆质量

所有其他浏览器都会立即产生预期的结果。这是一个已知的 Chromium 错误吗?我在这里错过了什么吗?

编辑:

这是 Spinner 元素。它是唯一从 App 的入口点呈现的内容。

import React from "react";
import styled, { keyframes } from "styled-components";
import { COLOR_PRIMARY } from "core/constants";

const SpinnerWrapper = styled.div`
    display: inline-block;
    position: relative;
    width: ${props => props.size || "2rem"};
    height: ${props => props.size || "2rem"};
    pointer-events: none;
`;

const spinnerAnimation = keyframes`
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
`;

const SpinnerItem = styled.div`
    box-sizing: border-box;
    display: block;
    position: absolute;
    width: calc(100% - 12px);
    height: calc(100% - 12px);
    margin: 6px;
    border: 2px solid #fff;
    border-radius: 50%;
    animation: ${spinnerAnimation} 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
    border-color: ${props => props.inverse ? "white" : COLOR_PRIMARY} transparent transparent transparent;
    animation-delay: ${props => props.delay || "0"}s;
    transform-origin: 50% 50% !important;
`;

export default ({ size, inverse }) => (
    <SpinnerWrapper size={size}>
        <SpinnerItem inverse={inverse} delay={-.45} />
        <SpinnerItem inverse={inverse} delay={-.3} />
        <SpinnerItem inverse={inverse} delay={-.15} />
    </SpinnerWrapper>
);

标签: cssreactjschromiumcss-transformsstyled-components

解决方案


如果没有一些示例代码来展示您的问题,很难知道我是否正在解决您的实际问题,但我设法遇到了类似的情况。

这个近似再现您的动画的小提琴上,当鼠标悬停在身体​​上时,变换原点更改为居中,但是在某些浏览器上(可以确认当前的 Chrome 和 Chromium 75),动画运行时该值不会更新,除非,正如您所提到的,该元素被检查。

我发现的一个可能的技巧是重置动画。您可以通过复制关键帧声明并在更改变换原点时切换到备用声明来做到这一点:

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(1turn); }
}
@keyframes spin2 {
    from { transform: rotate(0deg); }
    to { transform: rotate(1turn); }
}
.part {
    transform-origin: 0 0;
    animation: spin 1.5s ease infinite;
}
body:hover .part {
    transform-origin: center;
    animation-name: spin2;
}

这是一个展示技巧的小提琴。

如果您不想复制关键帧,我相信您也可以使用 JS 删除动画,强制重排然后重新添加。例子:

// Removes the animation
myElement.style.animation = 'none';
// Forces a reflow - the browser will register that the animation was removed
myElement.clientWidth;
// Adds the animation back (resets it to what is defined in the CSS)
myElement.style.animation = '';

推荐阅读