javascript - 使用 React 的动态 CSS 动画变量
问题描述
const {useState, useEffect, useRef} = React;
const App = () => {
const [pressed, setPressed] = useState(false);
const [shoot, setShoot] = useState(false);
const [seconds, setSeconds] = useState(0);
useInterval(() => {
// Your custom logic here
pressed && seconds < 3 && setSeconds((prev)=> Number((prev+0.1).toFixed(1)));
}, 100);
useInterval(()=>{
!pressed && seconds > 0 && setSeconds((prev)=>{
if( Number((prev-0.5).toFixed(1)) < 0){
return 0;
}
return Number((prev-0.5).toFixed(1))
});
}, 20)
return (
<div>
<button
onMouseDown={()=>{
console.log('mouseDown')
setShoot(false);
setPressed(true);
}}
onMouseUp={()=>{
console.log('mouseUp')
setShoot(true);
setPressed(false);
}}
style={{
transform: `rotate(-${seconds*15}deg)`
}}
>Press</button>
<span className={`dot ${shoot ? '--shooted' : ''}`} />
<p>{seconds}</p>
</div>
)
};
ReactDOM.render(<App />, document.getElementById('root'));
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
.dot{
position: absolute;
width: 16px;
height: 16px;
border-radius:100%;
background: red;
}
.dot.--shooted{
animation: test 1s;
}
@keyframes test{
0%{
transform: translateX(0px);
}
100%{
transform: translateX(200px); // it should be dynamic px.
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />
我想在按下按钮的几秒钟内移动红点。
但我正在使用animation
,所以我无法控制px
CSS 中的。
如果我按下按钮 3 秒,红点应该移动到300px
.
如果我按下按钮 1 秒,红点应该移动到100px
.
解决方案
这是一个例子。但是您需要添加一个逻辑才能将其移回。
const {
useState,
useEffect,
useRef
} = React;
const App = () => {
const [pressed, setPressed] = useState(false);
const [shoot, setShoot] = useState(false);
const [seconds, setSeconds] = useState(0);
const dotRef = useRef();
useInterval(() => {
// Your custom logic here
pressed && seconds < 3 && setSeconds((prev) => Number((prev + 0.1).toFixed(1)));
}, 100);
useInterval(() => {
!pressed && seconds > 0 && setSeconds((prev) => {
if (Number((prev - 0.5).toFixed(1)) < 0) {
return 0;
}
return Number((prev - 0.5).toFixed(1))
});
}, 20)
const handleMouseUp = () => {
dotRef.current.style.transform = `translateX(${seconds * 100}px)`;
}
return ( <
div >
<
button onMouseDown = {
() => {
console.log('mouseDown')
setShoot(false);
setPressed(true);
}
}
onMouseUp = {
() => {
console.log('mouseUp')
setShoot(true);
setPressed(false);
handleMouseUp();
}
}
style = {
{
transform: `rotate(-${seconds*15}deg)`
}
} >
Press < /button> <
span className = {
`dot ${shoot ? '--shooted' : ''}`
}
ref = {
dotRef
}
/> <
p > {
seconds
} < /p> < /
div >
)
};
ReactDOM.render( < App / > , document.getElementById('root'));
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
.dot {
position: absolute;
width: 16px;
height: 16px;
border-radius: 100%;
background: red;
transition: transform 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />
推荐阅读
- java - 在 liferay 中使用 commons-fileupload 无法正确解析请求
- node.js - 为什么将 WSDL 文件传递给肥皂服务器?
- sql - 在 Oracle SQL 中使用另一个表中的数据创建一个新表
- javascript - Javascript:将数组转换为 CSV 格式并复制到剪贴板
- php - PHP cannot connect to mysql through python
- corda - 如何在corda api中使用post而不是put?
- unity3d - Unity NetworkDiscovery,使用“使用 NetworkManager”?
- javascript - React - 更改输入时自动提交表单
- regex - RegEx 验证 - 使 none@anydomain.com 无效,但验证其他电子邮件
- angular - 将 Angular 模块分离到不同的包中