这是一款HTML5 SVG线条变形动画特效。这个特效demo是一个轮播图分页导航的例子,在每个分页圆点上都有一个SVG圆形线条,当用户点击其它圆点时,圆形线条以平滑过渡的方式运动到下一个位置。
使用方法
操作SVG需要使用gsap的TweenMax.min.js库。
<script src="path/to/TweenMax.min.js"></script>
HTML结构
实现这个效果需要2个元素,一个圆形和一条直线。分页圆点导航按钮的解绑HTML结构如下:
<div class="controls"> <!-- 圆形线条 --> <div id="circle-line"> <svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <circle id="circle-line-path" stroke-width="4" cx="19" cy="19" r="17"></circle> </g> </svg> </div> <!-- 直线 --> <div class="straight-line"></div> <div class="dot active"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> </div>
CSS样式
为圆形线条和直线添加下面的CSS样式。
#circular-line { position: absolute; top: 0; left: 0; pointer-events: none; transform: rotate(90deg); } #circular-line.flip { transform: rotate(90deg) scaleY(-1); } #circular-line-path { stroke-dasharray: 106; stroke-dashoffset: 0; stroke-linejoin: round; stroke-linecap: round; stroke: #F6A4EB; } .straight-line { position: absolute; left: 0; right: 0; width: 100%; bottom: 0; height: 4px; background: #F6A4EB; border-radius: 3px; transform-origin: left; transform: scaleX(0); }
JavaScript
伪类使圆形线条运动起来,需要修改circle
元素的stroke-dashoffset
值,使它从0变化到105。对于直线,只需要简单的修改transform scaleX
属性,使它从0变为1。
// define animation timeline var tl = new TimelineMax({}); tl.to(circularLinePath, staticAnimProps.duration, { css: { // animation css stroke-dashoffset property // this will yield the circular loading effect "stroke-dashoffset": 105 } }) .to(straightLine, staticAnimProps.duration/2, { // animates the length of the line scaleX: 1, onComplete: function(){ // straight line animation direction changes to the opposite this.target.style.transformOrigin = dynamicAnimProps.direction; // move circular line position to the clicked dot position circularLine.style.left = dynamicAnimProps.circularLinePos + "px"; } }, 0.15) .to(straightLine, staticAnimProps.duration, { // animate the straight line length to zero scaleX: 0 }) .to(circularLinePath, staticAnimProps.duration, { onStart: function(){ // if the animation direction goes to left, flip the circular line (dynamicAnimProps.flipcircular) ? circularLine.className = "" : circularLine.className = "flip"; }, delay: -staticAnimProps.duration, css: { // animate circular line to 0 "stroke-dashoffset": 0 } })
另外还需要判断点击的是当前圆点左边的圆点还是右边的圆点,因为从左向右运动和从右向左运动是不同的,需要分别处理。
// define animation direction // if the selected dot has bigger index, then it's animation direction goes to the right if(getIndex(this, thisArray) > getIndex(activeDot, thisArray)){ dynamicAnimProps.direction = "right"; // get the width between the active dot and the clicked dot dynamicAnimProps.straightLine.width = dynamicAnimProps.newLinePos - dynamicAnimProps.oldLinePos + 2.5; dynamicAnimProps.straightLine.pos = dynamicAnimProps.oldLinePos + 5; dynamicAnimProps.flipcircular = false; dynamicAnimProps.straightLine.origin = "left"; dynamicAnimProps.translateVal = staticAnimProps.translateVal; } else { dynamicAnimProps.direction = "left"; dynamicAnimProps.straightLine.width = -(dynamicAnimProps.newLinePos - dynamicAnimProps.oldLinePos - 2.5); dynamicAnimProps.straightLine.pos = dynamicAnimProps.newLinePos + 5; dynamicAnimProps.flipcircular = true; dynamicAnimProps.straightLine.origin = "right"; dynamicAnimProps.translateVal = -staticAnimProps.translateVal; }
这款HTML5 SVG线条变形动画特效的github地址为:https://github.com/balapa/SVG-Line-Morphing-Transition