css - CSS动画一个圆锥渐变作为边框图像
问题描述
我正在尝试使用 css 作为 boder 图像来为锥形渐变设置动画。我使用另一个开发人员的代码盘作为样板并尝试更改它。他的动画是使用自定义属性来旋转边框图像:
div {
--angle: 0deg;
width: 50vmin;
height: 50vmin;
border: 10vmin solid;
border-image: conic-gradient(from var(--angle), red, yellow, lime, aqua, blue, magenta, red) 1;
animation: 10s rotate linear infinite;
}
@keyframes rotate {
to {
--angle: 360deg;
}
}
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
我试图为不起作用的实际渐变设置动画。我想以某种方式得到这样的工作:
div {
--angle: 0%;
width: 50vmin;
height: 50vmin;
border: 10vmin solid;
border-image: conic-gradient(from 0deg at 50% 50%, rgba(0, 154, 177, 0) 0%, rgba(0, 154, 177, 0) var(--angle), rgba(0, 154, 177, 1) var(--angle), rgba(0, 154, 177, 1) 100%, rgba(0, 154, 177, 0) 100%, rgba(0, 154, 177, 0) 100%) 1;
animation: 10s rotate linear infinite;
}
@keyframes rotate {
from {
--angle: 0%;
}
to {
--angle: 25%;
}
}
@property --angle {
syntax: '<angle>';
initial-value:0%;
inherits: false;
}
[更新]
通过使用剪辑路径选项,我现在的结果是:
div {
padding: 10px;
}
a{
position:relative;
text-decoration: none;
padding: 10px 20px;
background-color: transparent;
transition: background-color .5s ease-in;
}
a:after{
content:"";
position:absolute;
border:1px solid black;
top:0;
left:0;
width:100%;
height:100%;
box-sizing: border-box;
}
a:hover{
background-color: rgba(0,0,0,.2);
}
a:hover:after{
animation: .8s clipping-border ease-in forwards;
}
* {
box-sizing: border-box;
}
@keyframes clipping-border {
from {
clip-path:polygon(0% 100%, 100% 100%,100% 0%,50% 0%,50% 50%,50% 0%,0% 0%);
}
40% {
clip-path:polygon(0% 100%, 100% 100%,100% 0%,100% 0%,50% 50%,0% 0%,0% 0%);
}
40.1% {
clip-path:polygon(0% 100%, 100% 100%,100% 0%,50% 50%,50% 50%,50% 50%,0% 0%);
}
60% {
clip-path:polygon(0% 100%, 100% 100%,100% 100%,50% 50%,50% 50%,50% 50%,0% 100%);
}
60.1% {
clip-path:polygon(0% 100%, 100% 100%,50% 50%,50% 50%,50% 50%,50% 50%,50% 50%);
}
62% {
clip-path:polygon(5% 100%, 95% 100%,95% 50%,95% 50%,5% 50%,5% 50%,5% 50%);
border-width: 1px;
}
to {
clip-path:polygon(5% 100%, 95% 100%,95% 50%,95% 50%,5% 50%,5% 50%,5% 50%);
border-width: 5px;
}
}
<div>
<a href="#">Some button</a>
</div>
解决方案
更新您的代码,如下所示。选择正确的类型很重要,您使用的是百分比而不是角度:
div {
--angle: 0%;
width: 50vmin;
height: 50vmin;
border: 10vmin solid;
border-image: conic-gradient(transparent var(--angle), rgba(0, 154, 177, 1) 0 100%) 1;
animation: 10s rotate linear infinite;
}
@keyframes rotate {
to {
--angle: 100%;
}
}
@property --angle {
syntax: '<percentage>'; /* this one is important */
initial-value: 0%;
inherits: false;
}
input[type="checkbox"] {
position: fixed;
top: 1em;
left: 1em;
}
input[type="checkbox"]:after {
content: 'Toggle Fill';
white-space: nowrap;
padding-left: 1.5em;
}
input[type="checkbox"]:checked+div {
border-image-slice: 1 fill;
}
body {
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
display: grid;
place-items: center;
background: #fff;
}
footer {
text-align: center;
font-style: italic;
}
<input type="checkbox" />
<div></div>
或者像这样:
div {
--angle: 0deg;
width: 50vmin;
height: 50vmin;
border: 10vmin solid;
border-image: conic-gradient(from calc(-1*var(--angle)),transparent calc(2*var(--angle)), rgba(0, 154, 177, 1) 0 100%) 1;
animation: 10s rotate linear infinite;
}
@keyframes rotate {
to {
--angle: 180deg;
}
}
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
input[type="checkbox"] {
position: fixed;
top: 1em;
left: 1em;
}
input[type="checkbox"]:after {
content: 'Toggle Fill';
white-space: nowrap;
padding-left: 1.5em;
}
input[type="checkbox"]:checked+div {
border-image-slice: 1 fill;
}
body {
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
display: grid;
place-items: center;
background: #fff;
}
footer {
text-align: center;
font-style: italic;
}
<input type="checkbox" />
<div></div>
使用剪辑路径没有 CSS 变量的另一个想法:
div {
width: 50vmin;
height: 50vmin;
position:relative;
}
div::before {
content:"";
position:absolute;
inset:-10vmin;
padding: 10vmin;
background:rgba(0, 154, 177, 1);
-webkit-mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
-webkit-mask-composite:destination-out;
mask-composite:exclude;
animation: 5s rotate linear infinite;
clip-path:polygon(0 0, 50% 0,50% 50%,50% 0,100% 0,100% 100%,0 100%);
}
@keyframes rotate {
20% {
clip-path:polygon(0 0, 0 0,50% 50%,100% 0,100% 0,100% 100%,0 100%);
}
75% {
clip-path:polygon(0 100%, 0 100%,50% 50%,100% 100%,100% 100%,100% 100%,0 100%);
}
100% {
clip-path:polygon(50% 100%, 50% 100%,50% 50%,50% 100%,50% 100%,50% 100%,50% 100%);
}
}
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
input[type="checkbox"] {
position: fixed;
top: 1em;
left: 1em;
}
input[type="checkbox"]:after {
content: 'Toggle Fill';
white-space: nowrap;
padding-left: 1.5em;
}
input[type="checkbox"]:checked+div:before {
-webkit-mask:none;
}
body {
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
display: grid;
place-items: center;
background: #fff;
}
<input type="checkbox" />
<div></div>
推荐阅读
- html - 图片在 Blogger 博客的移动视图中调整大小
- javascript - 如何使用Javascript通过乘数放大文本
- javascript - 递归访问对象中对象的键/值对并将它们组合成一个平面数组
- python - 带有计时器触发器和 RunOnStartup 的 Python 中的 Azure 函数在本地失败,并出现错误“未找到任何已初始化的语言工作者”
- r - 您可以将 Shiny Dashboard 框的宽度设置为 1.5 吗?
- python-3.x - 使用 matplotlib 的多行 x 刻度标签
- c# - 具有不同显示缩放问题的 C# WPF 显示屏幕截图
- java - Firebase Android:随机显示数据
- bash - 根据列分隔文本文件中的行
- javascript - 如何在谷歌标签管理器中为某个类的每个元素触发 DOM Ready 的标签?