How to exchange the SVG drawing for a PNG image after completing the animation?

Asked

Viewed 57 times

0

Good afternoon! I put a drawing in SVG on my site, and put an animation for when the drawing is visible on the screen, start the animation of the drawing if "completing", follows the JS code.

document.addEventListener('DOMContentLoaded', function() {

   var svg4 = new Walkway({
    selector: '#Layer_1',
    duration: 3500,
    redrawOnFocus: true
   });

   $(window).on("scroll", function(){
      var el = $('#Layer_1');
      var eleHeight = el.outerHeight(); // altura do elemento
      var eleTopo = el.offset().top; // distancia do elemento ao topo do documento
      var scrlTopo = $(window).scrollTop(); // quanto foi rolada a janela
      var distance = eleTopo-scrlTopo; // distancia do elemento ao topo da janela
      var altJanela = window.innerHeight; // altura da janela
      if(distance <= altJanela-(eleHeight/2)) {
         svg4.draw(); // inicia a animação
      }
   });

  document.addEventListener('dblclick', function() {
    svg.redraw();
    svg4.redraw();
  }, false);
});

/*
 * Walkway.js
 *
 * Copyright 2016, Connor Atherton - http://connoratherton.com/
 * Released under the MIT Licence
 * http://opensource.org/licenses/MIT
 *
 * Github: http://github.com/ConnorAtherton/Walkway
 */

// Export Walkway depending on environment (AMD, CommonJS or Browser global)
;(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory);
  } else if (typeof exports === 'object') {
    // CommonJS
    module.exports = factory();
  } else {
    // Browser globals
    root.Walkway = factory();
  }
}(this, function factory(exports) {
  'use strict';

  /*
   * Shim for requestAnimationFrame on older browsers
   */

  var lastTime = 0;
  window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() {
        callback(currTime + timeToCall);
      }, timeToCall);

      lastTime = currTime + timeToCall;
      return id;
    };
  }

  if (!window.cancelAnimationFrame) {
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
  }

  /*
   * Easing Functions - inspired from http://gizma.com/easing/
   * only considering the t value for the range [0, 1] => [0, 1]
   *
   * Taken from https://gist.github.com/gre/1650294
   */

  var EasingFunctions = {
    // no easing, no acceleration
    linear: function (t) { return t; },
    // accelerating from zero velocity
    easeInQuad: function (t) { return t*t; },
      // decelerating to zero velocity
    easeOutQuad: function (t) { return t*(2-t); },
      // acceleration until halfway, then deceleration
    easeInOutQuad: function (t) { return t<0.5 ? 2*t*t : -1+(4-2*t)*t; },
      // accelerating from zero velocity
    easeInCubic: function (t) { return t*t*t; },
      // decelerating to zero velocity
    easeOutCubic: function (t) { return (--t)*t*t+1; },
      // acceleration until halfway, then deceleration
    easeInOutCubic: function (t) { return t<0.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; },
      // accelerating from zero velocity
    easeInQuart: function (t) { return t*t*t*t; },
      // decelerating to zero velocity
    easeOutQuart: function (t) { return 1-(--t)*t*t*t; },
      // acceleration until halfway, then deceleration
    easeInOutQuart: function (t) { return t<0.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t; },
      // accelerating from zero velocity
    easeInQuint: function (t) { return t*t*t*t*t; },
      // decelerating to zero velocity
    easeOutQuint: function (t) { return 1+(--t)*t*t*t*t; },
      // acceleration until halfway, then deceleration
    easeInOutQuint: function (t) { return t<0.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t; }
  };

  /*
   * Creates a selector used to select all element to animate
   * Currently only supports *path*, *line*, and *polyline* svg elements
   *
   * @param {string} selector The selector of the parent element
   * @returns {string} the complete selector
   * @private
   */

  function _createSelector(selector) {
    var supported = ['path', 'line', 'polyline'];
    var newSelector = supported.reduce(function(prev, curr){
      return prev + selector + ' ' + curr + ', ';
    }, '');
    // chop the last , from the string
    return newSelector.slice(0, -2);
  }

  /*
   * All Walkway instances present on the current page. This is needed for when
   * the tab loses focus and we need to force each animation to finish.
   */
  var _elements = [];
  var _instances = [];

  document.addEventListener('visibilitychange', function() {
    if (!document.hidden) {
      return;
    }

    for (var i = 0, instancesLen = _instances.length; i < instancesLen; i++) {
      _instances[i].cancel();
    }

    for (var j = 0, elementsLen = _elements.length; j < elementsLen; j++) {
      _elements[j].complete();
    }
  }, false);

  /*
   * Walkway constructor function
   * opts.selector is the only mandatory param and can be passed in alone
   * as a string
   *
   * @param {object} opts the configuration objects for the instance.
   * @returns {walkway}
   */

  function Walkway(opts) {
    if (!(this instanceof Walkway)) {
      return new Walkway(opts);
    }

    if (typeof opts === 'string') {
      opts = { selector: opts };
    }

    if (!opts.selector) {
      return this.error('A selector needs to be specified');
    }

    this.opts = opts;
    this.selector = opts.selector;
    this.duration = opts.duration || 500;
    this.easing = (typeof opts.easing === 'function') ?
      opts.easing :
      EasingFunctions[opts.easing] || EasingFunctions.easeInOutCubic;
    this.id = false;
    this.elements = this.getElements();
    this.callback = opts.callback;

    this.setInitialStyles();

    _elements = _elements.concat(this.elements);
    _instances.push(this);
  }

  Walkway.prototype = {
    constructor: Walkway,

    /*
     * Prints an error message to the console
     *
     * @param {string} message the message to be displayed
     * @returns {void}
     */
    error: function(message) {
      console.error('Walkway error: ' + message);
    },

    /*
     * Uses a pre-build selector to find and store elements to animate
     *
     * @returns {array} of Path instances
     */
    getElements: function() {
      var self = this;
      var selector = _createSelector(this.selector);
      var els = document.querySelectorAll(selector);
      els = Array.prototype.slice.call(els);

      return els.map(function(el) {
        if(el.tagName === 'path') {
          return new Path(el, self.duration, self.easing);
        } else if (el.tagName === 'line') {
          return new Line(el, self.duration, self.easing);
        } else if(el.tagName === 'polyline') {
          return new Polyline(el, self.duration, self.easing);
        }
      });
    },

    /*
     * Sets initial styles on all elements to be animated
     *
     * @returns {void}
     */
    setInitialStyles: function() {
      this.elements.forEach(function(n) {
        n.el.style.strokeDasharray = n.length + ' ' + n.length;
        n.el.style.strokeDashoffset = n.length;
      });
    },

    /*
     * The general update loop for the animations.
     * Once individal paths are completed they are marked as such and
     * are not updated.
     *
     * @returns {void}
     */
    draw: function(callback) {
      var counter = this.elements.length;
      var allComplete = this.elements.filter(function(el) { return el.done; }).length === counter;
      var element = null;
      var done = false;

      // Overwrite existing callback passed in with options
      this.callback = callback || this.callback;

      if (allComplete) {
        if (this.callback && typeof(this.callback) === 'function') {
          this.callback();
        }

        this.cancel();
        return;
      }

      while (counter--) {
        element = this.elements[counter];
        done = element.update();

        if (done) {
          element.done = true;
        }
      }

      this.id = window.requestAnimationFrame(this.draw.bind(this, callback));
    },

    cancel: function() {
      window.cancelAnimationFrame(this.id);
    },

    redraw: function() {
      this.cancel();

      this.elements.forEach(function(element) {
        element.reset();
      });

      this.draw();
    }
  };

  function WalkwayElement(el, duration, easing) {
    this.el = el;
    this.duration = duration;
    this.easing = easing;
    this.animationStart = null;
    this.animationStarted = false;
  }

  WalkwayElement.prototype = {
    constructor: WalkwayElement,

    /*
     * This contains the general update logic for all supported svg
     * elements.
     *
     * @returns {boolean} true if the animation is complete, false otherwise
     */
    update: function() {
      if (!this.animationStarted) {
        this.animationStart = Date.now();
        this.animationStarted = true;
      }

      var progress = this.easing((Date.now() - this.animationStart) / this.duration);

      this.fill(progress);

      return progress >= 1 ? true : false;
    },

    fill: function(progress) {
      var value = Math.ceil(this.length * (1 - progress));
      this.el.style.strokeDashoffset = value < 0 ? 0 : Math.abs(value);
    },

    complete: function() {
      this.fill(1);
    },

    reset: function() {
      this.done = false;
      this.animationStart = 0;
      this.animationStarted = false;
      this.fill(0);
    }
  };

  /*
   * Constructor for new path instance
   *
   * @param {node} path actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {Path}
   */

  function Path(path, duration, easing) {
    WalkwayElement.call(this, path, duration, easing);

    this.length = path.getTotalLength();
  }

  /*
   * Constructor for new Line instance
   *
   * @param {node} line actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {line}
   */

  function Line(line, duration, easing) {
    WalkwayElement.call(this, line, duration, easing);

    this.length = getLineLength(line);
  }

  /*
   * Constructor for new Polyline instance
   *
   * @param {node} polyline actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {polyline}
   */
  function Polyline(polyline, duration, easing) {
    WalkwayElement.call(this, polyline, duration, easing);

    this.length = getPolylineLength(polyline);
  }

  Path.prototype = Line.prototype = Polyline.prototype = Object.create(WalkwayElement.prototype);

  /*
   * Calculates the length of a polyline using pythagoras theorem for each line segment
   *
   * @param {node} polyline The polyline element to calculate length of
   * @returns {Number} Length of the polyline
   */

  function getPolylineLength(polyline) {
    var dist = 0;
    var x1, x2, y1, y2;
    var i;
    var points = polyline.points.numberOfItems;

    for (i = 1; i < points; i++){
      x1 = polyline.points.getItem(i - 1).x;
      x2 = polyline.points.getItem(i).x;
      y1 = polyline.points.getItem(i - 1).y;
      y2 = polyline.points.getItem(i).y;

      dist += Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
    }

    return dist;
  }

  /*
   * Calculates the length a line using pythagoras theorem
   *
   * @param {node} line The line element to calculate length of
   * @returns {Number} Length of the line
   */

  function getLineLength(line) {
    var x1 = line.getAttribute('x1');
    var x2 = line.getAttribute('x2');
    var y1 = line.getAttribute('y1');
    var y2 = line.getAttribute('y2');

    return Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
  }

  return Walkway;
}));
svg {
	width: 300px;
	height: 300px;
	fill: red;
	margin-left: 130px;
}

svg path {
	stroke: #310B3B;
}

svg:not(:root) {
	overflow: visible;
}

path {
	fill: transparent;
}

svg > span {
	position: absolute;
	top: 0;
	right: 0;
}

path, line, polyline {
	stroke: #fff;
	stroke-width: 1px;
}



polyline {
        stroke-width: 4px;
}

#Layer_1 path {
        stroke-width: 6.5px;
      }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

Role para baixo
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

<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"
	 viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
	<g>
		<path d="M437.586,297.264c-4.567,0-8.267,3.701-8.267,8.267v56.517c0,9.597-7.807,17.405-17.405,17.405H212.561
			c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.7,8.267,8.267,8.267h0.552l-9.52,39.656c-0.591,2.462-0.021,5.059,1.547,7.048
			c1.567,1.988,3.96,3.149,6.492,3.149h111.689c4.567,0,8.267-3.701,8.267-8.267c0-4.566-3.7-8.267-8.267-8.267h-32.429
			l-7.999-33.319h129.022c18.714,0,33.939-15.224,33.939-33.939v-56.517C445.853,300.966,442.153,297.264,437.586,297.264z
			 M222.118,429.306l7.999-33.319h35.772l7.999,33.319H222.118z"/>
	</g>
</g>
<g>
	<g>
		<path d="M346.573,92.259H75.284c-18.72,0-33.95,15.23-33.95,33.95l0.001,78.903c0,4.566,3.7,8.267,8.267,8.267
			c4.567,0,8.267-3.701,8.267-8.267l-0.001-78.903c0-9.603,7.813-17.416,17.416-17.416h271.288c4.567,0,8.267-3.701,8.267-8.267
			C354.84,95.961,351.139,92.259,346.573,92.259z"/>
	</g>
</g>
<g>
	<g>
		<path d="M413.746,344.236H210.357c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h203.389
			c4.567,0,8.267-3.701,8.267-8.267S418.312,344.236,413.746,344.236z"/>
	</g>
</g>
<g>
	<g>
		<path d="M346.573,127.476H73.455c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.7,8.267,8.267,8.267h273.118
			c4.567,0,8.267-3.701,8.267-8.267C354.84,131.178,351.139,127.476,346.573,127.476z"/>
	</g>
</g>
<g>
	<g>
		<path d="M503.733,203.388c4.567,0,8.267-3.701,8.267-8.267v-127c0-14.314-11.644-25.959-25.959-25.959h-96.886
			c-14.314,0-25.959,11.645-25.959,25.959v195.646c0,14.314,11.644,25.959,25.959,25.959h96.886
			c14.314,0,25.959-11.645,25.959-25.959v-43.844c0-4.566-3.7-8.267-8.267-8.267s-8.267,3.701-8.267,8.267v43.844
			c0,5.197-4.228,9.425-9.425,9.425h-96.886c-5.197,0-9.425-4.228-9.425-9.425V68.121c0-5.197,4.228-9.425,9.425-9.425h96.886
			c5.197,0,9.425,4.228,9.425,9.425v127.001C495.466,199.687,499.166,203.388,503.733,203.388z"/>
	</g>
</g>
<g>
	<g>
		<path d="M329.575,211.025l-20.532-20.532c-3.229-3.227-8.462-3.229-11.692,0c-3.228,3.229-3.228,8.463,0,11.692l6.42,6.42h-72.136
			c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h72.136l-6.42,6.42c-3.228,3.229-3.228,8.463,0,11.692
			c1.615,1.614,3.731,2.422,5.846,2.422c2.115,0,4.232-0.807,5.846-2.422l20.532-20.532
			C332.803,219.487,332.803,214.253,329.575,211.025z"/>
	</g>
</g>
<g>
	<g>
		<path d="M323.728,267.023h-72.136l6.42-6.42c3.229-3.229,3.229-8.463,0-11.692c-3.229-3.227-8.462-3.229-11.692,0l-20.533,20.532
			c-1.55,1.551-2.421,3.653-2.421,5.845s0.871,4.296,2.421,5.845l20.533,20.532c1.615,1.614,3.731,2.422,5.846,2.422
			c2.115,0,4.232-0.807,5.846-2.422c3.229-3.229,3.229-8.463,0-11.692l-6.42-6.42h72.136c4.566,0.002,8.266-3.699,8.266-8.265
			S328.295,267.023,323.728,267.023z"/>
	</g>
</g>
<g>
	<g>
		<path d="M480.126,86.909h-85.058c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h85.058c4.567,0,8.267-3.701,8.267-8.267
			S484.693,86.909,480.126,86.909z"/>
	</g>
</g>
<g>
	<g>
		<path d="M480.126,228.444h-85.058c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h85.058
			c4.567,0,8.267-3.701,8.267-8.267S484.693,228.444,480.126,228.444z"/>
	</g>
</g>
<g>
	<g>
		<path d="M167.863,222.275H25.959C11.644,222.275,0,233.921,0,248.233v49.213c0,4.566,3.7,8.267,8.267,8.267
			s8.267-3.701,8.267-8.267v-49.213c0-5.197,4.228-9.425,9.425-9.425h141.904c5.197,0,9.425,4.228,9.425,9.425v195.646
			c0,5.197-4.228,9.425-9.425,9.425H25.959c-5.197,0-9.425-4.228-9.425-9.425V322.983c0-4.566-3.7-8.267-8.267-8.267
			S0,318.418,0,322.983v120.896c0,14.314,11.644,25.959,25.959,25.959h141.904c14.314,0,25.959-11.645,25.959-25.959V248.233
			C193.823,233.921,182.177,222.275,167.863,222.275z"/>
	</g>
</g>
<g>
	<g>
		<path d="M163.834,267.023H29.987c-4.567,0-8.267,3.701-8.267,8.267s3.701,8.267,8.267,8.267h133.847
			c4.567,0,8.267-3.701,8.267-8.267S168.401,267.023,163.834,267.023z"/>
	</g>
</g>
<g>
	<g>
		<path d="M163.834,408.557H29.987c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.701,8.267,8.267,8.267h133.847
			c4.567,0,8.267-3.701,8.267-8.267C172.101,412.259,168.401,408.557,163.834,408.557z"/>
	</g>
</g>
<g>
	<g>
		<circle cx="437.597" cy="258.943" r="8.267"/>
	</g>
</g>
<g>
	<g>
		<circle cx="96.911" cy="439.526" r="8.267"/>
	</g>
</g>
</svg>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

How do I stop when the animation completes, the edges of the drawing are removed and enter an image in place? I have this vector image, with a transparent background, so I’d be fine.

foto

1 answer

2


Enter the code below where it is verified that the animation has been completed (inside the if(allComplete){):

if(!terminou){
   terminou = true;
   $("#nova").fadeIn();
   $("#Layer_1").fadeOut();
}

It was necessary to create a new div #desenho to group the svg and another div #nova that will be the div with the background .png. I did this because I dynamically add a background under these conditions using .fadeIn() would cause that "blink" in transition.

I also created a flag terminou = false; to prevent the code from being executed more than once unnecessarily in scroll after the end of the animation.

terminou = false;
document.addEventListener('DOMContentLoaded', function() {

   var svg4 = new Walkway({
    selector: '#Layer_1',
    duration: 3500,
    redrawOnFocus: true
   });

   $(window).on("scroll", function(){
      var el = $('#Layer_1');
      var eleHeight = el.outerHeight(); // altura do elemento
      var eleTopo = el.offset().top; // distancia do elemento ao topo do documento
      var scrlTopo = $(window).scrollTop(); // quanto foi rolada a janela
      var distance = eleTopo-scrlTopo; // distancia do elemento ao topo da janela
      var altJanela = window.innerHeight; // altura da janela
      if(distance <= altJanela-(eleHeight/2)) {
         svg4.draw(); // inicia a animação
      }
   });

  document.addEventListener('dblclick', function() {
    svg.redraw();
    svg4.redraw();
  }, false);
});

/*
 * Walkway.js
 *
 * Copyright 2016, Connor Atherton - http://connoratherton.com/
 * Released under the MIT Licence
 * http://opensource.org/licenses/MIT
 *
 * Github: http://github.com/ConnorAtherton/Walkway
 */

// Export Walkway depending on environment (AMD, CommonJS or Browser global)
;(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory);
  } else if (typeof exports === 'object') {
    // CommonJS
    module.exports = factory();
  } else {
    // Browser globals
    root.Walkway = factory();
  }
}(this, function factory(exports) {
  'use strict';

  /*
   * Shim for requestAnimationFrame on older browsers
   */

  var lastTime = 0;
  window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() {
        callback(currTime + timeToCall);
      }, timeToCall);

      lastTime = currTime + timeToCall;
      return id;
    };
  }

  if (!window.cancelAnimationFrame) {
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
  }

  /*
   * Easing Functions - inspired from http://gizma.com/easing/
   * only considering the t value for the range [0, 1] => [0, 1]
   *
   * Taken from https://gist.github.com/gre/1650294
   */

  var EasingFunctions = {
    // no easing, no acceleration
    linear: function (t) { return t; },
    // accelerating from zero velocity
    easeInQuad: function (t) { return t*t; },
      // decelerating to zero velocity
    easeOutQuad: function (t) { return t*(2-t); },
      // acceleration until halfway, then deceleration
    easeInOutQuad: function (t) { return t<0.5 ? 2*t*t : -1+(4-2*t)*t; },
      // accelerating from zero velocity
    easeInCubic: function (t) { return t*t*t; },
      // decelerating to zero velocity
    easeOutCubic: function (t) { return (--t)*t*t+1; },
      // acceleration until halfway, then deceleration
    easeInOutCubic: function (t) { return t<0.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; },
      // accelerating from zero velocity
    easeInQuart: function (t) { return t*t*t*t; },
      // decelerating to zero velocity
    easeOutQuart: function (t) { return 1-(--t)*t*t*t; },
      // acceleration until halfway, then deceleration
    easeInOutQuart: function (t) { return t<0.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t; },
      // accelerating from zero velocity
    easeInQuint: function (t) { return t*t*t*t*t; },
      // decelerating to zero velocity
    easeOutQuint: function (t) { return 1+(--t)*t*t*t*t; },
      // acceleration until halfway, then deceleration
    easeInOutQuint: function (t) { return t<0.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t; }
  };

  /*
   * Creates a selector used to select all element to animate
   * Currently only supports *path*, *line*, and *polyline* svg elements
   *
   * @param {string} selector The selector of the parent element
   * @returns {string} the complete selector
   * @private
   */

  function _createSelector(selector) {
    var supported = ['path', 'line', 'polyline'];
    var newSelector = supported.reduce(function(prev, curr){
      return prev + selector + ' ' + curr + ', ';
    }, '');
    // chop the last , from the string
    return newSelector.slice(0, -2);
  }

  /*
   * All Walkway instances present on the current page. This is needed for when
   * the tab loses focus and we need to force each animation to finish.
   */
  var _elements = [];
  var _instances = [];

  document.addEventListener('visibilitychange', function() {
    if (!document.hidden) {
      return;
    }

    for (var i = 0, instancesLen = _instances.length; i < instancesLen; i++) {
      _instances[i].cancel();
    }

    for (var j = 0, elementsLen = _elements.length; j < elementsLen; j++) {
      _elements[j].complete();
    }
  }, false);

  /*
   * Walkway constructor function
   * opts.selector is the only mandatory param and can be passed in alone
   * as a string
   *
   * @param {object} opts the configuration objects for the instance.
   * @returns {walkway}
   */

  function Walkway(opts) {
    if (!(this instanceof Walkway)) {
      return new Walkway(opts);
    }

    if (typeof opts === 'string') {
      opts = { selector: opts };
    }

    if (!opts.selector) {
      return this.error('A selector needs to be specified');
    }

    this.opts = opts;
    this.selector = opts.selector;
    this.duration = opts.duration || 500;
    this.easing = (typeof opts.easing === 'function') ?
      opts.easing :
      EasingFunctions[opts.easing] || EasingFunctions.easeInOutCubic;
    this.id = false;
    this.elements = this.getElements();
    this.callback = opts.callback;

    this.setInitialStyles();

    _elements = _elements.concat(this.elements);
    _instances.push(this);
  }

  Walkway.prototype = {
    constructor: Walkway,

    /*
     * Prints an error message to the console
     *
     * @param {string} message the message to be displayed
     * @returns {void}
     */
    error: function(message) {
      console.error('Walkway error: ' + message);
    },

    /*
     * Uses a pre-build selector to find and store elements to animate
     *
     * @returns {array} of Path instances
     */
    getElements: function() {
      var self = this;
      var selector = _createSelector(this.selector);
      var els = document.querySelectorAll(selector);
      els = Array.prototype.slice.call(els);

      return els.map(function(el) {
        if(el.tagName === 'path') {
          return new Path(el, self.duration, self.easing);
        } else if (el.tagName === 'line') {
          return new Line(el, self.duration, self.easing);
        } else if(el.tagName === 'polyline') {
          return new Polyline(el, self.duration, self.easing);
        }
      });
    },

    /*
     * Sets initial styles on all elements to be animated
     *
     * @returns {void}
     */
    setInitialStyles: function() {
      this.elements.forEach(function(n) {
        n.el.style.strokeDasharray = n.length + ' ' + n.length;
        n.el.style.strokeDashoffset = n.length;
      });
    },

    /*
     * The general update loop for the animations.
     * Once individal paths are completed they are marked as such and
     * are not updated.
     *
     * @returns {void}
     */
    draw: function(callback) {
      var counter = this.elements.length;
      var allComplete = this.elements.filter(function(el) { return el.done; }).length === counter;
      var element = null;
      var done = false;

      // Overwrite existing callback passed in with options
      this.callback = callback || this.callback;

      if (allComplete) {
        if (this.callback && typeof(this.callback) === 'function') {
          this.callback();
        }

         if(!terminou){
            terminou = true;
            $("#nova").fadeIn();
            $("#Layer_1").fadeOut();
         }

        this.cancel();
        return;
      }

      while (counter--) {
        element = this.elements[counter];
        done = element.update();

        if (done) {
          element.done = true;
        }
      }

      this.id = window.requestAnimationFrame(this.draw.bind(this, callback));
    },

    cancel: function() {
      window.cancelAnimationFrame(this.id);
    },

    redraw: function() {
      this.cancel();

      this.elements.forEach(function(element) {
        element.reset();
      });

      this.draw();
    }
  };

  function WalkwayElement(el, duration, easing) {
    this.el = el;
    this.duration = duration;
    this.easing = easing;
    this.animationStart = null;
    this.animationStarted = false;
  }

  WalkwayElement.prototype = {
    constructor: WalkwayElement,

    /*
     * This contains the general update logic for all supported svg
     * elements.
     *
     * @returns {boolean} true if the animation is complete, false otherwise
     */
    update: function() {
      if (!this.animationStarted) {
        this.animationStart = Date.now();
        this.animationStarted = true;
      }

      var progress = this.easing((Date.now() - this.animationStart) / this.duration);

      this.fill(progress);

      return progress >= 1 ? true : false;
    },

    fill: function(progress) {
      var value = Math.ceil(this.length * (1 - progress));
      this.el.style.strokeDashoffset = value < 0 ? 0 : Math.abs(value);
    },

    complete: function() {
      this.fill(1);
    },

    reset: function() {
      this.done = false;
      this.animationStart = 0;
      this.animationStarted = false;
      this.fill(0);
    }
  };

  /*
   * Constructor for new path instance
   *
   * @param {node} path actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {Path}
   */

  function Path(path, duration, easing) {
    WalkwayElement.call(this, path, duration, easing);

    this.length = path.getTotalLength();
  }

  /*
   * Constructor for new Line instance
   *
   * @param {node} line actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {line}
   */

  function Line(line, duration, easing) {
    WalkwayElement.call(this, line, duration, easing);

    this.length = getLineLength(line);
  }

  /*
   * Constructor for new Polyline instance
   *
   * @param {node} polyline actual dom node of the path
   * @param {string} duration how long the animation should take to complete
   * @param {string} easing the type of easing used - default is easeInOutCubic.
   * @returns {polyline}
   */
  function Polyline(polyline, duration, easing) {
    WalkwayElement.call(this, polyline, duration, easing);

    this.length = getPolylineLength(polyline);
  }

  Path.prototype = Line.prototype = Polyline.prototype = Object.create(WalkwayElement.prototype);

  /*
   * Calculates the length of a polyline using pythagoras theorem for each line segment
   *
   * @param {node} polyline The polyline element to calculate length of
   * @returns {Number} Length of the polyline
   */

  function getPolylineLength(polyline) {
    var dist = 0;
    var x1, x2, y1, y2;
    var i;
    var points = polyline.points.numberOfItems;

    for (i = 1; i < points; i++){
      x1 = polyline.points.getItem(i - 1).x;
      x2 = polyline.points.getItem(i).x;
      y1 = polyline.points.getItem(i - 1).y;
      y2 = polyline.points.getItem(i).y;

      dist += Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
    }

    return dist;
  }

  /*
   * Calculates the length a line using pythagoras theorem
   *
   * @param {node} line The line element to calculate length of
   * @returns {Number} Length of the line
   */

  function getLineLength(line) {
    var x1 = line.getAttribute('x1');
    var x2 = line.getAttribute('x2');
    var y1 = line.getAttribute('y1');
    var y2 = line.getAttribute('y2');

    return Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
  }

  return Walkway;
}));
#desenho {
	width: 300px;
	height: 300px;
   position: relative;
	margin-left: 130px;
}

#nova{
   display:none;
   width:100%;
   height:100%;
   position:absolute;
   top:0;
   left:0;
   background:url(http://dvdteste.hospedagemdesites.ws/teste1.png);
}

svg{
	width: 100%;
	height: 100%;
	fill: red;
}

svg path {
	stroke: #310B3B;
}

svg:not(:root) {
	overflow: visible;
}

path {
	fill: transparent;
}

svg > span {
	position: absolute;
	top: 0;
	right: 0;
}

path, line, polyline {
	stroke: #fff;
	stroke-width: 1px;
}



polyline {
        stroke-width: 4px;
}

#Layer_1 path {
        stroke-width: 6.5px;
      }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Role para baixo
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

<div id="desenho">
<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"
	 viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
	<g>
		<path d="M437.586,297.264c-4.567,0-8.267,3.701-8.267,8.267v56.517c0,9.597-7.807,17.405-17.405,17.405H212.561
			c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.7,8.267,8.267,8.267h0.552l-9.52,39.656c-0.591,2.462-0.021,5.059,1.547,7.048
			c1.567,1.988,3.96,3.149,6.492,3.149h111.689c4.567,0,8.267-3.701,8.267-8.267c0-4.566-3.7-8.267-8.267-8.267h-32.429
			l-7.999-33.319h129.022c18.714,0,33.939-15.224,33.939-33.939v-56.517C445.853,300.966,442.153,297.264,437.586,297.264z
			 M222.118,429.306l7.999-33.319h35.772l7.999,33.319H222.118z"/>
	</g>
</g>
<g>
	<g>
		<path d="M346.573,92.259H75.284c-18.72,0-33.95,15.23-33.95,33.95l0.001,78.903c0,4.566,3.7,8.267,8.267,8.267
			c4.567,0,8.267-3.701,8.267-8.267l-0.001-78.903c0-9.603,7.813-17.416,17.416-17.416h271.288c4.567,0,8.267-3.701,8.267-8.267
			C354.84,95.961,351.139,92.259,346.573,92.259z"/>
	</g>
</g>
<g>
	<g>
		<path d="M413.746,344.236H210.357c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h203.389
			c4.567,0,8.267-3.701,8.267-8.267S418.312,344.236,413.746,344.236z"/>
	</g>
</g>
<g>
	<g>
		<path d="M346.573,127.476H73.455c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.7,8.267,8.267,8.267h273.118
			c4.567,0,8.267-3.701,8.267-8.267C354.84,131.178,351.139,127.476,346.573,127.476z"/>
	</g>
</g>
<g>
	<g>
		<path d="M503.733,203.388c4.567,0,8.267-3.701,8.267-8.267v-127c0-14.314-11.644-25.959-25.959-25.959h-96.886
			c-14.314,0-25.959,11.645-25.959,25.959v195.646c0,14.314,11.644,25.959,25.959,25.959h96.886
			c14.314,0,25.959-11.645,25.959-25.959v-43.844c0-4.566-3.7-8.267-8.267-8.267s-8.267,3.701-8.267,8.267v43.844
			c0,5.197-4.228,9.425-9.425,9.425h-96.886c-5.197,0-9.425-4.228-9.425-9.425V68.121c0-5.197,4.228-9.425,9.425-9.425h96.886
			c5.197,0,9.425,4.228,9.425,9.425v127.001C495.466,199.687,499.166,203.388,503.733,203.388z"/>
	</g>
</g>
<g>
	<g>
		<path d="M329.575,211.025l-20.532-20.532c-3.229-3.227-8.462-3.229-11.692,0c-3.228,3.229-3.228,8.463,0,11.692l6.42,6.42h-72.136
			c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h72.136l-6.42,6.42c-3.228,3.229-3.228,8.463,0,11.692
			c1.615,1.614,3.731,2.422,5.846,2.422c2.115,0,4.232-0.807,5.846-2.422l20.532-20.532
			C332.803,219.487,332.803,214.253,329.575,211.025z"/>
	</g>
</g>
<g>
	<g>
		<path d="M323.728,267.023h-72.136l6.42-6.42c3.229-3.229,3.229-8.463,0-11.692c-3.229-3.227-8.462-3.229-11.692,0l-20.533,20.532
			c-1.55,1.551-2.421,3.653-2.421,5.845s0.871,4.296,2.421,5.845l20.533,20.532c1.615,1.614,3.731,2.422,5.846,2.422
			c2.115,0,4.232-0.807,5.846-2.422c3.229-3.229,3.229-8.463,0-11.692l-6.42-6.42h72.136c4.566,0.002,8.266-3.699,8.266-8.265
			S328.295,267.023,323.728,267.023z"/>
	</g>
</g>
<g>
	<g>
		<path d="M480.126,86.909h-85.058c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h85.058c4.567,0,8.267-3.701,8.267-8.267
			S484.693,86.909,480.126,86.909z"/>
	</g>
</g>
<g>
	<g>
		<path d="M480.126,228.444h-85.058c-4.567,0-8.267,3.701-8.267,8.267s3.7,8.267,8.267,8.267h85.058
			c4.567,0,8.267-3.701,8.267-8.267S484.693,228.444,480.126,228.444z"/>
	</g>
</g>
<g>
	<g>
		<path d="M167.863,222.275H25.959C11.644,222.275,0,233.921,0,248.233v49.213c0,4.566,3.7,8.267,8.267,8.267
			s8.267-3.701,8.267-8.267v-49.213c0-5.197,4.228-9.425,9.425-9.425h141.904c5.197,0,9.425,4.228,9.425,9.425v195.646
			c0,5.197-4.228,9.425-9.425,9.425H25.959c-5.197,0-9.425-4.228-9.425-9.425V322.983c0-4.566-3.7-8.267-8.267-8.267
			S0,318.418,0,322.983v120.896c0,14.314,11.644,25.959,25.959,25.959h141.904c14.314,0,25.959-11.645,25.959-25.959V248.233
			C193.823,233.921,182.177,222.275,167.863,222.275z"/>
	</g>
</g>
<g>
	<g>
		<path d="M163.834,267.023H29.987c-4.567,0-8.267,3.701-8.267,8.267s3.701,8.267,8.267,8.267h133.847
			c4.567,0,8.267-3.701,8.267-8.267S168.401,267.023,163.834,267.023z"/>
	</g>
</g>
<g>
	<g>
		<path d="M163.834,408.557H29.987c-4.567,0-8.267,3.701-8.267,8.267c0,4.566,3.701,8.267,8.267,8.267h133.847
			c4.567,0,8.267-3.701,8.267-8.267C172.101,412.259,168.401,408.557,163.834,408.557z"/>
	</g>
</g>
<g>
	<g>
		<circle cx="437.597" cy="258.943" r="8.267"/>
	</g>
</g>
<g>
	<g>
		<circle cx="96.911" cy="439.526" r="8.267"/>
	</g>
</g>
</svg>
   <div id="nova"></div>
</div>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

  • Is there any way to change the image with a fade effect? not to "blink" but to lose the opacity until changing the photo.

  • Okay, thank you! I had spoken to you on Whatsapp tbm, so ignore the message there kkk, since you helped me here :D

  • take only one other doubt my please, (when you have finished the fade effect), in case of your reply your image was inserted by the same JS, by a url, how do I insert the image that will be there in my img folder?

  • definitely perfect, always see you answering various questions here on the site, very smart... real inspiration. Thanks

  • @Lukasmonteiro Thanks, obg! We do what we can. Obg!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.