Firefox的@property的替代方法

huangapple go评论60阅读模式
英文:

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&#39;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&#39;s what I was doing with `@property`:


&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-js --&gt;

    $(&#39;.test&#39;).addClass(&#39;circle&#39;);

    var circle = $(&quot;.circle&quot;);
    var change = $(&quot;.change&quot;);
    var circleImg = $(&#39;.fade-in-img&#39;);

    circle.on(&#39;animationend&#39;, function() {
      $(circleImg).fadeIn();
    });

&lt;!-- language: lang-css --&gt;

    .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: &#39;&#39;;
    		display: block;
    		background: #479F56;
    		height: 5px;
    		left: -200px;
    		position: absolute;
    		top: 50%;
    		width: 161px;
    		border-radius: 5px;
    	}

    	@property --a {
    		syntax: &#39;&lt;angle&gt;&#39;;
    		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%;
    	}

&lt;!-- language: lang-html --&gt;

    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;div class=&quot;circle-graph&quot;&gt;
      &lt;div class=&quot;graph-wrap&quot;&gt;
        &lt;div id=&quot;graph-2&quot;&gt;
          &lt;div class=&quot;circle-wrap&quot;&gt;
          &lt;div class=&quot;test&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;outer-border&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;inner-border&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;

&lt;!-- end snippet --&gt;

I&#39;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:

&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-js --&gt;

    $(&#39;.test&#39;).addClass(&#39;circle&#39;);

    var circle = $(&quot;.circle&quot;);
    var change = $(&quot;.change&quot;);
    var circleImg = $(&#39;.fade-in-img&#39;);

    circle.on(&#39;animationend&#39;, function() {
      $(circleImg).fadeIn();
    });

&lt;!-- language: lang-css --&gt;

    .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: &#39;&#39;;
    		display: block;
    		background: #479F56;
    		height: 5px;
    		left: -200px;
    		position: absolute;
    		top: 50%;
    		width: 161px;
    		border-radius: 5px;
    	}

    	@property --a {
    		syntax: &#39;&lt;angle&gt;&#39;;
    		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%;
    	}

&lt;!-- language: lang-html --&gt;

    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;div class=&quot;circle-graph&quot;&gt;
      &lt;div class=&quot;graph-wrap&quot;&gt;
        &lt;div id=&quot;graph-2&quot;&gt;
          &lt;div class=&quot;circle-wrap&quot;&gt;
          &lt;div class=&quot;test&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;outer-border&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;inner-border&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;

&lt;!-- end snippet --&gt;

I&#39;m honestly stuck and could use a pointer or any help. Can I get what I&#39;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>
  1. 使 <circle> 的描边成为虚线,其中虚线的长度等于 <circle> 的周长。我们通过设置 pathLength 来将周长转化为已知的数字。然后使用 stroke-dasharray 来设置虚线的长度与 pathLength 相同的值:

    <circle
      
      pathLength="100"
      stroke-dasharray="100"
      transform="rotate(-90 242 242)"
    />
    
  2. 调整 stroke-dashoffset,以使 <circle> 的虚线的默认状态从两个虚线之间的空白处开始:

    .circle {
      stroke-dashoffset: 100;
    }
    
  3. 使用 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 &lt;svg&gt;.

  1. Replace the .test element with an &lt;svg&gt;:

    &lt;svg width=&quot;484&quot; height=&quot;484&quot; class=&quot;circle&quot;&gt;
      &lt;defs&gt;
        &lt;linearGradient id=&quot;myGradient&quot; gradientTransform=&quot;rotate(90)&quot;&gt;
          &lt;stop stop-color=&quot;rgb(71, 159, 86)&quot; offset=&quot;0%&quot;/&gt;
          &lt;stop stop-color=&quot;rgb(138, 173, 81)&quot; offset=&quot;100%&quot;/&gt;
        &lt;/linearGradient&gt;
      &lt;/defs&gt;
      &lt;circle
        stroke-width=&quot;20&quot;
        stroke=&quot;url(#myGradient)&quot;
        fill=&quot;none&quot;
        cx=&quot;242&quot;
        cy=&quot;242&quot;
        r=&quot;232&quot;
      /&gt;
    &lt;/svg&gt;
    
  2. Make the stroke of the &lt;circle&gt; a dash, where the dash is the length of the circumference of the &lt;circle&gt;. We do this by setting pathLength which translates the circumference to a known number. Then use stroke-dasharray to set the dash lengths to the same value as pathLength:

    &lt;circle
      pathLength=&quot;100&quot;
      stroke-dasharray=&quot;100&quot;
      transform=&quot;rotate(-90 242 242)&quot;
    /&gt;
    
  3. Adjust the stroke-dashoffset so that the default state of the &lt;circle&gt;'s dash starts from the blank space between two dashes:

    .circle {
      stroke-dashoffset: 100;
    }
    
  4. 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: &#39;&#39;;
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 -->

&lt;div class=&quot;circle-graph&quot;&gt;
&lt;div class=&quot;graph-wrap&quot;&gt;
&lt;div id=&quot;graph-2&quot;&gt;
&lt;div class=&quot;circle-wrap&quot;&gt;
&lt;svg width=&quot;484&quot; height=&quot;484&quot; class=&quot;circle&quot;&gt;
&lt;defs&gt;
&lt;linearGradient id=&quot;myGradient&quot; gradientTransform=&quot;rotate(90)&quot;&gt;
&lt;stop stop-color=&quot;rgb(71, 159, 86)&quot; offset=&quot;0%&quot;/&gt;
&lt;stop stop-color=&quot;rgb(138, 173, 81)&quot; offset=&quot;100%&quot;/&gt;
&lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;circle
stroke-width=&quot;20&quot;
stroke=&quot;url(#myGradient)&quot;
fill=&quot;none&quot;
cx=&quot;242&quot;
cy=&quot;242&quot;
r=&quot;232&quot;
pathLength=&quot;100&quot;
stroke-dasharray=&quot;100&quot;
transform=&quot;rotate(-90 242 242)&quot;
/&gt;
&lt;/svg&gt;
&lt;div class=&quot;outer-border&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;inner-border&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月30日 05:20:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76584666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定