尝试复制此示例,但我使用的是gatsby和styled组件;所以我正在尝试将普通的 css 文件转换为样式化组件。但是,当我单击或拖动时,卡片根本没有移动或反应,我做错了什么吗?
这个文件几乎只是复制/粘贴:
import React, { useState } from "react";
import { useSprings, animated, interpolate } from "react-spring";
import { useGesture } from "react-use-gesture";
const cards = [
"https://upload.wikimedia.org/wikipedia/en/f/f5/RWS_Tarot_08_Strength.jpg",
"https://upload.wikimedia.org/wikipedia/en/5/53/RWS_Tarot_16_Tower.jpg",
"https://upload.wikimedia.org/wikipedia/en/9/9b/RWS_Tarot_07_Chariot.jpg",
"https://upload.wikimedia.org/wikipedia/en/d/db/RWS_Tarot_06_Lovers.jpg",
"https://upload.wikimedia.org/wikipedia/en/thumb/8/88/RWS_Tarot_02_High_Priestess.jpg/690px-RWS_Tarot_02_High_Priestess.jpg",
"https://upload.wikimedia.org/wikipedia/en/d/de/RWS_Tarot_01_Magician.jpg"
];
// These two are just helpers, they curate spring data, values that are later being interpolated into css
const to = i => ({
x: 0,
y: i * -4,
scale: 1,
rot: -10 + Math.random() * 20,
delay: i * 100
});
const from = i => ({ x: 0, rot: 0, scale: 1.5, y: -1000 });
// This is being used down there in the view, it interpolates rotation and scale into a css transform
const trans = (r, s) =>
`perspective(1500px) rotateX(30deg) rotateY(${r /
10}deg) rotateZ(${r}deg) scale(${s})`;
function Deck() {
const [gone] = useState(() => new Set()); // The set flags all the cards that are flicked out
const [props, set] = useSprings(cards.length, i => ({
...to(i),
from: from(i)
})); // Create a bunch of springs using the helpers above
// Create a gesture, we're interested in down-state, delta (current-pos - click-pos), direction and velocity
const bind = useGesture(
({
args: [index],
down,
delta: [xDelta],
distance,
direction: [xDir],
velocity
}) => {
const trigger = velocity > 0.2; // If you flick hard enough it should trigger the card to fly out
const dir = xDir < 0 ? -1 : 1; // Direction should either point left or right
if (!down && trigger) gone.add(index); // If button/finger's up and trigger velocity is reached, we flag the card ready to fly out
set(i => {
if (index !== i) return; // We're only interested in changing spring-data for the current spring
const isGone = gone.has(index);
const x = isGone ? (200 + window.innerWidth) * dir : down ? xDelta : 0; // When a card is gone it flys out left or right, otherwise goes back to zero
const rot = xDelta / 100 + (isGone ? dir * 10 * velocity : 0); // How much the card tilts, flicking it harder makes it rotate faster
const scale = down ? 1.1 : 1; // Active cards lift up a bit
return {
x,
rot,
scale,
delay: undefined,
config: { friction: 50, tension: down ? 800 : isGone ? 200 : 500 }
};
});
if (!down && gone.size === cards.length)
setTimeout(() => gone.clear() || set(i => to(i)), 600);
}
);
// Now we're just mapping the animated values to our view, that's it. Btw, this component only renders once. :-)
return props.map(({ x, y, rot, scale }, i) => (
<animated.div
key={i}
style={{
transform: interpolate([x, y], (x, y) => `translate3d(${x}px,${y}px,0)`)
}}
>
{/* This is the card itself, we're binding our gesture to it (and inject its index so we know which is which) */}
<animated.div
{...bind(i)}
style={{
transform: interpolate([rot, scale], trans),
backgroundImage: `url(${cards[i]})`
}}
/>
</animated.div>
));
}
export default Deck;
在这里,我尝试将CSS文件拆分为(两个(样式的组件: 所以它基本上更像是一个包装器:
import React from "react";
import Tarot from "@components/SpringTarot";
import styled from "styled-components";
const Outer = styled.div`
* {
box-sizing: border-box;
}
overscroll-behavior-y: contain;
margin: 0;
padding: 0;
height: 100%;
width: 100%;
user-select: none;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
position: fixed;
overflow: hidden;
`;
const Wrapper = styled.div`
background: lightblue;
position: fixed;
overflow: hidden;
width: 100%;
height: 100%;
cursor: url("https://uploads.codesandbox.io/uploads/user/b3e56831-8b98-4fee-b941-0e27f39883ab/Ad1_-cursor.png")
16 16,
auto;
& > div {
position: absolute;
width: 100vw;
height: 100vh;
will-change: transform;
display: flex;
align-items: center;
justify-content: center;
}
& > div > div {
background-color: white;
background-size: auto 85%;
background-repeat: no-repeat;
background-position: center center;
width: 45vh;
max-width: 300px;
height: 85vh;
max-height: 570px;
will-change: transform;
border-radius: 10px;
box-shadow: 0 12.5px 100px -10px rgba(50, 50, 73, 0.4),
0 10px 10px -10px rgba(50, 50, 73, 0.3);
}
`;
const SpringTarot = () => (
<Outer>
<Wrapper>
<Tarot />
</Wrapper>
</Outer>
);
export default SpringTarot;
我尝试将现在在外部包装器中的内容放入样式组件全局样式中,但这没有任何区别。
确保使用动画扩展要设置动画的本机元素。如果你想在其他平台上对 React 组件、样式化组件或元素进行动画处理,请执行以下操作:
const AnimatedHeader = styled(animated.h1)`
...;
`
这是来自官方的春季文档。