這篇文章主要介紹了svg path在網(wǎng)頁開發(fā)中如何使用,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)長期為上千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為龍沙企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設計,龍沙網(wǎng)站改版等技術服務。擁有十多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。SVG是矢量圖形表示,它的一個強大之處在于path標簽可以表示任意的矢量形狀,利用好這個path可以做出很多傳統(tǒng)html/css做不出來的效果。下面舉幾個例子。
1. 做路徑動畫
這個我在《SVG導航下劃線光標跟隨效果》文后補充介紹了這個實現(xiàn),最后的效果是這樣的:
實現(xiàn)代碼如下:
利用animateMotion結合path做的動畫,具體說明可見上文。
2. 實現(xiàn)不規(guī)則形狀的點擊
如下圖所示,需要實現(xiàn)點到哪個洲就進入哪個洲的效果,例如點到非洲就進入非洲:
我們可以用div定一個框蓋在非洲的上面,但是用div的話只能是規(guī)則的四方形,沒辦法實現(xiàn)點到非洲大陸的時候才進入,但是大陸的輪廓又是不規(guī)則的,所以用傳統(tǒng)html是不能解決這個問題的。但是用SVG的path可以解決這個問題,方法1是監(jiān)聽path的點擊事件即可,如下圖所示:
因為這個輪廓可以跟UI要到,他們一般都是用AI/PS等矢量軟件畫出來的,讓他們導一個SVG給你就好了。
方法2是可以調SVG的isPointInFill這個API判斷點擊的點是否在Path的fill區(qū)域里面,這個也可以實現(xiàn),但是相對于方法1來說比較麻煩,因為還需要把鼠標的位置轉換為svg視圖的位置。
3. 沿著路徑拖拽的交互
在第1點沿著路徑的動畫是自動的過程,有沒有辦法讓用戶自己拖拽過去呢,實現(xiàn)如下效果:
這種的場景有音量控制等需要有百分比控制的。可以先用一個SVG的在線工具畫出一個這樣的圖形:
就可以拿到SVG的代碼:
<svg class="volumn-controller" width="580" height="400" xmlns="http://www.w3.org/2000/svg"> <path class="volumn-path" stroke="#000" d="m100,247c93,-128 284,-129 388,6" opacity="0.5" stroke-width="1" fill="#fff"/> <circle class="drag-button" r="12" cy="247" cx="100" stroke-width="1" stroke="#000" fill="#fff"/> </g> </svg>
這里比較關鍵的是path標簽里的d屬性,d是data的縮寫,定義這個路徑的形狀,它里面可以用很多屬性控制形狀的變化,如下圖所示:
為了實現(xiàn)這個交互,需要動態(tài)地改變circle的圓心位置(cx, cy)到路徑上相應的地方。SVG沒有直接提供相關的API,但是它提供了一個可以間接利用的API叫getPointAtLength,傳遞一個長度參數(shù),如下代碼所示:
let volumnPath = document.querySelector('.volumn-path'); // 輸出path在長度為100的位置的點坐標 console.log(volumnPath.getPointAtLength(100)); // 輸出當前path的總長度 console.log(volumnPath.getTotalLength());
控制臺輸出:
把circle的cx/cy改成上面的x/y坐標,圓圈就會跑到對應的位置去了:
這里的問題在于這個API傳遞的length參數(shù)是相對于曲線長度的,但是鼠標移動的位置是線性的,沒辦法直接知道當前鼠標在曲線上距離起始位置多少。
所以需要算一下,在這個場景里面我們可以取鼠標的x坐標在曲線上對應的位置就可以了,如下圖示意:
到這里就有思路了,可以把這條路徑上每隔一個像素長度就算一下它的坐標在哪里,然后存在一個數(shù)組里面。由于鼠標移動的時候x坐標是知道的,就可以查一下在這個數(shù)組里面相應x坐標的y坐標是多少,就能得到想要的圓心位置了。
所以先計算一下,保存到一個數(shù)組:
let $volumnController = document.querySelector('.volumn-controller'), $volumnPath = $volumnController.querySelector('.volumn-path'); // 得到當前路徑的總長度 let pathTotalLength = $volumnPath.getTotalLength() >> 0; let points = []; // 起始位置為長度為0的位置 let startX = Math.round($volumnPath.getPointAtLength(0).x); // 每隔一個像素距離就保存一下路徑上點的坐標 for (let i = 0; i < pathTotalLength; i++) { let p = $volumnPath.getPointAtLength(i); // 保存的坐標用四舍五入,可以平衡誤差 points[Math.round(p.x) - startX] = Math.round(p.y); }
這里用一個p0ints數(shù)組來保存,它的索引index就為x坐標,值為y坐標。在這個例子里面,總長度為451.5px,得到的points數(shù)組長度為388. 你可以隔0.5px長度就保存一個坐標,不過在這個例子里面1px就夠了。
然后監(jiān)聽鼠標事件,得到x坐標,查詢y坐標,動態(tài)地改變circle的圓心位置,如下代碼所示:
let $dragButton = $volumnController.querySelector('.drag-button'), // 得到起始位置相對當前視窗的位置,相當于jQuery.fn.offset dragButtonPos = $dragButton.getBoundingClientRect(); function movePoint (event) { // 當前鼠標的位置減去圓心起始位置就得到移位偏差,12是半徑值,這里先直接寫死 let diffX = event.clientX - Math.round(dragButtonPos.left + 12); // 需要做個邊界判斷 diffX < 0 && (diffX = 0); diffX >= points.length && (diffX = points.length - 1); // startX是在上面的代碼得到的長度為0的位置 $dragButton.setAttribute('cx', diffX + startX); // 使用points數(shù)組得到y(tǒng)坐標 $dragButton.setAttribute('cy', points[diffX]); } $dragButton.addEventListener('mousedown', function (event) { document.addEventListener('mousemove', movePoint); }); document.addEventListener('mouseup', function () { document.removeEventListener('mousemove', movePoint); });
這個實現(xiàn)的代碼也是比較簡單,需要注意的地方是起始位置的選取,這里有兩個坐標系,一個是相對頁面的視窗的,它的原點(0, 0)坐標點是當前頁面可視區(qū)域(client)的左上角,第二個坐標系是SVG的坐標系,它的原點(0, 0)位置是SVG畫布的左上角,如下圖所示:
鼠標的位置是相對于視圖client的,所以需要得到圓圈在client的位置,可以通過原生的getBoundingClient獲取,然后用鼠標的clientX減掉圓圈的clientX就得到正確的位移偏差diff了,這個diff值加上圓圏的在svg坐標的起始位置就能得到svg里的x坐標了,然后去查一下points數(shù)組就能得到y(tǒng)坐標,然后去設置circle的cx/cy值。
這個的實現(xiàn)已經(jīng)算是十分簡單的,大概30行代碼。需要注意的是如果svg縮放了,那么坐標也要相應比例地改一下。所以最好是不要縮放,1:1顯示就簡單多了。
如果要顯示具體的音量值呢?這個也好辦,只需要在第一步保存點坐標的時候把在路徑上的長度也保存下來就好了,最后效果如下:
如果路徑比較復雜怎么辦呢,一個x坐標可能會對應兩個點,如下圖所示:
這個也是有辦法的,計算的方法類似,也是需要把路徑上所有每隔1px的點坐標都取出來,然后計算一下鼠標的位置距離哪個點的坐標最接近,然后就取那個點就好了。當然在判斷哪個點最優(yōu)時,算法需要優(yōu)化,不能直接一個for循環(huán),具體可見這個codepen。
4. 路徑的變形動畫
路徑結合關鍵幀可以做出一些有趣的效果,如這個codepen的示例:
它的實現(xiàn)是hover的時候改變path的d值,然后做d的transition動畫,如下代碼:
<svg viewBox="0 0 10 10" class="svg-1"> <path d="M2,2 L8,8" /> </svg> <style> .svg-1:hover path { d: path("M8,2 L2,8"); } path { transition: d 0.5s linear; } </style>
這種變形過渡動畫是有條件的,就是它的路徑數(shù)據(jù)格式是要一致的,有多少個M/L/C屬性都要保持一致,否則無法做變形動畫。
5. 結合clip-path做遮罩效果
使用CSS通常只能用border-radius做一些圓角的遮罩,即用border-radius結合overflow: hidden實現(xiàn),但是使用clip-path + svg的路徑能夠做出任意形狀遮罩,如下做一個心形的:
如下代碼所示:
<div style="width:200px;height:200px"> <img src="photo.png" alt style="width:100%"> </div> <style> img { clip-path: url("#heart"); } </style>
style里面的id: #heart是指向了一個SVG的的clipPath,如下所示:
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0"> <clipPath id="heart" clipPathUnits="objectBoundingBox"> <path transform="scale(0.0081967, 0.0101010)" d="m61.18795,24.08746c24.91828,-57.29309 122.5489,0 0,73.66254c-122.5489,-73.66254 -24.91828,-130.95562 0,-73.66254z"/> </clipPath> </svg>
為了讓這個path剛好能撐起div容器寬度的100%,需要設置:
clipPathUnits="objectBoundingBox"
這樣會導致d屬性里面的單位變成比例的0到1,所以需要把它縮小一下,原本的width是122,height是99,需要需要scale的值為(1 / 122, 1 / 99)。這樣就達到100%占滿的目的,如果一開始d屬性坐標比例就是0到1,就不用這么搞了。
另外clip-path使用svg的path不支持變形動畫。
感謝你能夠認真閱讀完這篇文章,希望小編分享svg path在網(wǎng)頁開發(fā)中如何使用內容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設計公司,關注創(chuàng)新互聯(lián)成都網(wǎng)站設計公司行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián)成都網(wǎng)站設計公司,詳細的解決方法等著你來學習!
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、網(wǎng)站設計器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
網(wǎng)站題目:svgpath在網(wǎng)頁開發(fā)中如何使用-創(chuàng)新互聯(lián)
標題鏈接:http://vcdvsql.cn/article34/cedhpe.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、品牌網(wǎng)站設計、手機網(wǎng)站建設、網(wǎng)站維護、建站公司、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內容