Good afternoon! I put an SVG drawing on my site, and I put an animation for when the drawing is visible on the screen, start drawing animation by "completing", follow 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>Roleparabaixo<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><svgversion="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 do when the animation completes, the borders of the drawing are removed and an image is inserted? I have this vector image with a transparent background so it would look good.