昨天晚上索契冬奧會開幕,開幕式上還出現了五環變四環的烏龍,哈哈。我們用SVG弄個五環動畫加以彌補。
先來看看效果,效果如所示。根據大家留言的意見進行了修正,見效果。
好的,Let‘s do it.
<svg width="550px" height="300px" class="circle" viewbox="0 0 550 300"> <path class="blue" d="M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/> <path class="green" d="M 365, 175 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/> <path class="black" d="M 275, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/> <path class="red" d="M 450, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/> <path class="yellow" d="M 187.5, 175 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/></svg>
然後是CSS,我們用到了LESS
//顏色變數@blue : #0885C2;@red : #ED334C;@yellow : #FBB132;@green : #1C8b3C;@black : #292B2A;//動畫期間動畫@duration : 3s;//設定svg置中顯示html, body { height: 100%; }body { display: flex; justify-content: center; align-items: center; background: whitesmoke; margin: 0 1rem;}svg { maxwidth: 100%; height: auto; background: white; box-shadow: 0 1px 4px gainsboro; border-radius: .5rem;}//定義svg五環的繪製屬性和動畫效果 path { fill: transparent; stroke: rgba(0,0,0,.4); stroke-width: 12; stroke-dasharray: 465; stroke-linecap: round; stroke-linejoin: round; -webkit-animation: load @duration linear infinite; animation: load @duration linear infinite; transform-origin: center center;}//動畫主要畫面格@keyframes load { from{stroke-dashoffset:480; } to { stroke-dashoffset: 0; } }//五環的顏色//旋轉環以類比實現非同步效果.blue { stroke: @blue; transform: rotate(210deg)}.black { stroke: @black; transform: rotate(-20deg)}.red { stroke: @red; transform: rotate(-55deg)}.yellow { stroke: @yellow; transform: rotate(40deg)}.green { stroke: @green;}
好了,整個效果就是這樣。大家可以到我的codepen線上修改、體驗,或是下載收藏本效果。
------------------------------------------------------------------------------------------------------------------------
華麗的分分分分分分割線
------------------------------------------------------------------------------------------------------------------------
根據大家的意見進行了修正,參照Brian Suda的svg path animation最佳化了動畫操作,做法解析如下。
html部分增加了重播的按鈕和每條path的id控制
<button onclick="rerun();">Again!</button><svg id="mySvg" version="1.1" viewBox="0 0 550 300"><path id="i0" class="blue" d="M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/><path id="i1" class="green" d="M 365, 175 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0"/><path id="i2" class="black" d="M 275, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 "/><path id="i3" class="red" d="M 450, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0"/><path id="i4" class="yellow" d="M 187.5, 175 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0"/></svg>
css部分改變不大,去掉了動畫部分。
button { position: absolute; top: 10px; right: 5px;}path { fill: transparent; stroke-width: 12; stroke-linecap: round; stroke-linejoin: round;}.blue { stroke: #0885C2;}.black { stroke: #292B2A;}.red { stroke: #ED334C;}.yellow { stroke: #FBB132;}.green { stroke: #1C8b3C}
最重要的是進入了js最佳化動畫效果。
var current_frame, total_frames, path, length, handle, myobj;var mysvg=document.getElementById('mySvg');var init = function() { current_frame = 0; total_frames = 60; path = new Array(); length = new Array(); for(var i=0; i<5;i++){ path[i] = document.getElementById('i'+i); l = path[i].getTotalLength(); length[i] = l; path[i].style.strokeDasharray = l + ' ' + l; path[i].style.strokeDashoffset = l; } handle = 0;} var draw = function() { var progress = current_frame/total_frames; if (progress > 1) { window.cancelAnimationFrame(handle); } else { current_frame++; for(var j=0; j<path.length;j++){ path[j].style.strokeDashoffset = Math.floor(length[j] * (1 - progress)); } handle = window.requestAnimationFrame(draw); }};init();draw();var rerun = function() { var old = document.getElementById('mySvg'); old.parentNode.removeChild(old); document.getElementsByTagName('body')[0].appendChild(mysvg); init(); draw();};
That's it. 大家可以到我的codepen線上修改、體驗改進後的效果,或是下載收藏本效果。
---------------------------------------------------------------
前端開發whqet,關注web前端開發技術,分享網頁相關資源。
---------------------------------------------------------------