首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CSS3或VanillaJS在SVG动画中为时钟效果制作一个圆圈?

如何使用CSS3或VanillaJS在SVG动画中为时钟效果制作一个圆圈?
EN

Stack Overflow用户
提问于 2018-12-12 11:18:06
回答 1查看 199关注 0票数 1

我有以下代码:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="city-total-v2" version="1.1" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<g id="Block1board">
	<g>
		<linearGradient id="SVGID_492_" gradientUnits="userSpaceOnUse" x1="206.0166" y1="603.585" x2="165.4035" y2="493.2244">
			<stop offset="0" style="stop-color: rgb(48, 66, 204);" />
			<stop offset="1" style="stop-color: rgb(48, 66, 204); stop-opacity: 0;" />
		</linearGradient>
		<polygon fill-rule="evenodd" clip-rule="evenodd" fill="url(#SVGID_492_)" points="109.77,675.92 109.77,488.97 262.38,422.89 262.38,609.83 109.77,675.92  " />
		<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#3042CC" points="116.19,721.81 116.19,721.42 109.7,716.77 109.7,611.43 262.73,540.88 269.11,545.97 269.21,545.93 269.21,651.25 118.96,720.53 116.63,721.74 116.52,721.66 116.19,721.81  " />
		<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#0A2C60" points="116.19,721.81 116.19,721.42 109.7,716.77 109.7,611.43 201.92,682.28 118.96,720.53 116.63,721.74 116.52,721.66 116.19,721.81  " />
		<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M134.53,655.73c0.08-19.16,10.9-37.98,24.14-42 c13.24-4.03,23.92,8.25,23.83,27.41c-0.08,19.16-10.9,37.97-24.14,42S134.44,674.88,134.53,655.73L134.53,655.73z" style="     display: block; " />
		<linearGradient id="SVGID_493_" gradientUnits="userSpaceOnUse" x1="161.1758" y1="638.1934" x2="161.1758" y2="663.8602">
			<stop offset="0" style="stop-color: rgb(48, 66, 204);" />
			<stop offset="1" style="stop-color: rgb(75, 235, 201);" />
		</linearGradient>
		<path fill-rule="evenodd" clip-rule="evenodd" fill="url(#SVGID_493_)" d="M142.87,672.1L142.87,672.1l17.48-22.04v-32.18 c10.75-2.23,19.2,8.14,19.13,23.96c-0.07,16.5-9.39,32.71-20.8,36.18C152.31,679.96,146.63,677.51,142.87,672.1L142.87,672.1z" style="     transform: rotate3d(0, 16deg); " />
	</g>
</svg>

单击运行代码片段查看演示。

我想用渐变形状填充圆圈(就像时钟一样)

这可以使用CSS3或VanillaJS吗??任何建议都是非常感谢的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-13 13:25:36

为了使它工作,我已经注释掉了您的最后一条路径,现在我正在动态地绘制它。随着动画的每一步,路径改变了它的形状。

要启动动画,请单击svg画布。

请阅读我在代码中的评论。

代码语言:javascript
复制
let c = {x:159,y:648.13}//the center of the shape
let tilt = 16;//the tilt angle
// the radiuses of the ellipse 
let R = 30.5;
let r = 17.8;
let steps = 360;// number of frames for the animation
let step = 2*Math.PI/steps;
let rid = null;// request animation id
let ry = [];// an array for the points used to draw the ellipse
//rotate the path
test.setAttributeNS(null,"transform",`rotate(${tilt} ${c.x} ${c.y})` )


let a = -Math.PI/2 -(16 * Math.PI/180);// starting angle

function Frame(){
  rid= requestAnimationFrame(Frame);
  // with every step a new point is pushed in the points array
  if(a < 3*Math.PI/2){a+=step
  let x = c.x + r*Math.cos(a);
  let y = c.y + R*Math.sin(a);
  ry.push({x,y})
  // build the d attribute for the path
  let d = `M${c.x},${c.y}`;

ry.map(e=>{
  d+=`L${e.x},${e.y}`
})
 d+="Z" 
// reset the d attribute for the path                     
test.setAttributeNS(null,"d",d);
 }else{
 // when everithing is done, stop the animation
   cancelAnimationFrame(rid)
 }
}

// restart animation on click
svg.addEventListener("click",()=>{
  if(rid){cancelAnimationFrame(rid); rid="null"}
  a = -Math.PI/2 -(16 * Math.PI/180);
  ry = [];
  Frame()
})
代码语言:javascript
复制
svg{border:1px solid}
代码语言:javascript
复制
<svg id="svg" viewBox="100 400 200 350" width="200">
  <defs>
    <linearGradient id="SVGID_492_" gradientUnits="userSpaceOnUse" x1="206.0166" y1="603.585" x2="165.4035" y2="493.2244">
    <stop offset="0" style="stop-color: rgb(48, 66, 204);" />
    <stop offset="1" style="stop-color: rgb(48, 66, 204); stop-opacity: 0;" /></linearGradient>
  <linearGradient id="SVGID_493_" gradientUnits="userSpaceOnUse" x1="161.1758" y1="638.1934" x2="161.1758" y2="663.8602">
    <stop offset="0" style="stop-color: rgb(48, 66, 204);" />
    <stop offset="1" style="stop-color: rgb(75, 235, 201);" />
  </linearGradient>  
  </defs> 
  
<g id="Block1board">
  <polygon fill="url(#SVGID_492_)" points="109.77,675.92 109.77,488.97 262.38,422.89 262.38,609.83 109.77,675.92  " />
  <polygon fill="#3042CC" points="116.19,721.81 116.19,721.42 109.7,716.77 109.7,611.43 262.73,540.88 269.11,545.97 269.21,545.93 269.21,651.25 118.96,720.53 116.63,721.74 116.52,721.66 116.19,721.81  " />
  <polygon fill="#0A2C60" points="116.19,721.81 116.19,721.42 109.7,716.77 109.7,611.43 201.92,682.28 118.96,720.53 116.63,721.74 116.52,721.66 116.19,721.81" />
  <path fill="#FFFFFF" d="M134.53,655.73c0.08-19.16,10.9-37.98,24.14-42 c13.24-4.03,23.92,8.25,23.83,27.41c-0.08,19.16-10.9,37.97-24.14,42S134.44,674.88,134.53,655.73L134.53,655.73z" />
   
  <!--<path fill="url(#SVGID_493_)" d="M142.87,672.1L142.87,672.1l17.48-22.04v-32.18 c10.75-2.23,19.2,8.14,19.13,23.96c-0.07,16.5-9.39,32.71-20.8,36.18C152.31,679.96,146.63,677.51,142.87,672.1L142.87,672.1z" style="transform: rotate3d(0, 16deg); " />-->
  
  <path id="test" d="" fill="url(#SVGID_493_)"  />  
  </g>
</svg>

更新

为了以不同的角度停止动画,我添加了let stopAngle = (240*Math.PI/180)-Math.PI/2;在本例中,在240个degs处停止。如果您需要使动画变慢,请更改step持续时间。例如,尝试step = 0.008;而不是step = 2*Math.PI/steps

代码语言:javascript
复制
let c = {x:150,y:150}
let R = 120;
let r = 90;
let steps = 360;
let step = 0.005//2*Math.PI/steps;
let rid = null;
let ry = []


let a = -Math.PI/2;// starting angle

let stopAngle = (240*Math.PI/180)-Math.PI/2

function Frame(){
  rid= requestAnimationFrame(Frame);
  if(a < stopAngle){a+=step
  let x = c.x + r*Math.cos(a);
  let y = c.y + R*Math.sin(a);
  ry.push({x,y})
  let d = `M${c.x},${c.y}`;

ry.map(e=>{
  d+=`L${e.x},${e.y}`
})
 d+="Z" 
                     
test.setAttributeNS(null,"d",d);
 }else{
   cancelAnimationFrame(rid)
 }
}

Frame();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53741896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档