У меня есть svg изображение буквы А
которая составлена из трех элементов:
двух параллелограммов и прямоугольника - перекладины.
Необходимо сделать последовательную анимацию появления сначала левой наклонной части буквы, затем правой части и в конце анимации появление перекладины.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" height="600" width="800" viewBox="0 0 600 800">
<g fill="#008080">
<polygon id="right"
points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
<polygon id="left" points="34 537,150 536,289 130,314 53,196 51"/>
<rect id="rect1" x="120" y="320" stroke-miterlimit="10" width="270" height="120"/>
</g>
</svg>
Вот вариант, где opacity
считается по дельта времени между кадрами.
let left = document.querySelector('#left')
let right = document.querySelector('#right')
let rect1 = document.querySelector('#rect1')
let time = 3000; // время анимации
let delay = 1000; // задержка перед анимацией
// dt - кол-во миллисекунд с начала анимации
function animate(dt) {
let v = dt - delay;
opacity(left, v/time*3);
opacity(right, v/time*3 - 1);
opacity(rect1, v/time*3 - 2);
dt < time + delay + 50 && requestAnimationFrame(animate)
}
function opacity(el, v) {
v = Math.min(1, Math.max(v, 0)); // приводим к диапазону 0-1
el.setAttribute('opacity', v)
}
requestAnimationFrame(animate);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" height="175" viewBox="0 0 600 800">
<g fill="#008080">
<polygon id="right" opacity="0" points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
<polygon id="left" opacity="0" points="34 537,150 536,289 130,314 53,196 51"/>
<rect id="rect1" opacity="0" x="120" y="320" stroke-miterlimit="10" width="270" height="120"/>
</g>
</svg>
Вот такой вот эффект c background-image
и keyframes
.
Для этого группа фигур из оригинала была переделана в маску для прямоугольника.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 800">
<style>
svg {
height:160px;
background: url(https://i.imgur.com/Pr8tfnT.png);
background-position: 0px 111px;
background-repeat: repeat-x;
background-size: 100%;
animation: water 10s forwards;
}
@keyframes water {
100% {
background-position: 2000px 0px;
}
}
</style>
<mask id="mask" fill="black">
<rect fill="white" width="600" height="800"/>
<polygon id="right" points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
<polygon id="left" points="34 537,150 536,289 130,314 53,196 51"/>
<rect id="rect1" x="120" y="320" stroke-miterlimit="10" width="270" height="120"/>
</mask>
<rect fill="white" width="600" height="800" mask="url(#mask)"/>
</svg>
В ходе выполнения было замечено что у оригинала svg
viewbox
и width
, height
перепутаны...
.letter {
width:200px;height:auto;
stroke-width:2.5;
stroke:#000;
fill:none;
stroke-dasharray: 0 24;
}
.animateFirst { animation: 0.5s animateFirst ease-in forwards; }
.animateSecond { animation: 0.2s 0.45s animateSecond ease-out forwards; }
@keyframes animateFirst {
to { stroke-dasharray: 24 24; }
}
@keyframes animateSecond {
to { stroke-dasharray: 6 24; }
}
<svg class="letter" viewbox="0 0 12 10">
<polygon class="animateFirst" points="1,11.5 6,0 11,11.5" />
<polygon class="animateSecond" points="3,6.5 9,6.5" />
</svg>
Источник ответа:@web-tiki
Все элементы анимации в начале невидимы fill-opacity="0"
Анимация появления одного элемента:
<animate
id="an_left"
attributeName="fill-opacity"
begin="1s"
from="0"
to="1"
dur="0.3s"
fill="freeze"/>
Последовательность выполнения анимаций достигается цепочкой условиё в атрибуте begin="an_left.end"
Такая запись означает что анимация правого прямоугольника начнется только после окончания анимации левого многоугольника
Ниже полный код:
.container {
width:35%;
height:35%;
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 800">
<polygon id="right" fill="#008080" fill-opacity="0"
points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55">
<animate
id="an_right"
attributeName="fill-opacity"
begin="an_left.end"
from="0"
to="1"
dur="0.3s"
fill="freeze"/>
</polygon>
<polygon id="left" fill="#008080" fill-opacity="0" points="34 537,150 536,289 130,314 53,196 51">
<animate
id="an_left"
attributeName="fill-opacity"
begin="0.2s"
from="0"
to="1"
dur="0.3s"
fill="freeze"/>
</polygon>
<rect x="120" y="320" fill="#008080" fill-opacity="0" stroke-miterlimit="10" width="270" height="120">
<animate
id="an_rect"
attributeName="fill-opacity"
from="0"
to="1"
begin="an_right.end"
dur="0.3s"
fill="freeze"/>
</rect>
</svg>
</div>
.container {
width:35%;
height:35%;
}
#left,#right, #rect1 {
fill-opacity:0;
fill:#008080;
}
#left {
animation:anLeft 0.3s ease forwards;
animation-delay: 0.1s;
}
@keyframes anLeft {
100% {
fill-opacity:1;
}
}
#right {
animation:anRight 0.3s ease forwards;
animation-delay: 0.4s;
}
@keyframes anRight {
100% {
fill-opacity:1;
}
}
#rect1 {
animation:anRect 0.3s ease forwards;
animation-delay:0.7s;
}
@keyframes anRect {
100% {
fill-opacity:1;
}
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 800">
<polygon id="right"
points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
<polygon id="left" points="34 537,150 536,289 130,314 53,196 51"/>
<rect id="rect1" x="120" y="320" stroke-miterlimit="10" width="270" height="120"/>
</svg>
</div>
.container {
width:35%;
height:35%;
}
<div class="container">
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 800">
<g fill="#008080" fill-opacity="0" >
<polygon id="left" transform="rotate(72 306 200)" points="34 537,150 536,289 130,314 53,196 51">
<animateTransform
attributeName="transform"
type="rotate"
values="72 306 200;0 306 200"
begin="svg1.click"
dur="0.5s"
fill="freeze" />
<animate id="an_op1"
attributeName="fill-opacity"
from="0" to="1"
begin="svg1.click"
dur="0.5s"
fill="freeze" />
</polygon>
<polygon id="right" transform="rotate(-69 457.5 200)"
points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55">
<animateTransform
attributeName="transform"
type="rotate"
values="-69 457.5 200;0 457.5 200"
begin="an_op1.end"
dur="0.5s"
fill="freeze" />
<animate id="an_op2"
attributeName="fill-opacity"
from="0" to="1"
begin="an_op1.end"
dur="0.5s"
fill="freeze" />
</polygon>
<rect id="rect1" x="800" y="320" width="270" height="120">
<animate attributeName="x"
from="800" to="120"
begin="an_op2.end"
dur="0.5s"
fill="freeze" />
<animate id="an_op3"
attributeName="fill-opacity"
from="0" to="1"
begin="an_op2.end"
dur="0.5s"
fill="freeze" />
</rect>
</g>
<text x="0" y="80" font-size="50" fill="purple">Click me</text>
</svg>
</div>
Источник ответа:@Alexandr_TT
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Пишу бота на NodeJS, используя telegraph и вот уже в который раз сталкиваюсь с одной и той же проблемойКак ввести последовательно данные и сделать...