1

I made a scale animation test:

var btn = document.getElementById('testBtn');
var stopBtn = document.getElementById('testStop');
var runner;
var startSize = 20,
  endSize = 80;
const start = startSize === 0 ? 0.001 : startSize / 100;
const end = (endSize / 100) * (1 / start);
var x = 0,
  y = 0,
  width = 50,
  height = 50;
const endss = end * start;
let over = false;

const rect = document.getElementById('svg_1');
const svgEle = SVG(rect);
btn.addEventListener('click', () => {
  runner = svgEle.animate().opacity(0).animate().scale(start, start, x, y + height / 2)
    .animate().opacity(1)
    .animate({
      duration: 1500
    }).scale(end, end, x, y + height / 2);
})


stopBtn.addEventListener('click', () => {
  svgEle.timeline().finish();
  setTimeout(() => {
    rect.removeAttribute('transform');
  }, 200);
})
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0.10/dist/svg.min.js"></script>

<svg width="640" height="480" style="background: lightblue">
  <rect width="50" x="0" y="0" height="50" fill="#ff0000" id="svg_1"></rect>
</svg>

<div>
  <button id="testBtn">start</button>
</div>
<div style="margin-top: 30px;">
  <button id="testStop">restore</button>
</div>

that's what I say. when I click 'start' button, the rect scale from 20% to 80%, when I click 'restore' button, restore the rect scale to 1, but when I click 'start' again , the rect become smaller than before, ..... ... loop the operates, the rect become more and more small.

so, why the animation still depends on last's result. how to destory the last animation and start a new scale animation.

chrwahl
  • 8,675
  • 2
  • 20
  • 30
wpindesign
  • 23
  • 7

1 Answers1

0

A simple way to solve this could be using CSS transition. An alternative to transition could be using CSS animations.

Example 1

The class names are changed. Switch between different class names depending on what the element should do. You need to be able to add, remove class names (see a full list of functions here: DOMTokenList) and listen for events when the transition start and end (see more here: GlobalEventHandlers.ontransitionend).

var btn = document.getElementById('testBtn');
var stopBtn = document.getElementById('testStop');

const rect = document.getElementById('svg_1');

btn.addEventListener('click', () => {
  rect.classList.add('small');
});

rect.addEventListener('transitionend', e => {
  e.target.classList.replace('small', 'large');
});

stopBtn.addEventListener('click', () => {
  rect.classList.remove('small', 'large');
})
rect#svg_1 {
  transform: scale(1);
  transition: all 1.5s;
}

rect#svg_1.small {
  transform: scale(.1);
  opacity: 0;
}

rect#svg_1.large {
  transform: scale(2);
}
<svg width="100" height="100" style="background: lightblue">
  <rect width="50" x="0" y="0" height="50" fill="#ff0000" id="svg_1"></rect>
</svg>

<div>
  <button id="testBtn">start</button>
</div>
<div style="margin-top: 30px;">
  <button id="testStop">restore</button>
</div>

Example 2

The transform property on the element is updated based on something. In this example the changing of value on an range input element updates the value of the transform property. When clicking the restore button the inline style will be removed and the form reset.

var btn = document.getElementById('testBtn');
var stopBtn = document.getElementById('testStop');

const rect = document.getElementById('svg_1');

document.forms.scale.range.addEventListener('change', e => {
  rect.style.transform = `scale(${e.target.value})`;
});

stopBtn.addEventListener('click', () => {
  rect.removeAttribute('style');
  document.forms.scale.reset();
})
rect#svg_1 {
  transform: scale(1);
  transition: all 1.5s;
}
<svg width="100" height="100" style="background: lightblue">
  <rect width="50" x="0" y="0" height="50" fill="#ff0000" id="svg_1"></rect>
</svg>
<form name="scale">
  <input name="range" type="range" min="0" max="2" step=".1" value="1" />
</form>
<div style="margin-top: 30px;">
  <button id="testStop">restore</button>
</div>
chrwahl
  • 8,675
  • 2
  • 20
  • 30
  • the startSize and endSize is just an example, it's value acturaly is dynamic – wpindesign Jun 15 '22 at 02:23
  • @wpindesign I updated my answer. Maybe example 2 fits your case better. I use a range input element to update the scale value, but it could be something else that triggered the update. – chrwahl Jun 15 '22 at 07:05