javascript - 如何使用 React 将动画从静态定位到固定定位?
问题描述
我想做从静态到固定定位的平滑过渡。因为浏览器在动画之前需要知道初始值,所以我想分两个阶段来做:
- 将位置更改为固定并强制渲染,将元素从流中取出,但将其放置在同一位置。left、top、right 和 bottom 的值现在对浏览器来说是已知的。
- 将值更改为它们的目标位置并强制另一个渲染。浏览器现在应该能够为这些值设置动画。
但是我认为我误解了一些基本的东西,因为虽然它确实定位正确,但它根本没有动画。有人可以告诉我以下代码中缺少什么吗?或者,如果我对此采取了错误的方法?
const Component = ({
className
}) => {
const placeholder = React.useRef()
const container = React.useRef()
const [state, setState] = React.useState('contracted')
React.useEffect(() => {
const containerStyle = container.current.style
const placeholderStyle = placeholder.current.style
switch (state) {
case 'expand':
const {
left,
top,
right,
bottom,
width,
height
} = container.current.getBoundingClientRect()
// Take the container out of the flow, placing it
// at the same position.
containerStyle.position = 'fixed'
containerStyle.left = left + 'px'
containerStyle.top = top + 'px'
containerStyle.right = right + 'px'
containerStyle.bottom = bottom + 'px'
// Replace the container with the placeholder.
placeholderStyle.width = width + 'px'
placeholderStyle.height = height + 'px'
// Set animation parameters for the next render.
containerStyle.transition = 'all 1s ease'
// Force a render by transitioning to the next state.
setState('expanding')
break;
case 'expanding':
// Position the container relative to the viewport.
containerStyle.left = 10 + '%'
containerStyle.top = 10 + '%'
containerStyle.right = 10 + '%'
containerStyle.bottom = 10 + '%'
// Force a render by transitioning to the next state.
setState('expanded')
break;
case 'contract':
// Place the container back into the flow.
containerStyle.transition = null
containerStyle.position = null
containerStyle.left = null
containerStyle.top = null
containerStyle.right = null
containerStyle.bottom = null
// Remove the placeholder.
placeholderStyle.width = null
placeholderStyle.height = null
// Force a render by transitioning to the next state.
setState('contracted')
break;
}
}, [state])
const toggle = () => {
if (state === 'contracted') {
setState('expand')
} else {
setState('contract')
}
}
return (
<div ref={placeholder} className={className} >
<div
ref={container}
className='container'
onClick={toggle}>
<span>This should animate.</span>
</div>
</div>
)
}
ReactDOM.render(
<React.StrictMode >
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla.
<Component className = 'component' />
Gravida dictum fusce ut placerat orci nulla pellentesque dignissim.Netus et malesuada fames ac turpis egestas.Accumsan lacus vel facilisis volutpat est velit egestas dui id.
</React.StrictMode>,
document.getElementById('root')
)
.component {
float: left;
margin: 0.5rem;
}
.container {
display: inline-flex;
justify-content: center;
align-items: center;
padding: 0.5rem;
background-color: lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js" integrity="sha512-qlzIeUtTg7eBpmEaS12NZgxz52YYZVF5myj89mjJEesBd/oE9UPsYOX2QAXzvOAZYEvQohKdcY8zKE02ifXDmA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js" integrity="sha512-9jGNr5Piwe8nzLLYTk8QrEMPfjGU0px80GYzKZUxi7lmCfrBjtyCc1V5kkS5vxVwwIB7Qpzc7UxLiQxfAN30dw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="root"></div>
解决方案
推荐阅读
- javascript - 通过 JavaScript 更新时,固定位置 div 中的按钮消失(仅在 Firefox 移动浏览器中出现)
- angular - 将文件上传到 Angular 6 输入文件时,有没有办法获取文件的真实路径?
- c - 如何正确比较 2 个数组以查看它们是否相同?
- angular - 如何在 ngxs 选择器上直接使用 rxjs 管道
- python - 如何生成每个刻度的指标值、金融研究、量化交易、矢量化回测
- c - 如何从文件中读取所有字节
- ios - 如何更改 SwiftUI Divider 上方和下方的填充?
- python - Python - 如何找出列表中元素的长度?
- machine-learning - 如何进一步调整超参数与以下趋势线的训练损失和验证损失?
- python - 我想冻结我的所有转换,但代码太长