SVG - problems with animation

I have some shapes that I rotate with two buttons: clockwise and the other counterclockwise:

var svgNS = "http://www.w3.org/2000/svg";

function cwAnim(evt) {
  if (window.svgDocument == null)
    svgDoc = evt.target.ownerDocument;

  addRotateTransform('someShape', 1, -1, 180);
  addRotateTransform('shape1', 1, 1, 360);
  addRotateTransform('shape2', 1, 1, 360);
}

function acwAnim(evt) {
  if (window.svgDocument == null)
    svgDoc = evt.target.ownerDocument;

  addRotateTransform('someShape', 1, 1, 180);
  addRotateTransform('shape1', 1, -1, 360);
  addRotateTransform('shape2', 1, -1, 360);
}

function addRotateTransform(target_id, dur, dir, angle) {
  var my_element = svgDoc.getElementById(target_id);
  var a = svgDoc.createElementNS(svgNS, "animateTransform");

  var bb = my_element.getBBox();
  var cx = bb.x + bb.width / 2;
  var cy = bb.y + bb.height / 2;

  a.setAttributeNS(null, "attributeName", "transform");
  a.setAttributeNS(null, "attributeType", "XML");
  a.setAttributeNS(null, "type", "rotate");
  a.setAttributeNS(null, "dur", dur + "s");
  a.setAttributeNS(null, "repeatCount", "1");
  a.setAttributeNS(null, "fill", "freeze");
  a.setAttributeNS(null, "additive", "sum");
  a.setAttributeNS(null, "accumulate", "sum");
  a.setAttributeNS(null, "from", "0 " + cx + " " + cy);
  a.setAttributeNS(null, "to", angle * dir + " " + cx + " " + cy);

  my_element.appendChild(a);
  a.beginElement();
}
<svg width="600px" height="600px" viewBox="0 0 1000 1000">
  <circle stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
  <g id="someShape">
    <circle fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
    <path id="shape1" fill="#DC5A00" stroke="#000000" stroke-miterlimit="10" d="M692.373,317.798C692.373,418.425,606.244,500,500,500
			c-106.245,0-192.374-81.575-192.374-182.202c0-100.629,86.128-182.204,192.374-182.204
			C606.244,135.595,692.373,217.169,692.373,317.798z M553.391,220.34c-39.316,0-71.188,31.87-71.188,71.187
			s31.871,71.187,71.188,71.187c39.314,0,71.186-31.87,71.186-71.187S592.705,220.34,553.391,220.34z" />
    <path id="shape2" fill="#3DFF63" stroke="#000000" stroke-miterlimit="10" d="M577.368,647.034c0,69.738-56.913,126.271-127.119,126.271
			c-70.206,0-127.119-56.533-127.119-126.271c0-69.737,56.913-126.271,127.119-126.271
			C520.455,520.764,577.368,577.297,577.368,647.034z M466.352,617.373c-21.998,0-39.831,17.453-39.831,38.983
			c0,21.529,17.833,38.982,39.831,38.982s39.831-17.453,39.831-38.982C506.182,634.826,488.349,617.373,466.352,617.373z" />
  </g>
  <g onclick="cwAnim(evt)">
    <rect x="89.762" y="815.369" stroke="#000000" stroke-miterlimit="10" width="217.865" height="134.426" />
    <text transform="matrix(1 0 0 1 127.4673 864.5491)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">AntiClockwise</text>
  </g>
  <g onclick="acwAnim(evt)">
    <rect x="692.373" y="815.369" stroke="#000000" stroke-miterlimit="10" width="194.11" height="134.426" />
    <text transform="matrix(1 0 0 1 752.0576 869.467)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">Clockwise</text>
  </g>
</svg>
Run codeHide result

You can also see it on this CodePen: http://codepen.io/Daolagajao/pen/qdyBLo

When I click once, the form animates perfectly. The problem occurs when I click buttons in quick chains (double click, triple click, etc.). The axis of rotation shifts, and this, of course, is undesirable.

Is there any way to solve this problem? Something like, when I click on the next button, the previous animation in the process stops saving the position and a new animation occurs.

+4
source share
1 answer

busy, , , . , .

var svgNS = "http://www.w3.org/2000/svg";
var busy = false;

function animationDelegate(evt, direction){
    /* Check if we are busy before doing anything.*/
    /* If we are, stop executing this request, otherwise, set busy to true.*/
    if(busy) return; else busy = true;
    if(direction === 'cw') cwAnim(evt);
    else if(direction === 'ccw') acwAnim(evt);
    /* Your duration is 1 second, so 1000ms.*/
    /* Set a timeout that resets busy.*/
    setTimeout(function(){ busy = false}, 1000);
}

function cwAnim(evt){
  if ( window.svgDocument == null)
    svgDoc = evt.target.ownerDocument;

  addRotateTransform('someShape', 1, -1, 180);
  addRotateTransform('shape1', 1, 1, 360);
  addRotateTransform('shape2', 1, 1, 360);				
}

function acwAnim(evt){
  if ( window.svgDocument == null)
    svgDoc = evt.target.ownerDocument;

  addRotateTransform('someShape', 1, 1, 180);
  addRotateTransform('shape1', 1, -1, 360);
  addRotateTransform('shape2', 1, -1, 360);							
}

function addRotateTransform(target_id, dur, dir, angle){
  var my_element = svgDoc.getElementById(target_id);
  var a = svgDoc.createElementNS(svgNS, "animateTransform");

  var bb = my_element.getBBox();
  var cx = bb.x + bb.width/2;
  var cy = bb.y + bb.height/2;

  a.setAttributeNS(null, "attributeName", "transform");
  a.setAttributeNS(null, "attributeType", "XML");
  a.setAttributeNS(null, "type", "rotate");
  a.setAttributeNS(null, "dur", dur + "s");
  a.setAttributeNS(null, "repeatCount", "1");
  a.setAttributeNS(null, "fill", "freeze");
  a.setAttributeNS(null, "additive", "sum");
  a.setAttributeNS(null, "accumulate", "sum");
  a.setAttributeNS(null, "from", "0 "+cx+" "+cy);
  a.setAttributeNS(null, "to", angle*dir+" "+cx+" "+cy);

  my_element.appendChild(a);
  a.beginElement();
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="600px" height="600px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
  <circle stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
  <g id="someShape">
    <circle fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
    <path id="shape1" fill="#DC5A00" stroke="#000000" stroke-miterlimit="10" d="M692.373,317.798C692.373,418.425,606.244,500,500,500
			c-106.245,0-192.374-81.575-192.374-182.202c0-100.629,86.128-182.204,192.374-182.204
			C606.244,135.595,692.373,217.169,692.373,317.798z M553.391,220.34c-39.316,0-71.188,31.87-71.188,71.187
			s31.871,71.187,71.188,71.187c39.314,0,71.186-31.87,71.186-71.187S592.705,220.34,553.391,220.34z" />
    <path id="shape2" fill="#3DFF63" stroke="#000000" stroke-miterlimit="10" d="M577.368,647.034c0,69.738-56.913,126.271-127.119,126.271
			c-70.206,0-127.119-56.533-127.119-126.271c0-69.737,56.913-126.271,127.119-126.271
			C520.455,520.764,577.368,577.297,577.368,647.034z M466.352,617.373c-21.998,0-39.831,17.453-39.831,38.983
			c0,21.529,17.833,38.982,39.831,38.982s39.831-17.453,39.831-38.982C506.182,634.826,488.349,617.373,466.352,617.373z" />
  </g>
  <g onclick="animationDelegate(evt, 'ccw')">
    <rect x="89.762" y="815.369" stroke="#000000" stroke-miterlimit="10" width="217.865" height="134.426" />
    <text transform="matrix(1 0 0 1 127.4673 864.5491)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">AntiClockwise</text>
  </g>
  <g onclick="animationDelegate(evt, 'cw')">
    <rect x="692.373" y="815.369" stroke="#000000" stroke-miterlimit="10" width="194.11" height="134.426" />
    <text transform="matrix(1 0 0 1 752.0576 869.467)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">Clockwise</text>
  </g>
</svg>
Hide result
+4

Source: https://habr.com/ru/post/1598212/


All Articles