SVG 帶有過渡效果的按鈕

風的王子發表於2015-04-20

SVG圖形動畫變形效果原理及展示

圖形動畫變形過程需要兩個SVG圖形實現,需要有相同個數的點數(point屬性中的座標個數),如下:
你可以使用免費的SVG工具來實現你需要的SVG圖形,例如:inkscape

        <!-- 初始圖形:一個五角星 -->
        <svg viewBox="0 0 200 200">
            <!-- 多邊形定義:這裡是一個五角星的圖形 -->
            <polygon fill="#dd4814" points="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9">
                <!-- 新增動畫效果 -->
                <!-- 有一個問題:動畫最後圖形沒有保持住,自動復原到了五角星 -->
                <animate attributeName="points" dur="1200ms" fill="freeze" to="110,58.2 147.3,0 192.1,29 141.7,105.1 118.7,139.8 88.8,185.1 46.1,156.5 0,125 23.5,86.6 71.1,116.7" />
                <!-- 小提示:兩個圖形的point個數應該是一樣的,否則會有問題!切記! -->
                <!-- 這裡新增顏色變形效果:方法類似上面 -->
                <animate attributeName="fill" dur="1200ms" fill="freeze" to="#53B848" />
            </polygon>
        </svg>

javascrip 啟動效果

/*現在呼叫JS來啟動動畫*/

//取得頁面定義的元素id="toCheck" 和 id = "toGreen"
var tocheck = document.getElementById("toCheck"),
      togreen = document.getElementById("toGreen");

      //呼叫SVG的啟動方法
      tocheck.beginElement(); //變形
      togreen.beginElement(); //變色
<!-- 初始圖形:一個五角星 -->
        <svg viewBox="0 0 200 200">
            <!-- 多邊形定義:這裡是一個五角星的圖形 -->
            <polygon fill="#dd4814" points="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9">
                <animate id="toCheck" attributeName="points" dur="1200ms" fill="freeze" begin="indefinite" to="110,58.2 147.3,0 192.1,29 141.7,105.1 118.7,139.8 88.8,185.1 46.1,156.5 0,125 23.5,86.6 71.1,116.7" />

                <animate id="toGreen" attributeName="fill" dur="1200ms" fill="freeze" begin="indefinite" to="#53B848" />
            </polygon>
        </svg>
<script type="text/javascript" src="../js/demo4.js" ></script>

新增恢復上個動畫

var tocheck = document.getElementById("toCheck"),
      togreen = document.getElementById("toGreen");

      tocheck.beginElement();
      togreen.beginElement();


//這裡定義一個恢復方法,類似上面
var tostar = document.getElementById("toStar"),
      tored = document.getElementById("toRed");

function restoreTransform(){
  tostar.beginElement();
  tored.beginElement();
}

//這裡我們延遲2000ms來執行變形恢復方法,如下:

setTimeout(restoreTransform, 2000); //大家可以在課程結束自己除錯程式碼試試
<svg viewBox="0 0 200 200">

            <polygon fill="#dd4814" points="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9">

                <animate id="toCheck" attributeName="points" dur="1200ms" fill="freeze" begin="indefinite" to="110,58.2 147.3,0 192.1,29 141.7,105.1 118.7,139.8 88.8,185.1 46.1,156.5 0,125 23.5,86.6 71.1,116.7" />

                <animate id="toStar" attributeName="points" dur="1200ms" fill="freeze" begin="indefinite" to="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9" />

                <animate id="toGreen" attributeName="fill" dur="1200ms" fill="freeze" begin="indefinite" to="#53B848" />

                <animate id="toRed" attributeName="fill" dur="1200ms" fill="freeze" begin="indefinite" to="#dd4814" />

            </polygon>

        </svg>
        <script type="text/javascript" src="../js/demo4.js" ></script>

示例

參考https://css-tricks.com/svg-shape-morphing-works/

/*CSS程式碼片段*/
body{
  background: #CFCFCF;
}

/* 定義按鈕CSS */

button{
  border: 0;
  background: linear-gradient(
    to bottom,
    #555,
    #111
  );
  border-radius: 10px;
  padding: 10px 30px 12px;
  display: inline-block;
  width: 230px;
  text-align:left;
}

/* 定義按鈕懸浮效果 */
button:hover, button:active {
  background: black;
}

/* 定義SVG圖形CSS*/
button svg{
  width: 45px;
  height: 45px;
  display: inline-block;
  vertical-align: middle;
  margin-right: 10px;
}

/* 定義按鈕文字 */
button span{
  font-size: 32px;
  position:relative;
  top: 7px;
  color: #fff;
  font-family: "microsoft yahei",Arial,sans-serif;
}

/* 元素居中效果CSS */
.center{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* 定義一個已收藏的文字顏色 */
button.saved span{
  color: #53B848;
}
/*處理動畫效果JS*/

/* 定義按鈕文字和四個動畫狀態變數 */

var buttonText = document.getElementById("btn-text"),
  tocheck = document.getElementById("toCheck"),
  togreen = document.getElementById("toGreen"),
  tostar = document.getElementById("toStar"),
  tored = document.getElementById("toRed"),
  button = document.getElementById("button");

//新增按鈕事件

button.addEventListener('click', function(){
  //這裡通過新增一個class定義來判斷是否點選
  if(button.classList.contains('saved')){
    tostar.beginElement();
    tored.beginElement();
    button.classList.remove('saved');
    buttonText.innerHTML = '收藏';
  }else{
    tocheck.beginElement();
    togreen.beginElement();
    button.classList.add('saved');
    buttonText.innerHTML = '已收藏';
  }


}, false);

<!-- 生成一個頁面按鈕 -->

        <button id="button" class="center">

            <!-- 新增SVG圖形生成按鈕圖示:這裡使用上節課的SVG程式碼  -->
            <svg viewBox="0 0 200 200">

                <polygon fill="#dd4814" points="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9">

                    <animate id="toCheck" begin="indefinite" attributeName="points" dur="1200ms" fill="freeze" to="110,58.2 147.3,0 192.1,29 141.7,105.1 118.7,139.8 88.8,185.1 46.1,156.5 0,125 23.5,86.6 71.1,116.7" />

                    <animate id="toStar" begin="indefinite" attributeName="points" dur="1200ms" fill="freeze" to="97.3,0 127.4,60.9 194.6,70.7 145.9,118.1 157.4,185.1 97.3,153.5 37.2,185.1 48.6,118.1 0,70.7 67.2,60.9" />

                    <!-- 這裡新增顏色變形效果:方法類似上面 -->
                    <animate id="toGreen" begin="indefinite" attributeName="fill" dur="1200ms" fill="freeze" to="#53B848" />

                    <animate id="toRed" begin="indefinite" attributeName="fill" dur="1200ms" fill="freeze" to="#dd4814" />
                </polygon>

            </svg>

            <span id="btn-text">收藏</span>

        </button>
        <script type="text/javascript" src="../js/demo5.js"></script>

相關文章