我一直在尝试使用 React 和 vanilla css 创建类似动画的里程表。到目前为止,它的工作原理是当数字增加时,translationY
会像实际的里程表一样向上发生。我目前的问题是,当它从 9 变为 0 时,它translationY
发生在相反的方向(向下而不是向上)。我希望它仍然朝着相同的方向(向上)前进,但非常坚持如何做到这一点。任何帮助将不胜感激...
问问题
126 次
1 回答
1
我花了太多时间寻找解决方案。首先,有很多库可以让这样的事情变得微不足道,但是我很享受寻找解决方案的学习过程。
我没有创建特定于 react 的解决方案,但我的 vanilla javascript 演示应该足以轻松地将其移植到 react 解决方案中。
为了完成这个任务,我首先尝试在每次发生变化时创建一个元素,底部的数字是起始编号,顶部的数字是着陆编号,然后向下滑动直到达到所需的数字,然后制作旧元素消失。然而,当元素快速更改时,这最终看起来不连贯,并产生了一些意想不到的效果。
在偶然发现一些演示后,我意识到 3d css 可能是完美的解决方案。我们可以创建一个在轮子上旋转的 3d 元素,而不是让我们上下转换的 2d 元素。Js 可以计算旋转元素始终向前旋转所需的度数。
请欣赏我的小演示,如果您有任何问题,请提出。
const $ = (str, dom = document) => [...dom.querySelectorAll(str)];
const panels = $(".panel");
panels.forEach((panel, i) => {
panel.style.setProperty("--angle", `${360 / panels.length * i}deg`)
});
const ring = $(".ring")[0];
const nums = $(".num");
nums.forEach((num, i) => {
num.addEventListener("click", () => {
const numAngle = 36 * i;
const currentAngle =
ring.style.getPropertyValue("--deg")
.replace(/\D/g, "");
let nextAngle = numAngle;
while (nextAngle < currentAngle) {
nextAngle += 360;
}
ring.style.setProperty("--deg", `-${nextAngle}deg`)
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body {
display: grid;
place-items: center;
min-height: 100vh;
perspective: 500px;
perspective-origin: 50% 50%;
}
.ring {
transform-style: preserve-3d;
transition: transform 1s;
transform: rotateX(var(--deg));
}
.panel {
position: absolute;
transform:
translate(-50%, -50%)
rotateX(var(--angle))
translateZ(22.5px);
border-bottom: 1px solid black;
background-color: white;
}
.numPanel {
position: absolute;
top: 0;
left: 0;
width: 100%;
display: flex;
justify-content: center;
gap: 1rem;
user-select: none;
}
.num {
font-size: 2rem;
padding: 0.5rem;
cursor: pointer;
}
.num:hover {
background-color: lightblue;
}
<div class="numPanel">
<div class="num">0</div>
<div class="num">1</div>
<div class="num">2</div>
<div class="num">3</div>
<div class="num">4</div>
<div class="num">5</div>
<div class="num">6</div>
<div class="num">7</div>
<div class="num">8</div>
<div class="num">9</div>
</div>
<div class="ring">
<div class="panel">0</div>
<div class="panel">1</div>
<div class="panel">2</div>
<div class="panel">3</div>
<div class="panel">4</div>
<div class="panel">5</div>
<div class="panel">6</div>
<div class="panel">7</div>
<div class="panel">8</div>
<div class="panel">9</div>
</div>
于 2021-12-19T06:51:16.507 回答