CSS3和SVG实现的圆环菜单动画

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS3和SVG实现的圆环菜单动画</title>

<style type="text/css">
    body, html { font-size: 100%;   padding: 0; margin: 0;}

/* Reset */
*,
*:after,
*:before {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

/* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */
.clearfix:before,
.clearfix:after {
    content: " ";
    display: table;
}

.clearfix:after {
    clear: both;
}

body{
    font-family: "Microsoft YaHei","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif;
}
</style>
<link href="https://fonts.googleapis.com/css?family=Poppins:200,400" rel="stylesheet">

<style type="text/css">

</style>

</head>
<body>

<div class="main">
  <div class="navigation-circle">
    <div class="navigation-circle__inner">
      <svg class="navigation-circle-svg navigation-circle-svg--opaque" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewbox="0 0 320 320" style="enable-background:new 0 0 320 320;">
        <circle cx="160" cy="160" r="158" fill="none" stroke-width="1" stroke="#c644fc" stroke-linecap="round" stroke-miterlimit="10" style="stroke-dashoffset:0;stroke-dasharray:none;"></circle>
      </svg>
      <svg class="navigation-circle-svg navigation-circle-svg--mask" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewbox="0 0 320 320" style="enable-background:new 0 0 320 320;">
        <circle id="mask-circle" cx="160" cy="160" r="158" fill="none" stroke-width="2" stroke="#c644fc" stroke-linecap="round" stroke-miterlimit="10" style="stroke-dasharray:1005.3088px;"></circle>
      </svg>
      <ul class="navigation-circle__list">
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(1)" onmouseenter="calculateOffset(1)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #1
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(2)" onmouseenter="calculateOffset(2)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #2
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(3)" onmouseenter="calculateOffset(3)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #3
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(4)" onmouseenter="calculateOffset(4)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #4
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(5)" onmouseenter="calculateOffset(5)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #5
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(6)" onmouseenter="calculateOffset(6)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #6
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
        <li class="navigation-circle-list-item"><a class="navigation-circle-list-item__point" onClick="onClick(7)" onmouseenter="calculateOffset(7)" onMouseLeave="onMouseLeave()">
            <div class="navigation-circle-list-item__meta">
              <h3 class="navigation-circle-list-item__title">Item #7
              </h3>
              <h4 class="navigation-circle-list-item__subtitle">It just goes round and round</h4>
            </div></a></li>
      </ul>
    </div>
  </div>
</div>

<script>
    const pointCount = 7;
const circleRadius = 160;
const startAnimDelta = 5;
const circumference = Math.PI * circleRadius * 2;

var selectedItemIndex = -1;

var circlePath = document.getElementById('mask-circle');

/**
 * @description On Mouse Leave event handler for points
 */
const onMouseLeave = () => {
    let index = (selectedItemIndex !== -1) ? selectedItemIndex : 0;
    calculateOffset(index);
};

/**
 * @description On Click event handler for points
 * @param {Number} index - Index of list item
 */
const onClick = (index) => {
    //If already selected, deselect
    selectedItemIndex = (selectedItemIndex === index) ? -1 : index;
    calculateOffset(index);
    
    //Find active item, deselect
    let activeListItem = document.querySelectorAll('.navigation-circle-list-item.active');
    if (activeListItem.length > 0) activeListItem[0].classList.remove('active');
    
    //Find new item by index, select
    let listItem = document.querySelectorAll('.navigation-circle-list-item:nth-of-type(' + selectedItemIndex + ')');
    if (listItem.length > 0) listItem[0].classList.add('active');
};

/**
 * @description - Calculate offset for circle path by index of list item
 * @param {Number} index - Index of list item
 */
const calculateOffset = (index=0) => {
    let offset = 0;

    if (index !== 0) offset = (circumference / pointCount) * (pointCount - index);
    
    circlePath.style.strokeDashoffset = `${offset}px`;
};

// INTRO

let buffer = 500;
let delay = 1000 * (1 + (pointCount / startAnimDelta) - (1 / startAnimDelta)) + buffer;

setTimeout(() => onClick(1), delay);
</script>

</body>
</html>


CSS3和SVG实现的圆环菜单动画

评论者:[[ schemeInfo.user.username ]]

评论内容:[[ schemeInfo.pbody ]]

评论时间:[[ schemeInfo.ptime ]]





发表你的评论:

提交评论
上一篇:
下一篇: