Как анимировать несколько путей SVG в круговой / кольцевой диаграмме в последовательности с помощью SMIL / CSS - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть группа svg, которая содержит серию путей, представляющих различные области круговой диаграммы. Эти пути представлены круговым тегом, и график отображается в виде кольцевой диаграммы.

<svg width="71" height="70" xmlns="http://www.w3.org/2000/svg">
    <g class="graph-arc" transform="translate(1,1)">
        <path stroke="#3f88c5" fill="#3f88c5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(225, 34.5, 34.5)"></path>
        <path stroke="#3f88c5" fill="#3f88c5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(238.5, 34.5, 34.5)"></path>
        <path stroke="#3A8DC3" fill="#3A8DC3" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(252, 34.5, 34.5)"></path>
        <path stroke="#3593BF" fill="#3593BF" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(265.5, 34.5, 34.5)"></path>
        <path stroke="#3398BE" fill="#3398BE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(279, 34.5, 34.5)"></path>
        <path stroke="#3398BE" fill="#3398BE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(292.5, 34.5, 34.5)"></path>
        <path stroke="#359DBB" fill="#359DBB" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(306, 34.5, 34.5)"></path>
        <path stroke="#36A3B9" fill="#36A3B9" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(319.5, 34.5, 34.5)"></path>
        <path stroke="#36A3B9" fill="#36A3B9" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(333, 34.5, 34.5)"></path>
        <path stroke="#38A8B6" fill="#38A8B6" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(346.5, 34.5, 34.5)"></path>
        <path stroke="#39ADB4" fill="#39ADB4" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(360, 34.5, 34.5)"></path>
        <path stroke="#39ADB4" fill="#39ADB4" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(373.5, 34.5, 34.5)"></path>
        <path stroke="#3BB3B2" fill="#3BB3B2" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(387, 34.5, 34.5)"></path>
        <path stroke="#3DB8AE" fill="#3DB8AE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(400.5, 34.5, 34.5)"></path>
        <path stroke="#3DB8AE" fill="#3DB8AE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(414, 34.5, 34.5)"></path>
        <path stroke="#3EBDAD" fill="#3EBDAD" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(427.5, 34.5, 34.5)"></path>
        <path stroke="#40C3AA" fill="#40C3AA" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(441, 34.5, 34.5)"></path>
        <path stroke="#40C3AA" fill="#40C3AA" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(454.5, 34.5, 34.5)"></path>
        <path stroke="#00c8a8" fill="#00c8a8" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(468, 34.5, 34.5)"></path>
        <path stroke="#00c8a8" fill="#00c8a8" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55386505302874, 0.9532377462801749 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(481.5, 34.5, 34.5)"></path>
        <path stroke="#e5e5e5" fill="#e5e5e5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 34.5, 0 z" xmlns="http://www.w3.org/2000/svg" transform="rotate(495, 34.5, 34.5)"></path>
    </g>
    <circle r="25.875" cx="35.5" cy="35.5" fill="#fff"></circle> . 
</svg>

Мне бы хотелось, чтобы общий эффект был таким: https://codepen.io/seanstopnik/pen/GqHng

Есть много примеров использования stroke-dasharray для линий, но я неудалось найти что-нибудь для анимации нескольких путей!Каков наилучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

У вас нет анимации, как в обычном методе.Так что вы можете превратить анимированную линию в маску.Затем примените эту маску к более сложной форме.

#progress circle {
  animation: do-progress 4s infinite;
}

@keyframes do-progress {
    0% { stroke-dashoffset: 0px; }
   50% { stroke-dashoffset: -146px; }
  100% { stroke-dashoffset: 0px; }
}
<svg width="71" height="70" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <mask id="progress" maskUnits="userSpaceOnUse">
            <rect x="-1" y="-1" width="100%" height="100%" fill="#fff"/>
            <circle r="30.5" cx="34.5" cy="34.5" fill="none" stroke="#000" stroke-width="10" stroke-dasharray="146 192" transform="rotate(-227, 34.5, 34.5)"/>
        </mask>
    </defs>
    <g class="graph-arc" transform="translate(1,1)" mask="url(#progress)">
        <path stroke="#3f88c5" fill="#3f88c5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(225, 34.5, 34.5)"/>
        <path stroke="#3f88c5" fill="#3f88c5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(238.5, 34.5, 34.5)"/>
        <path stroke="#3A8DC3" fill="#3A8DC3" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(252, 34.5, 34.5)"/>
        <path stroke="#3593BF" fill="#3593BF" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55 0.95 z" transform="rotate(265.5, 34.5, 34.5)"/>
        <path stroke="#3398BE" fill="#3398BE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(279, 34.5, 34.5)"/>
        <path stroke="#3398BE" fill="#3398BE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(292.5, 34.5, 34.5)"/>
        <path stroke="#359DBB" fill="#359DBB" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(306, 34.5, 34.5)"/>
        <path stroke="#36A3B9" fill="#36A3B9" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(319.5, 34.5, 34.5)"/>
        <path stroke="#36A3B9" fill="#36A3B9" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(333, 34.5, 34.5)"/>
        <path stroke="#38A8B6" fill="#38A8B6" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(346.5, 34.5, 34.5)"/>
        <path stroke="#39ADB4" fill="#39ADB4" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(360, 34.5, 34.5)"/>
        <path stroke="#39ADB4" fill="#39ADB4" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(373.5, 34.5, 34.5)"/>
        <path stroke="#3BB3B2" fill="#3BB3B2" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(387, 34.5, 34.5)"/>
        <path stroke="#3DB8AE" fill="#3DB8AE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(400.5, 34.5, 34.5)"/>
        <path stroke="#3DB8AE" fill="#3DB8AE" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(414, 34.5, 34.5)"/>
        <path stroke="#3EBDAD" fill="#3EBDAD" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(427.5, 34.5, 34.5)"/>
        <path stroke="#40C3AA" fill="#40C3AA" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(441, 34.5, 34.5)"/>
        <path stroke="#40C3AA" fill="#40C3AA" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(454.5, 34.5, 34.5)"/>
        <path stroke="#00c8a8" fill="#00c8a8" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(468, 34.5, 34.5)"/>
        <path stroke="#00c8a8" fill="#00c8a8" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 42.55, 0.95 z" transform="rotate(481.5, 34.5, 34.5)"/>
        <path stroke="#e5e5e5" fill="#e5e5e5" d="M 34.5,34.5 L34.5,0 A34.5,34.5 0 0,1 34.5, 0 z" transform="rotate(495, 34.5, 34.5)"/>
    </g>
    <circle r="25.875" cx="35.5" cy="35.5" fill="#fff"/>
</svg>
0 голосов
/ 12 февраля 2019

Как прокомментировал Temani Afif, использование нескольких путей не является хорошим способом.Вот как я бы это сделал:

Чтобы вычислить длину пути (155,53), я использовал JS & метод getTotalLength.Я рассчитал путь как дугу с радиусом 33 единицы, начиная с 3*Math.PI/4 и заканчивая Math.PI/4.

Анимация происходит при наведении мыши на .

svg{border:1px solid;width:90vh}

#thePath{
  stroke-dasharray : 155.53px;
  stroke-dashoffset : 155.53px;
  transition: stroke-dashoffset .5s;
}

svg:hover #thePath{
  stroke-dashoffset : 0px;
}
<svg viewBox ="0 0 71 70" id="svg">
<defs>
  <linearGradient id="lg">
   <stop offset="0%" stop-color="#3f88c5"></stop>
   <stop offset="100%" stop-color="#00c8a8"></stop>
  </linearGradient>
 </defs>
  
  <path id="thePath" d="M12.165476220843935,58.33452377915607A33,33,0 1 1 58.834523779156065,58.334523779156065" fill="none" stroke="url(#lg)" stroke-width="4" />
</svg>

И вот код, в котором я использую JS для вычисления всего этого:

let R = 33;// the radius of the arc for the path
// the starting point of the path
let x = 35.5 + R * Math.cos(3 * Math.PI / 4);
let y = 35 + R * Math.sin(3 * Math.PI / 4);
// the end point of the path
let _x = 35.5 + R * Math.sin(Math.PI / 4);
let _y = 35 + R * Math.sin(Math.PI / 4);
// the value of the d attribute of the path
let d = `M${x},${y}A${R},${R},0 1 1 ${_x},${_y}`;
thePath.setAttributeNS(null, "d", d);

let pathLength = thePath.getTotalLength();

thePath.setAttribute(
  "style",
  `stroke-dasharray : ${pathLength}px; stroke-dashoffset : ${pathLength}px;`
);
svg{border:1px solid;width:90vh;}

#thePath{ 
  transition: stroke-dashoffset .5s;
}

svg:hover #thePath{
  stroke-dashoffset : 0px!important;
}
<svg viewBox ="0 0 71 70" id="svg">
<defs>
  <linearGradient id="lg">
   <stop offset="0%" stop-color="#3f88c5"></stop>
   <stop offset="100%" stop-color="#00c8a8"></stop>
  </linearGradient>
 </defs>
  
  <path id="thePath" fill="none" stroke="url(#lg)" stroke-width="4" />
</svg>
...