我正在努力在 React Typescript 中重做这个代码笔。我在这里的博客文章中找到了它 简单的方法 - 创建 React 应用程序并添加到 css 文件中,它完美运行。 不,我尝试了使用样式组件的方法,但似乎我缺少一些东西,因为它还没有工作?
App.tsx
import React from "react";
import "./App.css";
import styled from "styled-components";
/* Animate when Houdini is available */
const Houdini = styled.div`
width: 400px;
height: 300px;
border-radius: 10px;
padding: 2rem;
margin: auto;
display: grid;
place-content: center;
text-align: center;
font-size: 1.5em;
--border-size: 0.3rem;
border: var(--border-size) solid transparent;
/* Paint an image in the border */
border-image: conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
)
1 stretch;
background: rgb(255 255 255 / var(--opacity));
@supports (background: paint(houdini)) {
@property --opacity {
syntax: "<number>";
initial-value: 0.5;
inherits: false;
}
@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
@keyframes opacityChange {
to {
--opacity: 1;
}
}
@keyframes rotate {
to {
--angle: 360deg;
}
}
.rainbow {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
/* Hide the warning */
.warning {
display: none;
}
}
`;
function App() {
return (
<>
<Houdini>
<p>
This demo uses a real border with <code>border-image</code>, a
background, and finally Houdini to animate.
</p>
</Houdini>
<div>
<p>
⚠️ Your browser does not support{" "}
<a href="https://web.dev/css-individual-transform-properties/">
@property
</a>{" "}
so the animation won’t work
<br />
Please use Chrome.
</p>
</div>
</>
);
}
export default App;
和工作代码笔的轻微变化 我的App.tsx中的更改与上述相同 - 同样的问题,我使用了样式化的组件并且效果没有显示。
const Houdini = styled.div`
.
.
.
--border-size: 0.3rem;
border: var(--border-size) dotted transparent;
background-image: linear-gradient(
to right,
rgb(255 255 255 / var(--opacity)),
rgb(255 255 255 / var(--opacity))
),
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
);
background-origin: border-box;
background-clip: padding-box, border-box;
.
.
.
`;
罪魁祸首是启动动画的嵌套CSS 规则:
.rainbow {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
。在 CodePen 示例中,它以带有边框的元素为目标:
<div class="rainbow">
<p>This demo uses a real border with <code>border-image</code>,
a background, and finally Houdini to animate.</p>
</div>
但是一旦转换为样式化组件,带有"rainbow"类名的<div>
就被<Houdini>
样式的 React 组件所取代。因此,它的类名不再是"彩虹",而是由样式化组件生成的。
<Houdini> // styled-components replaces it by something like "<div class="sc-bczRLJ kCseJt">"
<p>
This demo uses a real border with <code>border-image</code>, a
background, and finally Houdini to animate.
</p>
</Houdini>
为了达到相同的效果(即准备然后嵌套规则来启动动画,应用于相同的类名),我们可以简单地使用&
(&符号)标识符,样式化组件将其替换为生成的类名(SASS/SCSS 技术):
https://styled-components.com/docs/basics#pseudoelements-pseudoselectors-and-nesting
&
单个 & 符号引用组件的所有实例;它用于应用广泛的覆盖
& /*.rainbow*/ {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
。现在动画成功了!
注意:不要忘记定义您的初始 CSS 变量(例如在全局 CSS 文件中):
:root {
--angle: 45deg;
--opacity: 0.5;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
代码沙盒演示:https://codesandbox.io/s/winter-dream-ej7yec?file=/src/App.tsx:1069-1176