英文:
Alternative for @property for Firefox
问题
我最近在一个项目中正在制作一个圆形动画,不小心使用了@property
,但我并不知道它只在某些浏览器中可用。我需要这个动画在所有浏览器中都能工作,所以我试图看看是否有替代方法。以下是我在使用@property
时所做的事情:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$('.test').addClass('circle');
var circle = $(".circle");
var change = $(".change");
var circleImg = $('.fade-in-img');
circle.on('animationend', function() {
$(circleImg).fadeIn();
});
<!-- language: lang-css -->
.circle-graph-info {
align-items: center;
display: flex;
justify-content: center;
margin: 0 0 0 240px;
position: relative;
}
.circle-graph-info p {
color: #479F56;
font-size: 120px;
font-weight: 800;
margin: 0 -50px 0 0;
max-width: 275px;
position: relative;
}
.circle-graph-info span {
color: #000;
display: block;
font-size: 28px;
font-weight: 400;
}
.circle-graph-info p:first-of-type::before {
content: '';
display: block;
background: #479F56;
height: 5px;
left: -200px;
position: absolute;
top: 50%;
width: 161px;
border-radius: 5px;
}
@property --a {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.circle {
width: 484px;
height: 484px;
padding: 20px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(#000 var(--a), transparent var(--a)),
linear-gradient(#000, #000) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: rgb(138,173,81);
background: linear-gradient(90deg, rgba(138,173,81,1) 0%, rgba(71,159,86,1) 0%, rgba(138,173,81,1) 100%);
border-radius: 50%;
animation: progress 2s .3s ease forwards;
-webkit-animation: progress 2s .3s ease forwards;
}
@-webkit-keyframes progress {
to {
--a: 360deg;
}
}
.circle-wrap {
padding: 5px;
position: relative;
height: 484px;
width: 484px;
}
.fade-in-img {
display: none;
position: absolute;
z-index: 9;
top: 32%;
left: 0;
right: 0;
margin: 0 auto;
width: 140px;
text-align: center;
}
.outer-border {
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25);
height: 102%;
width: 102%;
}
.inner-border {
background: #fff;
position: absolute;
top: 32px;
left: 32px;
border-radius: 50%;
box-shadow: 0px 0px 10px rgba(0,0,0,0.25);
height: 89%;
width: 89%;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="circle-graph">
<div class="graph-wrap">
<div id="graph-2">
<div class="circle-wrap">
<div class="test"></div>
<div class="outer-border"></div>
<div class="inner-border"></div>
</div>
</div>
</div>
</div>
<!-- end snippet -->
我一直在尝试在不使用@property
部分的情况下让它工作,但是我尝试的每一种方法都会破坏动画。我一直在尝试使用以下代码:
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
和
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
但这些都给我带来了非常不同的结果。
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$('.test').addClass('circle');
var circle = $(".circle");
var change = $(".change");
var circleImg = $('.fade-in-img');
circle.on('animationend', function() {
$(circleImg).fadeIn();
});
<!-- language: lang-css -->
.circle-graph-info {
align-items: center;
display: flex;
justify-content: center;
margin: 0 0 0 240px;
position: relative;
}
.circle-graph-info p {
color: #479F56;
font-size: 120px;
font-weight: 800;
margin: 0 -50px 0 0;
max-width: 275px;
position: relative;
}
.circle-graph-info span {
color: #000;
display: block;
font-size: 28px;
font-weight: 400;
}
.circle-graph-info p:first-of-type::before {
content: '';
display: block;
background: #479F56;
height: 5px;
left: -200px;
position: absolute;
top: 50%;
width: 161px;
border-radius: 5px;
}
@property --a {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.circle {
width: 484px;
height: 484px;
padding: 20px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(red, transparent),
linear-gradient(red, red) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: rgb(138,173,81);
border
<details>
<summary>英文:</summary>
I was working on a circle animation for a project recently and mistakenly used `@property` without knowing that it's only available in certain browsers. I needed this animation to work in all browsers so I was trying to see if there is alternative to this. Here's what I was doing with `@property`:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$('.test').addClass('circle');
var circle = $(".circle");
var change = $(".change");
var circleImg = $('.fade-in-img');
circle.on('animationend', function() {
$(circleImg).fadeIn();
});
<!-- language: lang-css -->
.circle-graph-info {
align-items: center;
display: flex;
justify-content: center;
margin: 0 0 0 240px;
position: relative;
}
.circle-graph-info p {
color: #479F56;
font-size: 120px;
font-weight: 800;
margin: 0 -50px 0 0;
max-width: 275px;
position: relative;
}
.circle-graph-info span {
color: #000;
display: block;
font-size: 28px;
font-weight: 400;
}
.circle-graph-info p:first-of-type::before {
content: '';
display: block;
background: #479F56;
height: 5px;
left: -200px;
position: absolute;
top: 50%;
width: 161px;
border-radius: 5px;
}
@property --a {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.circle {
width: 484px;
height: 484px;
padding: 20px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(#000 var(--a), transparent var(--a)),
linear-gradient(#000, #000) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: rgb(138,173,81);
background: linear-gradient(90deg, rgba(138,173,81,1) 0%, rgba(71,159,86,1) 0%, rgba(138,173,81,1) 100%);
border-radius: 50%;
animation: progress 2s .3s ease forwards;
-webkit-animation: progress 2s .3s ease forwards;
}
@-webkit-keyframes progress {
to {
--a: 360deg;
}
}
.circle-wrap {
padding: 5px;
position: relative;
height: 484px;
width: 484px;
}
.fade-in-img {
display: none;
position: absolute;
z-index: 9;
top: 32%;
left: 0;
right: 0;
margin: 0 auto;
width: 140px;
text-align: center;
}
.outer-border {
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25);
height: 102%;
width: 102%;
}
.inner-border {
background: #fff;
position: absolute;
top: 32px;
left: 32px;
border-radius: 50%;
box-shadow: 0px 0px 10px rgba(0,0,0,0.25);
height: 89%;
width: 89%;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="circle-graph">
<div class="graph-wrap">
<div id="graph-2">
<div class="circle-wrap">
<div class="test"></div>
<div class="outer-border"></div>
<div class="inner-border"></div>
</div>
</div>
</div>
</div>
<!-- end snippet -->
I've been trying to get this to work without the `@property` part but everything I attempt breaks the animation. I have been trying use
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
and
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
but these give me very different result:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$('.test').addClass('circle');
var circle = $(".circle");
var change = $(".change");
var circleImg = $('.fade-in-img');
circle.on('animationend', function() {
$(circleImg).fadeIn();
});
<!-- language: lang-css -->
.circle-graph-info {
align-items: center;
display: flex;
justify-content: center;
margin: 0 0 0 240px;
position: relative;
}
.circle-graph-info p {
color: #479F56;
font-size: 120px;
font-weight: 800;
margin: 0 -50px 0 0;
max-width: 275px;
position: relative;
}
.circle-graph-info span {
color: #000;
display: block;
font-size: 28px;
font-weight: 400;
}
.circle-graph-info p:first-of-type::before {
content: '';
display: block;
background: #479F56;
height: 5px;
left: -200px;
position: absolute;
top: 50%;
width: 161px;
border-radius: 5px;
}
@property --a {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.circle {
width: 484px;
height: 484px;
padding: 20px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(red, transparent),
linear-gradient(red, red) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: rgb(138,173,81);
/* background: linear-gradient(90deg, rgba(138,173,81,1) 0%, rgba(71,159,86,1) 0%, rgba(138,173,81,1) 100%); */
border-radius: 50%;
animation: progress 2s .3s ease forwards;
-webkit-animation: progress 2s .3s ease forwards;
}
.reverse-circle {
animation: reverse-progress 2s .3s ease forwards;
-webkit-animation: reverse-progress 2s .3s ease forwards;
}
@-webkit-keyframes progress {
/* 0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);} */
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes reverse-progress {
to {
--a: 0deg;
}
}
.circle-wrap {
padding: 5px;
position: relative;
height: 484px;
width: 484px;
}
.fade-in-img {
display: none;
position: absolute;
z-index: 9;
top: 32%;
left: 0;
right: 0;
margin: 0 auto;
width: 140px;
text-align: center;
}
.outer-border {
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25);
height: 102%;
width: 102%;
}
.inner-border {
background: #fff;
position: absolute;
top: 32px;
left: 32px;
border-radius: 50%;
box-shadow: 0px 0px 10px rgba(0,0,0,0.25);
height: 89%;
width: 89%;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="circle-graph">
<div class="graph-wrap">
<div id="graph-2">
<div class="circle-wrap">
<div class="test"></div>
<div class="outer-border"></div>
<div class="inner-border"></div>
</div>
</div>
</div>
</div>
<!-- end snippet -->
I'm honestly stuck and could use a pointer or any help. Can I get what I'm trying to do to even work here or do I need to go in a different direction?
</details>
# 答案1
**得分**: 1
请注意,您仅指定了 `@-webkit-keyframes` 而没有更标准的 `@keyframes`,因此即使 Firefox 支持 `--property`,它也不会执行动画。
不管怎样,考虑使用 `<svg>`。
1. 用 `<svg>` 替换 `.test` 元素:
```svg
<svg width="484" height="484" class="circle">
<defs>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop stop-color="rgb(71, 159, 86)" offset="0%"/>
<stop stop-color="rgb(138, 173, 81)" offset="100%"/>
</linearGradient>
</defs>
<circle
stroke-width="20"
stroke="url(#myGradient)"
fill="none"
cx="242"
cy="242"
r="232"
/>
</svg>
-
使
<circle>
的描边成为虚线,其中虚线的长度等于<circle>
的周长。我们通过设置pathLength
来将周长转化为已知的数字。然后使用stroke-dasharray
来设置虚线的长度与pathLength
相同的值:<circle … pathLength="100" stroke-dasharray="100" transform="rotate(-90 242 242)" />
-
调整
stroke-dashoffset
,以使<circle>
的虚线的默认状态从两个虚线之间的空白处开始:.circle { stroke-dashoffset: 100; }
-
使用
animation
使虚线动画出现:.circle { … animation: progress 2s .3s ease forwards; } @keyframes progress { to { stroke-dashoffset: 0; } }
示例代码:
<!-- 在这里插入您的HTML代码 -->
/* 在这里插入您的CSS代码 */
这是翻译好的部分,如果需要更多帮助,请告诉我。
英文:
Please note you have only specified @-webkit-keyframes
and not the more standard @keyframes
, so even if --property
was supported in Firefox, it would not animate.
Regardless, consider using an <svg>
.
-
Replace the
.test
element with an<svg>
:<svg width="484" height="484" class="circle"> <defs> <linearGradient id="myGradient" gradientTransform="rotate(90)"> <stop stop-color="rgb(71, 159, 86)" offset="0%"/> <stop stop-color="rgb(138, 173, 81)" offset="100%"/> </linearGradient> </defs> <circle stroke-width="20" stroke="url(#myGradient)" fill="none" cx="242" cy="242" r="232" /> </svg>
-
Make the stroke of the
<circle>
a dash, where the dash is the length of the circumference of the<circle>
. We do this by settingpathLength
which translates the circumference to a known number. Then usestroke-dasharray
to set the dash lengths to the same value aspathLength
:<circle … pathLength="100" stroke-dasharray="100" transform="rotate(-90 242 242)" />
-
Adjust the
stroke-dashoffset
so that the default state of the<circle>
's dash starts from the blank space between two dashes:.circle { stroke-dashoffset: 100; }
-
Animate the dash in with
animation
:.circle { … animation: progress 2s .3s ease forwards; } @keyframes progress { to { stroke-dashoffset: 0; } }
Live example:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.circle-graph-info {
align-items: center;
display: flex;
justify-content: center;
margin: 0 0 0 240px;
position: relative;
}
.circle-graph-info p {
color: #479F56;
font-size: 120px;
font-weight: 800;
margin: 0 -50px 0 0;
max-width: 275px;
position: relative;
}
.circle-graph-info span {
color: #000;
display: block;
font-size: 28px;
font-weight: 400;
}
.circle-graph-info p:first-of-type::before {
content: '';
display: block;
background: #479F56;
height: 5px;
left: -200px;
position: absolute;
top: 50%;
width: 161px;
border-radius: 5px;
}
.circle {
stroke-dashoffset: 100;
animation: progress 2s .3s ease forwards;
}
@keyframes progress {
to {
stroke-dashoffset: 0;
}
}
.circle-wrap {
padding: 5px;
position: relative;
height: 484px;
width: 484px;
}
.fade-in-img {
display: none;
position: absolute;
z-index: 9;
top: 32%;
left: 0;
right: 0;
margin: 0 auto;
width: 140px;
text-align: center;
}
.outer-border {
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25);
height: 102%;
width: 102%;
}
.inner-border {
background: #fff;
position: absolute;
top: 32px;
left: 32px;
border-radius: 50%;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25);
height: 89%;
width: 89%;
}
<!-- language: lang-html -->
<div class="circle-graph">
<div class="graph-wrap">
<div id="graph-2">
<div class="circle-wrap">
<svg width="484" height="484" class="circle">
<defs>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop stop-color="rgb(71, 159, 86)" offset="0%"/>
<stop stop-color="rgb(138, 173, 81)" offset="100%"/>
</linearGradient>
</defs>
<circle
stroke-width="20"
stroke="url(#myGradient)"
fill="none"
cx="242"
cy="242"
r="232"
pathLength="100"
stroke-dasharray="100"
transform="rotate(-90 242 242)"
/>
</svg>
<div class="outer-border"></div>
<div class="inner-border"></div>
</div>
</div>
</div>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论