CSS 動做路徑標準 Motion Path 簡介

在 CSS 動畫中,咱們日常都會經過 CSS Animation 和 CSS Transform 等實現一些簡單的 CSS 動畫。然而,要想讓動畫對象沿着一條路徑進行移動,仍是有一些難點的。CSS Motion Path 標準的出現,讓開發者可以給動畫對象定義一條動畫路徑,配合 keyframe 等操做,輕鬆實現讓一個物體沿着一條路徑進行動畫。css

Motion Path Level 1 從 2015 年 4 月 9 日發表第一個工做草案以來,通過3年多的時間,發展得已經比較成熟了,同時 Google Chrome、Opera 瀏覽器也是第一批可以支持大部分草案標準功能的瀏覽器。chrome

下面咱們就來了解一下吧。瀏覽器

動做路徑

既然是要讓對象沿着一條路徑走,那麼本標準中最重要的點就在如何定義路徑上了。bash

offset-path

offset-path 即爲定義路徑的屬性,它可以接受 ray()、CSS Shaps 中的圖形 以及可以接受相似 SVG 路徑定義的 path()ide

在 Chrome 中,目前叫 motion-pathpost

ray()

ray()即爲輻射線。它以容器的中心爲圓心,在容器中嵌入一個可以嵌入的最大圓形,結合自定義的夾角,將圓心與邊上的點相連,造成路徑。動畫

ray接受三個參數,分別是角度,大小以及設置是否讓對象徹底包含在路徑內。url

用下面的例子進行一一解釋spa

<style>
    body {
        transform-style: preserve-3d;
        width: 200px;
        height: 200px;
    }
    .box {
        width: 50px;
        height: 50px;
        offset-position: 50% 50%;
        offset-distance: 100%;
        offset-rotate: 0deg;
    }
    #redBox {
        background-color: red;
        offset-path: ray(45deg closest-side);
    }
    #blueBox {
        background-color: blue;
        offset-path: ray(180deg closest-side);
    }
</style>
<body>
    <div class="box" id="redBox"></div>
    <div class="box" id="blueBox"></div>
</body>
複製代碼

角度

即 CSS 中的角度定義,如上圖,45deg 和 90deg 分別造成 45 度和 90 度的夾角。.net

大小

第二個大小參數決定了路徑的長短,它支持如下的屬性

屬性值 含義
closest-side 初始位置到最近一邊的距離
closest-corner 初始位置到最近一角的距離
farthest-side 初始位置到最遠一遍的距離
farthest-corner 初始位置到最遠一角的距離
sides 初始位置到交線的距離
contain

設置對象是否徹底包含在路徑之中

若是上述例子設置了 conatin,兩個 box 將會徹底包含在路徑以內

offset-path: ray(90deg, closest-side, contain)

CSS 圖形

咱們還能利用 CSS 中的形狀來定義動做路徑,CSS 中的形狀咱們已經不陌生了,例如inset() , circle(), ellipse(), polygon(),甚至還能使用盒模型的數值如 margin-box, border-box, padding-box, content-box

下面這個例子使用了 margin-box 的邊做爲動做路徑:

<style>
    body {
        width: 500px;
        height: 300px;
        border-radius: 80px;
        border: dashed aqua;
        margin: 0;
    }
    #blueBox {
        width: 40px;
        height: 20px;
        background-color: blue;
        offset-path: margin-box;
    }
</style>
<body>
    <div id="blueBox"></div>
</body>
複製代碼

path()

path() 能夠接受 SVG 中的幾何描述數據做爲動做路徑

.path {
    offset-path: path('M150 0 L75 200 L225 200 Z');
}
複製代碼

如上代碼使用 SVG 描述一個三角形,那麼這個對象的動做路徑即爲這個三角形,那麼他的初始位置以及初始方向,能夠參考 SVG 相關標準進行設定。

url

url 與 上面的 path() 相同,path() 直接將 SVG 幾何描述內容寫到 CSS 中,url 則能夠直接引用 SVG 文件。

offset-distance

offset-distance 用於設定對象在路徑上的位置。

<style>
    body {
        transform-style: preserve-3d;
        width: 300px;
        height: 300px;
        border: dashed gray;
        border-radius: 50%;
    }
    .circleBox {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 40px;
        height: 40px;
        background-color: red;
        border-radius: 50%;
    }
    #circle1 {
        offset-path: ray(0deg farthest-side);
        offset-distance: 50%;
    }
    #circle2 {
        offset-path: ray(90deg farthest-side);
        offset-distance: 20%;
    }
    #circle3 {
        offset-path: ray(225deg farthest-side);
        offset-distance: 100%;
    }
</style>
<body>
    <div class="circleBox" id="circle1"></div>
    <div class="circleBox" id="circle2"></div>
    <div class="circleBox" id="circle3"></div>
</body>

複製代碼

上面例子中,經過設定三個不一樣的offset-distance設定對應對象在路徑上的位置分別爲 50%, 20%, 100%。

那麼對於 SVG 的幾何圖形,咱們所設定的一些路徑可能沒有閉合,那麼 offset-distance 設定超過 100% 會怎麼樣呢?

<style>
    .item {
        width: 100px;
        height: 40px;
        offset-position: 0% 0%;
        offset-path: path('m 0 0 h 200 v 150');
    }
    #box1 {
        background-color: red;
        offset-distance: -280%;
    }
    #box2 {
        background-color: green;
        offset-distance: 190%;
    }
</style>
<body>
    <div class="item" id="box1"></div>
    <div class="item" id="box2"></div>
</body>
複製代碼

能夠看到,兩個分別設置在 -280% 和 +190% 的位置,最終因爲路徑沒有造成閉合,兩個對象停留在最小和最大的可達位置。

<style>
    .item {
        width: 100px;
        height: 40px;
        offset-position: 0% 0%;
        offset-path: path('m 0 0 h 200 v 150 z');
    }
    #box1 {
        background-color: red;
        offset-distance: -280%;
    }
    #box2 {
        background-color: green;
        offset-distance: 190%;
    }
</style>
<body>
    <div class="item" id="box1"></div>
    <div class="item" id="box2"></div>
</body>
複製代碼

上面的例子則演示了閉合路徑的狀態,兩個對象都可在路徑上「循環」移動。

offset-position

offset-position 指定了路徑自己的初始位置在哪裏,能夠提供屬性值auto或者指定的位置。若是offset-positionauto而且position不爲static,那麼默認的offset-position則爲position的位置。

<style>
    #wrap {
        position: relative;
        width: 300px;
        height: 300px;
        border: 1px solid black;
    }

    #box {
        width: 100px;
        height: 100px;
        background-color: green;
        position: absolute;
        top: 100px;
        left: 80px;
        offset-position: auto;
        offset-anchor: center;
        offset-path: ray(45deg);
    }
</style>
<body>
    <div id="wrap">
        <div id="box"></div>
    </div>
</body>
複製代碼

offset-anchor

須要移動的對象可能不必定得是對象的正中心,咱們想要自定義對象的錨點,則能夠經過offset-anchor來實現。

#plane {
    offset-anchor: center;
}
複製代碼

上面例子指定了對象的錨點在中心位置。

<style>
    body {
        transform-style: preserve-3d;
        width: 300px;
        height: 300px;
        border: 2px solid gray;
        border-radius: 50%;
    }
    .box {
        width: 50px;
        height: 50px;
        background-color: orange;
        offset-position: 50% 50%;
        offset-distance: 100%;
        offset-rotate: 0deg;
    }
    #item1 {
        offset-path: ray(45deg closest-side);
        offset-anchor: right top;
    }
    #item2 {
        offset-path: ray(135deg closest-side);
        offset-anchor: right bottom;
    }
    #item3 {
        offset-path: ray(225deg closest-side);
        offset-anchor: left bottom;
    }
    #item4 {
        offset-path: ray(315deg closest-side);
        offset-anchor: left top;
    }
</style>
<body>
    <div class="box" id="item1"></div>
    <div class="box" id="item2"></div>
    <div class="box" id="item3"></div>
    <div class="box" id="item4"></div>
</body>
複製代碼

上面例子中指定了四個矩形的四個不一樣的錨點位置。

若是 offset-anchor 的屬性值爲 auto,有以下規則進行計算:

條件 結果
offset-path: none;
offset-position: 非 auto;
取 offset-position 的值
offset-anchor: auto;
offset-path: none;
與 background-position 行爲相同
若是上述都不符合 取 transform-origin 的值
<style>
    body {
        width: 500px;
        height: 500px;
    }
    .box {
        background-color: mediumpurple;
        offset-path: none;
        offset-anchor: auto;
    }
    #item1 {
        offset-position: 90% 20%;
        width: 60%;
        height: 20%;
    }
    #item2 {
        offset-position: 100% 100%;
        width: 30%;
        height: 10%;
    }
    #item3 {
        offset-position: 50% 100%;
        width: 20%;
        height: 60%;
    }
    #item4 {
        offset-position: 0% 100%;
        width: 30%;
        height: 90%;
    }
</style>
<body>
    <div class="box" id="item1"></div>
    <div class="box" id="item2"></div>
    <div class="box" id="item3"></div>
    <div class="box" id="item4"></div>
</body>
複製代碼

上面例子展現了,offset-anchorauto 時,錨點的位置計算結果。

offset-rotate

offset-rotate 指定了對象的旋轉角度或是如何自動旋轉。

屬性值 效果
auto 對象根據當前路徑的朝向進行旋轉
若是對 offset-distance 進行動畫,對象也會隨着當前點的朝向進行旋轉
reverse 與 auto 效果相同,但與朝向相反
自定義角度 對象始終朝着一個方向旋轉

當屬性值爲 auto 時,隨着 offset-distance 的改變,角度也會自動改變

當屬性值爲 reverse時,角度與朝向相反

當屬性值爲 -45deg 時,角度始終不變

在線演示

參考資料

相關文章
相關標籤/搜索