several fixes
This commit is contained in:
@ -0,0 +1,75 @@
|
||||
// Karma configuration
|
||||
// Generated on Fri Jul 18 2014 10:58:08 GMT+0100 (BST)
|
||||
|
||||
module.exports = function(config) {
|
||||
var options = {
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '..',
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'test/unit.setup.js',
|
||||
'src/pathformer.js',
|
||||
'src/vivus.js',
|
||||
'test/unit/**.js'
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [],
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'../src/pathformer.js': ['coverage'],
|
||||
'../src/vivus.js': ['coverage']
|
||||
},
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress', 'coverage'],
|
||||
|
||||
// optionally, configure the reporter
|
||||
coverageReporter: {
|
||||
type: 'html',
|
||||
dir: '../coverage/'
|
||||
},
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['Chrome'],
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
singleRun: true
|
||||
};
|
||||
|
||||
if (process.env.TRAVIS) {
|
||||
options.customLaunchers = {
|
||||
Chrome_travis_ci: {
|
||||
base: 'Chrome',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
};
|
||||
options.browsers = ['Chrome_travis_ci'];
|
||||
}
|
||||
|
||||
config.set(options);
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
<svg height="300" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 404.7 354" enable-background="new 0 0 404.7 354">
|
||||
|
||||
<g stroke="#f9f9f9" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10">
|
||||
<!-- HI -->
|
||||
<path data-duration="10" d="M324.6,61.2c16.6,0,29.5-12.9,29.5-29.5c0-16.6-12.9-29.5-29.5-29.5c-16.6,0-29.5,12.9-29.5,29.5C295.1,48.4,308,61.2,324.6,61.2z"/>
|
||||
<path data-duration="130" d="M366.2,204.2c-9.8,0-15-5.6-15-15.1V77.2h-85v28h19.5c9.8,0,8.5,2.1,8.5,11.6v72.4c0,9.5,0.5,15.1-9.3,15.1H277h-20.7c-8.5,0-14.2-4.1-14.2-12.9V52.4c0-8.5,5.7-12.3,14.2-12.3h18.8v-28h-127v28h18.1c8.5,0,9.9,2.1,9.9,8.9v56.1h-75V53.4c0-11.5,8.6-13.3,17-13.3h11v-28H2.2v28h26c8.5,0,12,2.1,12,7.9v142.2c0,8.5-3.6,13.9-12,13.9h-21v33h122v-33h-11c-8.5,0-17-4.1-17-12.2v-57.8h75v58.4c0,9.1-1.4,11.6-9.9,11.6h-18.1v33h122.9h5.9h102.2v-33H366.2z"/>
|
||||
|
||||
<path data-async="" data-delay="20" d="M358.8,82.8c11.1-4.2,18.8-14.7,18.8-27.5c0-8.5-3.4-16-8.9-21.3"/>
|
||||
<path data-async="" d="M124.2,105.7V77c0-11.5,9.1-13.8,17.5-13.8h10.5V44.7"/>
|
||||
<polyline data-async="" points="147.9,40.2 171.2,63.2 175.7,63.2"/>
|
||||
<line data-async="" x1="295.1" y1="32.1" x2="275.2" y2="12.2"/>
|
||||
<path data-async="" d="M266.2,204.7V75.9c0-8.5,5.2-12.8,13.7-12.8h18.3V44.7"/>
|
||||
<polyline data-async="" points="265.9,105.2 289.2,129.2 293.7,129.2"/>
|
||||
<polyline data-async="" points="374.2,204.7 374.2,94.2 358.8,82.8 351.2,77.2"/>
|
||||
<polyline data-async="" points="148.2,237.2 171.2,261.2 294.6,261.2 300.5,261.2 402.2,261.2 402.2,228.2 379.2,204.2"/>
|
||||
<polyline data-async="" points="124.2,204.7 124.2,157.2 175.7,157.2"/>
|
||||
<line data-async="" x1="147.7" y1="228.2" x2="129.2" y2="204.2"/>
|
||||
<polyline data-async="" points="7.2,237.3 30.2,261.2 152.2,261.2 152.2,241.7"/>
|
||||
<polyline data-async="" points="1.9,40.2 26,63.2 39.7,63.2"/>
|
||||
<line data-async="" x1="129.2" y1="12.2" x2="148.2" y2="33.2"/>
|
||||
<line data-async="" x1="303.9" y1="53" x2="328.1" y2="77.2"/>
|
||||
|
||||
<line x1="345.1" y1="10.5" x2="368.7" y2="34"/>
|
||||
|
||||
<!-- there -->
|
||||
<path data-delay="30" data-duration="60" stroke-linecap="round" stroke-linejoin="round" d="M76.8,337.3c0,0,1.9,12.2,13.1,12.2c22.1,0,23.8-1.8,59-66.4c-19.7,35.7-36.4,66.2-19.3,66.2c15.2,0,22.9-14.2,28.3-23.7c3.3-0.5,24-3.2,35-25.5c4-8.1,4.1-17.8-8.1-15.2c-5.6,1.2-13.1,14.8-15.7,19.2c-7.6,12.7-22.4,45.2-22.4,45.2s10.3-22.4,21.5-22.4c15.5,0-9.4,22.4,4.7,22.4c4.9,0,11.7-11.4,16.6-20.9c7.5,4.7,19.7,1.7,24.5-8.1c10.1-20.4-14.4-12.8-24.5,8.1c-5.5,11.3-2.2,21.1,11.2,21.1c16.4,0,26.1-28.3,30.5-37.5c9.9,2.5,14,2.5,22.7-1.1c-3.5,5.1-24,38.1-8.3,38.1c6.7,0,11.7-11.4,16.6-20.9c7.5,4.7,19.7,1.7,24.5-8.1c10.1-20.4-14.4-12.8-24.5,8.1c-5.5,11.3-2.2,21.1,11.2,21.1c16.4,0,20.6-4,24.7-10.5"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M157.3,300.8c3.8-2.3-29,0.8-35.6,3.2"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,425 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>vivus.js - manual tests page</title>
|
||||
<meta name="description" content="SVG Drawing Animation" />
|
||||
|
||||
<style type="text/css">
|
||||
/* Base style */
|
||||
html {
|
||||
font-size: 24px;
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0 0 40px;
|
||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
font-weight: 200;
|
||||
color: #666666;
|
||||
background-color: #ffffff;
|
||||
word-break: break-word;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
font-weight: 100;
|
||||
}
|
||||
a,
|
||||
a:visited,
|
||||
a:hover,
|
||||
a:link {
|
||||
color: inherit;
|
||||
outline: 0;
|
||||
}
|
||||
small {
|
||||
font-weight: 100;
|
||||
}
|
||||
p {
|
||||
font-size: 1rem;
|
||||
line-height: 1.4rem;
|
||||
}
|
||||
button,
|
||||
.button {
|
||||
margin: 0;
|
||||
padding: 3px 6px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid currentColor;
|
||||
color: inherit;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
font-size: 0.6rem;
|
||||
font-weight: 300;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
}
|
||||
button.active,
|
||||
.button.active {
|
||||
background-color: currentColor;
|
||||
}
|
||||
button.active span,
|
||||
.button.active span {
|
||||
color: #ffffff;
|
||||
}
|
||||
i {
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
border-radius: 4px;
|
||||
}
|
||||
svg * {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table,
|
||||
th,
|
||||
td {
|
||||
border: 1px solid currentColor;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.content {
|
||||
margin: auto;
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.section {
|
||||
min-height: 90%;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.warning {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border: 1px solid currentColor;
|
||||
color: #fff;
|
||||
background-color: #c00;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.box-50 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
/* Themes */
|
||||
.intro {
|
||||
display: block;
|
||||
}
|
||||
.sunrise {
|
||||
color: #f037a5;
|
||||
background-color: #f8c72c;
|
||||
}
|
||||
.matrix {
|
||||
color: #86e0c4;
|
||||
background-color: #181f21;
|
||||
}
|
||||
.electric {
|
||||
color: #78c9db;
|
||||
background-color: #e4175b;
|
||||
}
|
||||
.night {
|
||||
color: #d3d679;
|
||||
background-color: #316bd2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="section intro">
|
||||
<h2>Vivus manual (cheap) tests.</h2>
|
||||
<p>
|
||||
Just scroll along the page and if a glitch appear or the visual
|
||||
appearance is not like the description, it's not good.
|
||||
</p>
|
||||
<p id="config-instructions" class="warning hidden">
|
||||
To use this page you must use an HTTP server to serve files. Run
|
||||
<i>npm run serve</i> in the repository then go to the
|
||||
<a href="http://127.0.0.1:8844/test/manual">test page</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="section matrix">
|
||||
<div class="content">
|
||||
<div class="box box-50">
|
||||
<p>
|
||||
This should display the obturateur SVG like on the demo page. The
|
||||
strokes must be orange. The element must remain an
|
||||
<i>object</i> tag.
|
||||
</p>
|
||||
<button
|
||||
onclick="this.textContent=(document.querySelector('object#obt')?'Pass!':'Failed.')"
|
||||
>
|
||||
Test
|
||||
</button>
|
||||
</div>
|
||||
<div class="box box-50">
|
||||
<object
|
||||
id="obt"
|
||||
data="obturateur.svg"
|
||||
type="image/svg+xml"
|
||||
style="width: 100%; max-height: 250px"
|
||||
></object>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section sunrise">
|
||||
<div class="content">
|
||||
<div class="box box-50">
|
||||
<div id="polaroid-dynamic"></div>
|
||||
</div>
|
||||
<div class="box box-50">
|
||||
<p>
|
||||
This should display the polaroid SVG like on the demo page. The
|
||||
strokes must have the same color as this text.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section electric">
|
||||
<div class="content">
|
||||
<div class="box box-50">
|
||||
<p>
|
||||
This should display the 'Hi there' SVG like ready to start. Be sure
|
||||
no glitch appear (no small path or dots). Click on the following
|
||||
button to start.
|
||||
</p>
|
||||
<button onclick="hiD.play();">Start</button>
|
||||
</div>
|
||||
<div class="box box-50">
|
||||
<div id="hi-dynamic" style="max-width: 300px; margin: auto"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section night">
|
||||
<div class="content">
|
||||
<div class="box box-50">
|
||||
<div id="synth-dynamic" style="max-width: 400px; margin: auto"></div>
|
||||
</div>
|
||||
<div class="box box-50">
|
||||
<p>
|
||||
This should display a synth ready to start. Be sure no glitch appear
|
||||
(no small path or dots). The animation should use a custom path
|
||||
timing function (ease_in: slow at start then finish fast.). Click on
|
||||
the following button to start.
|
||||
</p>
|
||||
<button onclick="synthD.play();">Start</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section electric">
|
||||
<div class="content">
|
||||
<table id="nonScaling">
|
||||
<tr style="height: 16.66%">
|
||||
<td style="width: 16.66%">
|
||||
<svg viewBox="0 0 100 100" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(.5,.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td style="width: 33.33%">
|
||||
<svg viewBox="0 0 200 100" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1,.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td style="width: 50%">
|
||||
<svg viewBox="0 0 300 100" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1.5,.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="height: 33.33%">
|
||||
<td>
|
||||
<svg viewBox="0 0 100 200" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(.5,1)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td>
|
||||
<svg viewBox="0 0 200 200" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1,1)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td>
|
||||
<svg viewBox="0 0 300 200" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1.5,1)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="height: 50%">
|
||||
<td>
|
||||
<svg viewBox="0 0 100 300" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(.5,1.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td>
|
||||
<svg viewBox="0 0 200 300" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1,1.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td>
|
||||
<svg viewBox="0 0 300 300" width="100%" height="100%">
|
||||
<line
|
||||
vector-effect="non-scaling-stroke"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="200"
|
||||
y2="200"
|
||||
transform="scale(1.5,1.5)"
|
||||
/>
|
||||
</svg>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Non scaling path<br />In any case of a resize, the animation of each
|
||||
line must be complete.
|
||||
</p>
|
||||
<button onclick="nonScalingResize();">Resize</button>
|
||||
<button onclick="nonScalingReplay();">Replay</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Le scripts -->
|
||||
<script src="/dist/vivus.js"></script>
|
||||
<script>
|
||||
// Display warning message if not on http server
|
||||
if (window.location.protocol === 'file:') {
|
||||
var configIntro = document.getElementById('config-instructions');
|
||||
configIntro.style.display = 'block';
|
||||
}
|
||||
|
||||
// Obturateur
|
||||
var obt1 = new Vivus('obt', {
|
||||
type: 'delayed',
|
||||
duration: 150,
|
||||
});
|
||||
|
||||
// polaroid-dynamic
|
||||
var polaroidD = new Vivus('polaroid-dynamic', {
|
||||
file: 'polaroid.svg',
|
||||
type: 'scenario-sync',
|
||||
duration: 20,
|
||||
});
|
||||
|
||||
var hiD = new Vivus('hi-dynamic', {
|
||||
file: 'hi-there.svg',
|
||||
type: 'scenario-sync',
|
||||
duration: 20,
|
||||
start: 'manual',
|
||||
});
|
||||
|
||||
var synthD = new Vivus('synth-dynamic', {
|
||||
file: 'synth.svg',
|
||||
type: 'oneByOne',
|
||||
duration: 200,
|
||||
start: 'manual',
|
||||
animTimingFunction: Vivus.EASE_IN,
|
||||
});
|
||||
|
||||
// Non scaling
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
nonScalingVivuses.forEach((v) => v.recalc());
|
||||
});
|
||||
resizeObserver.observe(window.nonScaling);
|
||||
|
||||
var nonScalingVivuses = Array.from(
|
||||
document.querySelectorAll('#nonScaling svg')
|
||||
).map((svg) => new Vivus(svg, { start: 'autostart' }));
|
||||
|
||||
function nonScalingResize() {
|
||||
const newWidth = Math.floor(Math.random() * 100);
|
||||
const newHeight = Math.floor(Math.random() * 100);
|
||||
window.nonScaling.style.width = `${newWidth}%`;
|
||||
window.nonScaling.style.height = `${newHeight}%`;
|
||||
nonScalingVivuses.forEach((v) => v.recalc());
|
||||
}
|
||||
|
||||
function nonScalingReplay() {
|
||||
nonScalingVivuses.forEach((v) => v.reset().play());
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="100%" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200">
|
||||
<g stroke="#f60" fill="none" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" >
|
||||
<circle cx="100" cy="100" r="90"/>
|
||||
<circle cx="100" cy="100" r="85.74"/>
|
||||
<circle cx="100" cy="100" r="72.947"/>
|
||||
<circle cx="100" cy="100" r="39.74"/>
|
||||
<line x1="34.042" y1="131.189" x2="67.047" y2="77.781"/>
|
||||
<line x1="31.306" y1="75.416" x2="92.41" y2="60.987"/>
|
||||
<line x1="68.81" y1="34.042" x2="122.219" y2="67.046"/>
|
||||
<line x1="124.584" y1="31.305" x2="139.013" y2="92.409"/>
|
||||
<line x1="165.957" y1="68.809" x2="132.953" y2="122.219"/>
|
||||
<line x1="168.693" y1="124.584" x2="107.59" y2="139.012"/>
|
||||
<line x1="131.19" y1="165.957" x2="77.781" y2="132.953"/>
|
||||
<line x1="75.417" y1="168.693" x2="60.987" y2="107.59"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 910 B |
@ -0,0 +1,62 @@
|
||||
<svg id="polaroid" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 200 160" enable-background="new 0 0 200 160">
|
||||
|
||||
<g stroke="#f9f9f9" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10">
|
||||
|
||||
<!-- Case -->
|
||||
<!-- The case items will be drawn at the same time (attribute `data-async` on each tag) with a custom duration of 40 frames (attribute `data-duration`). WARNING: When you want to draw a bloc asynchronously (like here), the last item need to be `data-async` free. Otherwise the following tags will also start at the same time. I know it's a bit confusing, play a bit with it and you'll see. -->
|
||||
<path data-async="" data-duration="40" d="
|
||||
M106.725,104.742c-0.773,2.498-3.586,4.229-6.285,3.867L12.473,96.802c-2.699-0.363-4.262-2.682-3.49-5.18l25.164-81.436
|
||||
c0.771-2.496,3.584-4.229,6.283-3.866l87.966,11.808c2.699,0.362,4.264,2.68,3.49,5.179L106.725,104.742z"/>
|
||||
<path data-async="" data-duration="40" d="
|
||||
M101.02,123.207c-0.773,2.5-3.587,4.23-6.286,3.867L6.766,115.27c-2.699-0.363-4.26-2.682-3.488-5.182l2.91-9.417
|
||||
c0.771-2.499,3.585-4.23,6.285-3.87l87.967,11.809c2.699,0.361,4.261,2.682,3.49,5.18L101.02,123.207z"/>
|
||||
<line data-async="" data-duration="40" x1="103.377" y1="128.225" x2="154.768" y2="155.32"/>
|
||||
<line data-async="" data-duration="40" x1="109.852" y1="112.684" x2="155.035" y2="136.906"/>
|
||||
<path data-async="" data-duration="40" d="
|
||||
M9.096,120.207l47.932,21.994c0,0,98.06,12.414,97.74,13.119c-0.318,0.709,5.426-16.205,5.426-16.205l-2.646-96.842
|
||||
c-1.098-7.587-2.467-11.8-8.559-15.024l-12.635-6.604"/>
|
||||
<path data-async="" data-duration="40" d="
|
||||
M161.586,38.135l30.717,16.085c0,0,5.295,2.323,4.543,6.504l-3.215,10.527c-0.648,2.621-2.939,4.988-8.229,2.798l-9.154-4.701
|
||||
l-11.834,56.441"/>
|
||||
<path data-duration="40" d="
|
||||
M183.148,49.518c0,0,5.295,2.324,4.543,6.506l-3.215,10.526c-0.648,2.622-2.938,4.988-8.229,2.798"/>
|
||||
|
||||
<!-- Lens -->
|
||||
<!-- All item will be drawn line by line, with an exception for the first one, a little delay (attribute `data-delay) to make a break between the drawing of the case and the start of the lens part -->
|
||||
<path data-delay="20" d="
|
||||
M87.176,56.143C83.274,68.78,69.043,77.538,55.395,75.706S33.846,62.146,37.75,49.511c3.903-12.637,18.135-21.392,31.783-19.562
|
||||
C83.181,31.782,91.081,43.51,87.176,56.143z"/>
|
||||
<path d="
|
||||
M92.745,56.891c-4.785,15.48-22.219,26.213-38.942,23.969C37.079,78.615,27.4,64.245,32.184,48.763
|
||||
c4.783-15.48,22.218-26.211,38.94-23.968C87.848,27.041,97.528,41.411,92.745,56.891z"/>
|
||||
<path d="
|
||||
M78.99,26.933c16.169,7.426,19.398,10.989,22.026,20.105c1.283,4.449,1.271,9.411-0.3,14.489
|
||||
c-4.783,15.479-22.217,26.213-38.941,23.969c-8.68-1.165-21.171-7.963-25.613-14.055"/>
|
||||
<path d="
|
||||
M42.602,50.162c3.137-10.157,14.573-17.193,25.543-15.722"/>
|
||||
|
||||
<!-- Flash -->
|
||||
<!-- This tag does not have any extra attribute. So it will start when the previous tag is finished. His duration and delay will be the one given in the options. -->
|
||||
<path d="
|
||||
M103.789,29.275c-0.568,1.841,0.582,3.549,2.57,3.818l12.807,1.72c1.988,0.266,4.062-1.012,4.633-2.851l1.66-5.38
|
||||
c0.568-1.843-0.582-3.551-2.57-3.816l-12.807-1.72c-1.988-0.268-4.062,1.01-4.633,2.85L103.789,29.275z"/>
|
||||
|
||||
<!-- Output -->
|
||||
<!-- Same case as Flash -->
|
||||
<path d="
|
||||
M11.129,105.791c-0.297,0.965,0.305,1.855,1.346,1.994l81.446,10.932c1.038,0.141,2.123-0.527,2.42-1.49l0,0
|
||||
c0.298-0.961-0.304-1.855-1.343-1.996l-81.447-10.93C12.51,104.16,11.426,104.828,11.129,105.791L11.129,105.791z"/>
|
||||
|
||||
<!-- Design (color lines on the front) -->
|
||||
<!-- All the lines will start at the same time, because they all have the attribute `data-async` -->
|
||||
<line data-async="" x1="47.583" y1="101.505" x2="51.561" y2="88.267"/>
|
||||
<line data-async="" x1="53.391" y1="102.326" x2="57.047" y2="90.125"/>
|
||||
<line data-async="" x1="59.224" y1="103.068" x2="62.749" y2="91.295"/>
|
||||
<line data-async="" x1="65.057" y1="103.814" x2="69.015" y2="90.637"/>
|
||||
<line data-async="" x1="72.87" y1="19.969" x2="75.497" y2="11.082"/>
|
||||
<line data-async="" x1="78.512" y1="21.325" x2="81.317" y2="11.868"/>
|
||||
<line data-async="" x1="83.833" y1="23.718" x2="87.16" y2="12.582"/>
|
||||
<line data-async="" x1="89.145" y1="26.141" x2="92.939" y2="13.498"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="378.995px" height="259.5px" viewBox="0 0 378.995 259.5" enable-background="new 0 0 378.995 259.5" xml:space="preserve">
|
||||
<g id="Synth">
|
||||
<path fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M375.5,108.934c1.549,2.693,0.627,5.739-2.059,6.804L72.043,235.257c-2.685,1.064-6.116-0.254-7.665-2.946L5.362,129.69
|
||||
c-1.548-2.692-0.625-5.737,2.059-6.802L308.818,3.369c2.686-1.065,6.117,0.254,7.666,2.946L375.5,108.934z"/>
|
||||
<path fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M376.246,111.47l-2.068,18.344c0,0-0.621,5.361-4.932,7.726L69.601,256.365c-2.685,1.064-6.116-0.254-7.665-2.946L3.693,152.145
|
||||
c-1.548-2.692-0.878-9.891-0.878-9.891l0.82-7.014"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="373.785" y1="112.765" x2="371.715" y2="130.65"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="70.318" y1="250.17" x2="371.715" y2="130.65"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="319.578" y1="22.078" x2="19.852" y2="140.935"/>
|
||||
|
||||
<polyline fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
19.852,140.935 72.387,232.284 70.318,250.17 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="371.715" y1="130.65" x2="365.053" y2="119.063"/>
|
||||
<g id="octaves_1_">
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="93.572" y1="226.72" x2="73.09" y2="191.106"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="114.616" y1="218.126" x2="94.134" y2="182.512"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="136.629" y1="209.646" x2="82.765" y2="115.986"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="158.158" y1="201.108" x2="137.674" y2="165.493"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="179.688" y1="192.572" x2="159.203" y2="156.957"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="201.213" y1="184.034" x2="180.732" y2="148.419"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="222.742" y1="175.497" x2="168.879" y2="81.838"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="244.27" y1="166.959" x2="223.789" y2="131.346"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="265.799" y1="158.423" x2="245.318" y2="122.809"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="287.328" y1="149.886" x2="233.463" y2="56.226"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="308.855" y1="141.349" x2="288.375" y2="105.734"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="330.385" y1="132.812" x2="309.902" y2="97.197"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="351.912" y1="124.274" x2="331.432" y2="88.66"/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="373.441" y1="115.737" x2="319.578" y2="22.078"/>
|
||||
</g>
|
||||
<g id="bemols_1_">
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
67.427,190.815 35.241,134.85 39.708,133.061 44.176,131.271 76.24,177.929 76.362,187.236 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
69.3,180.708 36.616,135.539 44.606,132.34 76.24,177.929 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="69.077" y1="183.09" x2="68.222" y2="187.702"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
89.117,182.213 56.931,126.247 61.398,124.458 65.866,122.669 97.93,169.326 98.052,178.634 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
90.99,172.105 58.306,126.937 66.295,123.736 97.93,169.326 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="90.767" y1="174.487" x2="89.912" y2="179.1"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
132.012,165.204 99.826,109.238 104.293,107.449 108.762,105.661 140.825,152.317 140.948,161.625 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
133.885,155.098 101.202,109.928 109.191,106.728 140.825,152.317 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="133.661" y1="157.479" x2="132.807" y2="162.091"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
153.541,156.666 121.354,100.7 125.821,98.911 130.289,97.122 162.354,143.779 162.475,153.088 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
155.416,146.559 122.729,101.39 130.719,98.19 162.354,143.779 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="155.191" y1="148.94" x2="154.335" y2="153.554"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
175.068,148.129 142.881,92.164 147.348,90.374 151.817,88.585 183.881,135.242 184.004,144.551 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
176.941,138.021 144.256,92.853 152.247,89.653 183.881,135.242 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="176.719" y1="140.403" x2="175.863" y2="145.017"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
218.127,131.056 185.939,75.089 190.406,73.3 194.875,71.512 226.938,118.169 227.061,127.476 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
220,120.948 187.314,75.778 195.305,72.579 226.938,118.169 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="219.775" y1="123.329" x2="218.922" y2="127.942"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
239.656,122.518 207.469,66.553 211.936,64.763 216.402,62.975 248.467,109.631 248.59,118.939 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
241.529,112.411 208.844,67.241 216.834,64.042 248.467,109.631 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="241.305" y1="114.792" x2="240.449" y2="119.405"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
282.713,105.443 250.525,49.478 254.992,47.688 259.459,45.9 291.523,92.558 291.646,101.864 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
284.584,95.337 251.902,50.168 259.891,46.968 291.523,92.558 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="284.361" y1="97.718" x2="283.508" y2="102.33"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
304.24,96.906 272.055,40.941 276.52,39.151 280.988,37.363 313.053,84.02 313.174,93.328 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
306.113,86.8 273.43,41.631 281.42,38.431 313.053,84.02 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="305.891" y1="89.181" x2="305.035" y2="93.794"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
325.768,88.369 293.582,32.404 298.049,30.614 302.518,28.825 334.58,75.482 334.703,84.791 "/>
|
||||
|
||||
<polygon fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
327.641,78.262 294.957,33.093 302.947,29.894 334.58,75.482 "/>
|
||||
|
||||
<line fill="none" stroke="#241F20" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="327.418" y1="80.644" x2="326.562" y2="85.257"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,14 @@
|
||||
/* Here is a cheap and bad implementation
|
||||
* of requestAnimationFrame and
|
||||
* cancelAnimationFrame mock.
|
||||
* But it's more than enough
|
||||
* for our tests.
|
||||
*/
|
||||
window.requestAnimFrameStack = [];
|
||||
window.requestAnimationFrame = function (callback) {
|
||||
window.requestAnimFrameStack.push(callback);
|
||||
return true;
|
||||
};
|
||||
window.cancelAnimationFrame = function () {
|
||||
window.requestAnimFrameStack = [];
|
||||
};
|
@ -0,0 +1,322 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Unit tests for Pathformer
|
||||
*
|
||||
*/
|
||||
describe('Pathformer', function () {
|
||||
|
||||
var svgTag,
|
||||
svgTagId = 'my-svg',
|
||||
svgGroupTag,
|
||||
svgGroupTagId = 'my-svg-group';
|
||||
|
||||
beforeEach(function () {
|
||||
// Remove tag if existing
|
||||
svgTag = document.getElementById(svgTagId);
|
||||
if (svgTag) {
|
||||
svgTag.remove();
|
||||
}
|
||||
|
||||
// Create the SVG
|
||||
svgTag = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
svgTag.id = svgTagId;
|
||||
svgTag.innerHTML = '<circle fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" cx="100" cy="100" r="72.947"/>' +
|
||||
'<circle fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" cx="100" cy="100" r="39.74"/>' +
|
||||
'<g id="' + svgGroupTagId + '">' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="34.042" y1="131.189" x2="67.047" y2="77.781"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="165.957" y1="68.809" x2="132.953" y2="122.219"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="131.19" y1="165.957" x2="77.781" y2="132.953"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="68.81" y1="34.042" x2="122.219" y2="67.046"/>' +
|
||||
'</g>';
|
||||
|
||||
svgGroupTag = svgTag.querySelector('#'+svgGroupTagId);
|
||||
|
||||
// Insert it to the body
|
||||
document.body.appendChild(svgTag);
|
||||
});
|
||||
|
||||
describe('[param tests]', function () {
|
||||
|
||||
// Tests about the SVG element
|
||||
it('should throw an error if the SVG is given in parameter', function () {
|
||||
expect(function () {
|
||||
new Pathformer();
|
||||
}).toThrow(new Error('Pathformer [constructor]: "element" parameter is required'));
|
||||
});
|
||||
|
||||
it('should work with only the SVG id', function () {
|
||||
expect(function () {
|
||||
new Pathformer(svgTagId);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should work with only the SVG object', function () {
|
||||
expect(function () {
|
||||
new Pathformer(svgTag);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should work with only the SVG group object', function () {
|
||||
expect(function () {
|
||||
new Pathformer(svgGroupTag);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if the SVG ID given is invalid', function () {
|
||||
expect(function () {
|
||||
new Pathformer('my-unexisting-svg');
|
||||
}).toThrow(new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'));
|
||||
});
|
||||
|
||||
it('should throw an error if the ID given is not related to a SVG element', function () {
|
||||
var divTag = document.createElement('div');
|
||||
divTag.id = 'my-div';
|
||||
document.body.appendChild(divTag);
|
||||
expect(function () {
|
||||
new Pathformer('my-div');
|
||||
}).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
});
|
||||
|
||||
it('should throw an error if the element is not a correct type (DOM object or string)', function () {
|
||||
expect(function () { new Pathformer({}); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
expect(function () { new Pathformer(42); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
expect(function () { new Pathformer(false); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
expect(function () { new Pathformer(new Date()); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
expect(function () { new Pathformer(function () {}); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
expect(function () { new Pathformer(document.createElement('div')); }).toThrow(new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('[translation]', function () {
|
||||
|
||||
// Line object
|
||||
describe('line', function () {
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.lineToPath({});
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with an unclosed shape', function () {
|
||||
var output = Pathformer.prototype.lineToPath({});
|
||||
expect(output.d.substr(-1)).not.toEqual('Z');
|
||||
});
|
||||
|
||||
it('should set default positino attributes to zero', function () {
|
||||
var output = Pathformer.prototype.lineToPath({
|
||||
x1: '21', x2: '32', y1: '11'
|
||||
});
|
||||
expect(output.d.indexOf('0')).not.toEqual(-1);
|
||||
expect(output.d.indexOf('undefined')).toEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
// Rect object
|
||||
describe('rect', function () {
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.rectToPath({});
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with a closed shape', function () {
|
||||
var output = Pathformer.prototype.rectToPath({});
|
||||
expect(output.d.substr(-1)).toEqual('Z');
|
||||
});
|
||||
|
||||
it('should set default positino attributes to zero', function () {
|
||||
var output = Pathformer.prototype.rectToPath({
|
||||
x: '21', height: '32', width: '11'
|
||||
});
|
||||
expect(output.d.indexOf('0')).not.toEqual(-1);
|
||||
expect(output.d.indexOf('undefined')).toEqual(-1);
|
||||
});
|
||||
|
||||
it('should apply rounded corners', function () {
|
||||
var result = 'M 50,10 ' +
|
||||
'L 50,10 A 40,20,0,0,1,90,30 ' +
|
||||
'L 90,50 A 40,20,0,0,1,50,70 ' +
|
||||
'L 50,70 A 40,20,0,0,1,10,50 ' +
|
||||
'L 10,30 A 40,20,0,0,1,50,10';
|
||||
|
||||
var output = Pathformer.prototype.rectToPath({
|
||||
x:10, y:10, width:80, height:60, rx:100, ry:20
|
||||
});
|
||||
|
||||
expect(output.d).toEqual(result);
|
||||
});
|
||||
|
||||
it('should apply rounded corners even when a value is missing', function () {
|
||||
var result = 'M 30,10 ' +
|
||||
'L 70,10 A 20,20,0,0,1,90,30 ' +
|
||||
'L 90,50 A 20,20,0,0,1,70,70 ' +
|
||||
'L 30,70 A 20,20,0,0,1,10,50 ' +
|
||||
'L 10,30 A 20,20,0,0,1,30,10';
|
||||
|
||||
var output = Pathformer.prototype.rectToPath({
|
||||
x:10, y:10, width:80, height:60, ry:20
|
||||
});
|
||||
|
||||
expect(output.d).toEqual(result);
|
||||
});
|
||||
});
|
||||
|
||||
// Polyline object
|
||||
describe('polyline', function () {
|
||||
var polyline;
|
||||
beforeEach(function () {
|
||||
polyline = {
|
||||
points: '2,3 4,5 6,7'
|
||||
};
|
||||
});
|
||||
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.polylineToPath(polyline);
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with an unclosed shape', function () {
|
||||
var output = Pathformer.prototype.polylineToPath(polyline);
|
||||
expect(output.d.substr(-1)).not.toEqual('Z');
|
||||
});
|
||||
|
||||
it('should ignore incorrect points', function () {
|
||||
var output;
|
||||
polyline.points += ' 43';
|
||||
output = Pathformer.prototype.polylineToPath(polyline);
|
||||
expect(output.d.indexOf('43')).toEqual(-1);
|
||||
});
|
||||
|
||||
it('should accept points defined with and without commas', function () {
|
||||
var outputWithPoint = Pathformer.prototype.polylineToPath(polyline);
|
||||
var outputWithoutPoint = Pathformer.prototype.polylineToPath({points: '2 3 4 5 6 7'});
|
||||
expect(outputWithPoint).toEqual(outputWithoutPoint);
|
||||
});
|
||||
});
|
||||
|
||||
// Polygon object
|
||||
describe('polygon', function () {
|
||||
var polygon;
|
||||
beforeEach(function () {
|
||||
polygon = {
|
||||
points: '2,3 4,5 6,7'
|
||||
};
|
||||
});
|
||||
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.polygonToPath(polygon);
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with a closed shape', function () {
|
||||
var output = Pathformer.prototype.polygonToPath(polygon);
|
||||
expect(output.d.substr(-1)).toEqual('Z');
|
||||
});
|
||||
});
|
||||
|
||||
// Ellipse object
|
||||
describe('ellipse', function () {
|
||||
|
||||
var ellipse;
|
||||
beforeEach(function () {
|
||||
ellipse = {
|
||||
cx: 2,
|
||||
cy: 3,
|
||||
rx: 3
|
||||
};
|
||||
});
|
||||
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.ellipseToPath(ellipse);
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with an unclosed shape', function () {
|
||||
var output = Pathformer.prototype.ellipseToPath(ellipse);
|
||||
expect(output.d.substr(-1)).not.toEqual('Z');
|
||||
});
|
||||
|
||||
it('should set default positino attributes to zero', function () {
|
||||
delete ellipse.cy;
|
||||
var output = Pathformer.prototype.ellipseToPath(ellipse);
|
||||
expect(output.d.indexOf('0')).not.toEqual(-1);
|
||||
expect(output.d.indexOf('undefined')).toEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
// Circle object
|
||||
describe('circle', function () {
|
||||
|
||||
var circle;
|
||||
beforeEach(function () {
|
||||
circle = {
|
||||
cx: 2,
|
||||
cy: 3,
|
||||
rx: 3,
|
||||
r: 1
|
||||
};
|
||||
});
|
||||
|
||||
it('should return an object with a `d` attribute', function () {
|
||||
var output = Pathformer.prototype.circleToPath(circle);
|
||||
expect(output.d).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return an object with an unclosed shape', function () {
|
||||
var output = Pathformer.prototype.circleToPath(circle);
|
||||
expect(output.d.substr(-1)).not.toEqual('Z');
|
||||
});
|
||||
|
||||
it('should set default positino attributes to zero', function () {
|
||||
delete circle.cy;
|
||||
var output = Pathformer.prototype.circleToPath(circle);
|
||||
expect(output.d.indexOf('0')).not.toEqual(-1);
|
||||
expect(output.d.indexOf('undefined')).toEqual(-1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('[utils]', function () {
|
||||
|
||||
describe('attribute parser', function () {
|
||||
it('should return an empty object if attributes length are undefined', function () {
|
||||
var output = Pathformer.prototype.parseAttr({});
|
||||
expect(output).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('engine', function () {
|
||||
it('shouldn\'t throw an error if the SVG got a tag not taken in charge', function () {
|
||||
svgTag.innerHTML = '<polypentagoneofhell fill="none" stroke="#666666" stroke-width="6" stroke-miterlimit="666" cx="666" cy="666"/>';
|
||||
|
||||
expect(function () {
|
||||
new Pathformer(svgTagId);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should remove useless attributes during transformation', function () {
|
||||
new Pathformer(svgTagId);
|
||||
expect(svgTag.childNodes[0].getAttribute('cx')).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validity', function () {
|
||||
it('should throw error if the SVG contain shape with percentage value', function () {
|
||||
// Create the SVG
|
||||
var svgTagPrc = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
svgTagPrc.innerHTML = '<circle cx="100%" cy="100" r="10"/>';
|
||||
expect(function () {
|
||||
new Pathformer(svgTagPrc);
|
||||
}).toThrow(new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'));
|
||||
});
|
||||
|
||||
it('shouldn\'t throw error if the SVG contain shape with percentage value on a non-data attribute', function () {
|
||||
// Create the SVG
|
||||
var svgTagPrc = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
svgTagPrc.innerHTML = '<circle width="100%" cx="100" cy="100" r="10"/>';
|
||||
expect(function () {
|
||||
new Pathformer(svgTagPrc);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,669 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Unit tests for Vivus
|
||||
*
|
||||
*/
|
||||
describe('Vivus', function () {
|
||||
|
||||
var ObjectElementMock,
|
||||
triggerFrames,
|
||||
myVivus,
|
||||
objTag,
|
||||
wrapTag,
|
||||
svgTag,
|
||||
svgTagId = 'my-svg',
|
||||
svgGroupTagId = 'my-svg-group';
|
||||
|
||||
// Mock ObjectElement and it's constructor via createElement
|
||||
ObjectElementMock = function () {
|
||||
this.loadCb = [];
|
||||
this.attr = {};
|
||||
this.addEventListener = function (evtName, cb) {
|
||||
if (evtName === 'load') {
|
||||
this.loadCb.push(cb);
|
||||
}
|
||||
};
|
||||
this.loaded = function () {
|
||||
for (var i = 0; i < this.loadCb.length; i++) {
|
||||
this.loadCb[i]({target: this});
|
||||
}
|
||||
};
|
||||
this.getBoundingClientRect = function () {
|
||||
return {
|
||||
height: 11,
|
||||
top: 364
|
||||
};
|
||||
};
|
||||
this.insertBefore = function () {};
|
||||
this.removeChild = function () {};
|
||||
this.setAttribute = function (key, val) {
|
||||
this.attr[key] = val;
|
||||
};
|
||||
this.getAttribute = function (key) {
|
||||
return this.attr[key];
|
||||
};
|
||||
};
|
||||
window.HTMLObjectElement = ObjectElementMock;
|
||||
|
||||
triggerFrames = function (counter) {
|
||||
counter = counter || -1;
|
||||
while (window.requestAnimFrameStack.length && counter !== 0) {
|
||||
window.requestAnimFrameStack.shift()();
|
||||
counter--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
// Create the SVG
|
||||
svgTag = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
svgTag.id = svgTagId;
|
||||
svgTag.innerHTML = '<circle fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" cx="100" cy="100" r="72.947"/>' +
|
||||
'<circle fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" cx="100" cy="100" r="39.74"/>' +
|
||||
'<g id="' + svgGroupTagId + '">' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="34.042" y1="131.189" x2="67.047" y2="77.781"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="165.957" y1="68.809" x2="132.953" y2="122.219"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="131.19" y1="165.957" x2="77.781" y2="132.953"/>' +
|
||||
'<line fill="none" stroke="#f9f9f9" stroke-width="3" stroke-miterlimit="10" x1="68.81" y1="34.042" x2="122.219" y2="67.046"/>' +
|
||||
'</g>';
|
||||
|
||||
wrapTag = document.createElement('div');
|
||||
wrapTag.appendChild(svgTag);
|
||||
|
||||
document.body.appendChild(wrapTag);
|
||||
|
||||
// Reset the request anim frame stack
|
||||
window.requestAnimFrameStack = [];
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
// Remove tag
|
||||
svgTag.remove();
|
||||
wrapTag.remove();
|
||||
});
|
||||
|
||||
describe('[basic tests]', function () {
|
||||
|
||||
it('should the class be defined under Vivus name', function () {
|
||||
expect(Vivus).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have timing functions set', function () {
|
||||
expect(Vivus.LINEAR).toBeDefined();
|
||||
expect(Vivus.EASE).toBeDefined();
|
||||
expect(Vivus.EASE_IN).toBeDefined();
|
||||
expect(Vivus.EASE_OUT).toBeDefined();
|
||||
expect(Vivus.EASE_OUT_BOUNCE).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have timing functions returning correct value on limits', function () {
|
||||
expect(Vivus.LINEAR(0)).toEqual(0);
|
||||
expect(Vivus.LINEAR(1)).toEqual(1);
|
||||
expect(Vivus.EASE(0)).toEqual(0);
|
||||
expect(Vivus.EASE(1)).toEqual(1);
|
||||
expect(Vivus.EASE_IN(0)).toEqual(0);
|
||||
expect(Vivus.EASE_IN(1)).toEqual(1);
|
||||
expect(Vivus.EASE_OUT(0)).toEqual(0);
|
||||
expect(Vivus.EASE_OUT(1)).toEqual(1);
|
||||
expect(Vivus.EASE_OUT_BOUNCE(0)).toEqual(0);
|
||||
expect(Vivus.EASE_OUT_BOUNCE(1)).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[param tests]', function () {
|
||||
|
||||
// Tests about the SVG element
|
||||
it('should throw an error if the SVG is given in parameter', function () {
|
||||
expect(function () {
|
||||
new Vivus();
|
||||
}).toThrow(new Error('Vivus [constructor]: "element" parameter is required'));
|
||||
});
|
||||
|
||||
it('should work with only the SVG id', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTagId);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should work with only the SVG object', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should work with the SVG group object', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgGroupTagId);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if the SVG ID given is invalid', function () {
|
||||
expect(function () {
|
||||
new Vivus('my-unexisting-svg');
|
||||
}).toThrow(new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'));
|
||||
});
|
||||
|
||||
it('should throw an error if the ID given is not related to a SVG element', function () {
|
||||
var divTag = document.createElement('div');
|
||||
divTag.id = 'my-div';
|
||||
document.body.appendChild(divTag);
|
||||
expect(function () {
|
||||
new Vivus('my-div');
|
||||
}).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
});
|
||||
|
||||
it('should accept any DOM element if `file` option is set', function () {
|
||||
var divTag = document.createElement('div');
|
||||
spyOn(window, 'XMLHttpRequest');
|
||||
try {
|
||||
new Vivus(divTag, {file: 'opensource.svg'});
|
||||
}
|
||||
catch(err) {}
|
||||
|
||||
expect(window.XMLHttpRequest).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw an error if the element is not a correct type (DOM object or string)', function () {
|
||||
expect(function () { new Vivus({}); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
expect(function () { new Vivus(42); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
expect(function () { new Vivus(false); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
expect(function () { new Vivus(new Date()); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
expect(function () { new Vivus(function () {}); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
expect(function () { new Vivus(document.createElement('div')); }).toThrow(new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'));
|
||||
});
|
||||
|
||||
it('should accept object element', function () {
|
||||
// Create a mock Object getElementById
|
||||
objTag = new ObjectElementMock();
|
||||
objTag.contentDocument = wrapTag;
|
||||
|
||||
expect(function () {
|
||||
new Vivus(objTag);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('the vivus state should be ready if the SVG is already loaded', function () {
|
||||
objTag = new ObjectElementMock();
|
||||
objTag.contentDocument = wrapTag;
|
||||
objTag.loaded();
|
||||
var myVivus = new Vivus(objTag);
|
||||
expect(myVivus.isReady).toEqual(true);
|
||||
});
|
||||
|
||||
it('the vivus instance should have `el` and `parentEl` different if the element is an object', function () {
|
||||
objTag = new ObjectElementMock();
|
||||
objTag.contentDocument = wrapTag;
|
||||
objTag.loaded();
|
||||
var myVivus = new Vivus(objTag);
|
||||
expect(myVivus.parentEl).not.toEqual(myVivus.el);
|
||||
});
|
||||
|
||||
it('should call `onReady` callback once the SVG is loaded', function () {
|
||||
objTag = new ObjectElementMock();
|
||||
objTag.contentDocument = document.createElement('div');
|
||||
var myVivus = new Vivus(objTag);
|
||||
objTag.contentDocument = wrapTag;
|
||||
objTag.loaded();
|
||||
expect(myVivus.isReady).toEqual(true);
|
||||
});
|
||||
|
||||
it('should throw an error if the SVG file does not exists', function () {
|
||||
objTag = new ObjectElementMock();
|
||||
objTag.contentDocument = document.createElement('div');
|
||||
new Vivus(objTag);
|
||||
expect(function () {
|
||||
objTag.loaded();
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
// Options
|
||||
it('should work without options', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if options is not an object', function () {
|
||||
expect(function () { new Vivus(svgTag, []); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
expect(function () { new Vivus(svgTag, 42); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
expect(function () { new Vivus(svgTag, false); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
expect(function () { new Vivus(svgTag, new Date()); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
expect(function () { new Vivus(svgTag, 'manual'); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
expect(function () { new Vivus(svgTag, function () {}); }).toThrow(new Error('Vivus [constructor]: "options" parameter must be an object'));
|
||||
});
|
||||
|
||||
// Options
|
||||
it('should work with empty option object', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {});
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if the `type` value given in options does not exists', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {type: 'by-unicorn'});
|
||||
}).toThrow(new Error('Vivus [constructor]: by-unicorn is not an existing animation `type`'));
|
||||
});
|
||||
|
||||
it('should throw an error if the `start` value given in options is not a string', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {start: 'when-unicorn-ready'});
|
||||
}).toThrow(new Error('Vivus [constructor]: when-unicorn-ready is not an existing `start` option'));
|
||||
});
|
||||
|
||||
it('should throw an error if the `delay` value is bigger (or equal) than `duration`', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {duration: 200, delay: 199});
|
||||
}).not.toThrow();
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {duration: 200, delay: 200});
|
||||
}).toThrow(new Error('Vivus [constructor]: delay must be shorter than duration'));
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {duration: 200, delay: 201});
|
||||
}).toThrow(new Error('Vivus [constructor]: delay must be shorter than duration'));
|
||||
});
|
||||
|
||||
it('should override `duration` if invalid', function () {
|
||||
myVivus = new Vivus(svgTag, {duration: -12});
|
||||
expect(myVivus.duration > 0).toBe(true);
|
||||
});
|
||||
|
||||
it('should override `delay` if invalid, with a null value', function () {
|
||||
myVivus = new Vivus(svgTag, {delay: -12});
|
||||
expect(!myVivus.delay).toBe(false);
|
||||
});
|
||||
|
||||
it('should set up default values', function () {
|
||||
myVivus = new Vivus(svgTag, {});
|
||||
expect(myVivus.type).toBeDefined();
|
||||
expect(myVivus.start).toBeDefined();
|
||||
expect(myVivus.duration).toBeDefined();
|
||||
});
|
||||
|
||||
it('the vivus instance should have `el` and `parentEl` equal if the element is a SVG object', function () {
|
||||
myVivus = new Vivus(svgTag, {});
|
||||
expect(myVivus.el).toEqual(myVivus.parentEl);
|
||||
});
|
||||
|
||||
// Callback
|
||||
it('should throw an error if callback is non a function', function () {
|
||||
expect(function () {
|
||||
new Vivus(svgTag, {}, 42);
|
||||
}).toThrow(new Error('Vivus [constructor]: "callback" parameter must be a function'));
|
||||
});
|
||||
|
||||
it('should use scale to determine path length when vector effect is non-scaling-stroke', function () {
|
||||
var scalingSvgTag = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
var scalingWrapTag = document.createElement('div');
|
||||
|
||||
scalingSvgTag.setAttribute('viewBox', '0 0 500 200');
|
||||
scalingWrapTag.style.width = '1000px';
|
||||
|
||||
scalingSvgTag.id = 'scaling-stroke-test';
|
||||
|
||||
scalingSvgTag.innerHTML = '<path vector-effect="non-scaling-stroke" fill="none" stroke="#f9f9f9" stroke-width="3" d="M0,68.57346635098205L20.833333333333332,3.8875909891199285L41.666666666666664,47.366000806779425L62.5,57.171841641625065L83.33333333333333"/>' +
|
||||
'<path fill="none" stroke="#f9f9f9" stroke-width="3" d="M0,68.57346635098205L20.833333333333332,3.8875909891199285L41.666666666666664,47.366000806779425L62.5,57.171841641625065L83.33333333333333"/>';
|
||||
|
||||
scalingWrapTag.appendChild(scalingSvgTag);
|
||||
|
||||
document.body.appendChild(scalingWrapTag);
|
||||
|
||||
myVivus = new Vivus(scalingSvgTag);
|
||||
|
||||
expect(myVivus.map.length).toEqual(2);
|
||||
expect(myVivus.map[0].length).toEqual(280);
|
||||
expect(myVivus.map[1].length).toEqual(141);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[engine]', function () {
|
||||
|
||||
// Mapping
|
||||
describe('Mapping:', function () {
|
||||
|
||||
it('should not trigger any error if the SVG is empty', function () {
|
||||
expect(function () {
|
||||
var svgTag = document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
myVivus = new Vivus(svgTag, {});
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should create a mapping of the SVG', function () {
|
||||
myVivus = new Vivus(svgTag, {});
|
||||
expect(myVivus.map && myVivus.map.length).toEqual(6);
|
||||
});
|
||||
|
||||
it('should map with correct values for start and duration', function () {
|
||||
var i, typeIndex, types = ['delayed', 'sync', 'oneByOne', 'scenario', 'scenario-sync'];
|
||||
for (typeIndex in types) {
|
||||
myVivus = new Vivus(svgTag, {type: types[typeIndex], duration: 200});
|
||||
for (i in myVivus.map) {
|
||||
expect(myVivus.map[i].startAt >= 0).toBe(true);
|
||||
expect(myVivus.map[i].duration >= 0).toBe(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Tests for 'getTotalLength' method in case of awkward results
|
||||
describe('SVG parsing issue', function () {
|
||||
|
||||
var getTotalLengthBkp = SVGPathElement.prototype.getTotalLength,
|
||||
warnBkp = console.warn;
|
||||
|
||||
beforeEach(function () {
|
||||
SVGPathElement.prototype.getTotalLength = function () {
|
||||
return NaN;
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
SVGPathElement.prototype.getTotalLength = getTotalLengthBkp;
|
||||
console.warn = warnBkp;
|
||||
});
|
||||
|
||||
it('should call console.warn if a path length is NaN', function () {
|
||||
var warnSpy = jasmine.createSpy('spy');
|
||||
console.warn = warnSpy;
|
||||
myVivus = new Vivus(svgTag);
|
||||
expect(warnSpy.calls.count()).toEqual(6);
|
||||
expect(myVivus.map.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('shouldn\'t call console.warn if not defined a path length is NaN', function () {
|
||||
console.warn = null;
|
||||
myVivus = new Vivus(svgTag);
|
||||
expect(myVivus.map.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Visibility checking:', function () {
|
||||
|
||||
it('should not accept a path which is not displayed', function () {
|
||||
// Hide a path
|
||||
svgTag.childNodes[1].style.display = 'none';
|
||||
myVivus = new Vivus(svgTag, {ignoreInvisible: true});
|
||||
expect(myVivus.map.length).toEqual(5);
|
||||
});
|
||||
|
||||
it('should not accept a path which with an ignore tag', function () {
|
||||
svgTag.childNodes[1].setAttribute('data-ignore', 'true');
|
||||
myVivus = new Vivus(svgTag);
|
||||
expect(myVivus.map.length).toEqual(5);
|
||||
});
|
||||
|
||||
it('should not accept a path which is not displayed', function () {
|
||||
svgTag.childNodes[1].setAttribute('data-ignore', 'false');
|
||||
myVivus = new Vivus(svgTag);
|
||||
expect(myVivus.map.length).toEqual(6);
|
||||
});
|
||||
});
|
||||
|
||||
// Drawing
|
||||
describe('Drawing:', function () {
|
||||
|
||||
it('should call the callback once the animation is finished', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'autostart'
|
||||
}, function () {
|
||||
done = true;
|
||||
});
|
||||
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call the callback once the reverse animation is finished', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
type: 'oneByOne',
|
||||
duration: 6
|
||||
}, function () {
|
||||
done = true;
|
||||
});
|
||||
|
||||
myVivus.finish().play(-1);
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call the method callback as the second param once the animation is finished', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual',
|
||||
});
|
||||
|
||||
myVivus.play(1, function() {
|
||||
done = true;
|
||||
});
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call the method callback as the first param once the animation is finished', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual',
|
||||
});
|
||||
|
||||
myVivus.play(function() {
|
||||
done = true;
|
||||
});
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call the method callback once the reverse animation is finished', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual',
|
||||
});
|
||||
|
||||
myVivus.finish().play(-1, function() {
|
||||
done = true;
|
||||
});
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call the method callback provided in the last play call', function () {
|
||||
var done = false;
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual',
|
||||
});
|
||||
|
||||
myVivus.finish().play(-1, function () {});
|
||||
myVivus.play(function() {
|
||||
done = true;
|
||||
});
|
||||
triggerFrames();
|
||||
expect(done).toBe(true);
|
||||
});
|
||||
|
||||
it('should call destroy method once the animation is finished', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual',
|
||||
selfDestroy: true
|
||||
});
|
||||
myVivus.destroy = jasmine.createSpy('spy');
|
||||
myVivus.play();
|
||||
triggerFrames();
|
||||
expect(myVivus.destroy.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('should\' call destroy method if selfDestroy option is not present', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual'
|
||||
});
|
||||
myVivus.destroy = jasmine.createSpy('spy');
|
||||
myVivus.play();
|
||||
triggerFrames();
|
||||
expect(myVivus.destroy.calls.count()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should stop animation if destroy has been called', function () {
|
||||
var callbackSpy = jasmine.createSpy('spy');
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'autostart'
|
||||
}, callbackSpy);
|
||||
|
||||
triggerFrames(1);
|
||||
myVivus.destroy();
|
||||
|
||||
triggerFrames();
|
||||
expect(callbackSpy.calls.count()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should stop the animation once it reaches currentFrame == 0', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual'
|
||||
});
|
||||
myVivus.stop = jasmine.createSpy('spy');
|
||||
myVivus.play(-1);
|
||||
triggerFrames();
|
||||
expect(myVivus.stop.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('should trace reasonably', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual'
|
||||
});
|
||||
spyOn(myVivus, 'trace').and.callThrough();
|
||||
myVivus.play(0.5);
|
||||
triggerFrames();
|
||||
expect(myVivus.trace.calls.count()).toEqual(12);
|
||||
});
|
||||
|
||||
it('should start by the last path if reverseStack is enabled', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
type: 'oneByOne',
|
||||
duration: 5,
|
||||
reverseStack: true
|
||||
});
|
||||
myVivus.setFrameProgress(0.5);
|
||||
|
||||
var paths = svgTag.querySelectorAll('path');
|
||||
expect(+paths[0].style.strokeDashoffset).not.toEqual(0);
|
||||
expect(+paths[paths.length -1].style.strokeDashoffset).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Force Render:', function () {
|
||||
|
||||
it('should use renderPath if forceRender option is set to true', function () {
|
||||
myVivus = new Vivus(svgTag, { duration: 2, start: 'manual', forceRender: true });
|
||||
|
||||
var originalFirstPath = myVivus.map[0].el;
|
||||
myVivus.renderPath(0);
|
||||
expect(myVivus.map[0].el).not.toBe(originalFirstPath);
|
||||
});
|
||||
|
||||
it('should not use renderPath if forceRender option is set to false', function () {
|
||||
myVivus = new Vivus(svgTag, { duration: 2, start: 'manual', forceRender: false });
|
||||
|
||||
var originalFirstPath = myVivus.map[0].el;
|
||||
myVivus.renderPath(0);
|
||||
expect(myVivus.map[0].el).toBe(originalFirstPath);
|
||||
});
|
||||
|
||||
it('renderPath should not throw an error if the index doesn\'t exists', function () {
|
||||
myVivus = new Vivus(svgTag, { duration: 2, start: 'manual', forceRender: true });
|
||||
expect(function () {
|
||||
myVivus.renderPath(42);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('[controls]', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
type: 'oneByOne',
|
||||
duration: 2,
|
||||
start: 'manual'
|
||||
});
|
||||
});
|
||||
|
||||
it('shouldn\'t play if the parameter in incorrect', function () {
|
||||
expect(function () {myVivus.play('a');}).toThrow(new Error('Vivus [play]: invalid speed'));
|
||||
expect(function () {myVivus.play({});}).toThrow(new Error('Vivus [play]: invalid speed'));
|
||||
expect(function () {myVivus.play([]);}).toThrow(new Error('Vivus [play]: invalid speed'));
|
||||
expect(function () {myVivus.play('1');}).toThrow(new Error('Vivus [play]: invalid speed'));
|
||||
});
|
||||
|
||||
it('should return the correct status', function () {
|
||||
expect(myVivus.getStatus()).toEqual('start');
|
||||
myVivus.setFrameProgress(0.5);
|
||||
expect(myVivus.getStatus()).toEqual('progress');
|
||||
myVivus.finish();
|
||||
expect(myVivus.getStatus()).toEqual('end');
|
||||
myVivus.reset();
|
||||
expect(myVivus.getStatus()).toEqual('start');
|
||||
});
|
||||
|
||||
it('should play with the normal speed by default', function () {
|
||||
myVivus.play();
|
||||
expect(myVivus.speed).toEqual(1);
|
||||
});
|
||||
|
||||
it('shouldn\'t run another process of drawing if the animation is in progress', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual'
|
||||
});
|
||||
spyOn(myVivus, 'trace').and.callThrough();
|
||||
|
||||
myVivus.play(0.5);
|
||||
myVivus.play(0.5);
|
||||
triggerFrames();
|
||||
expect(myVivus.trace.calls.count()).toEqual(12);
|
||||
});
|
||||
|
||||
it('should stop the animation only when the animation is running', function () {
|
||||
myVivus = new Vivus(svgTag, {
|
||||
duration: 6,
|
||||
start: 'manual'
|
||||
});
|
||||
myVivus.play();
|
||||
expect(myVivus.handle).toBeTruthy();
|
||||
myVivus.stop();
|
||||
expect(myVivus.handle).toBeFalsy();
|
||||
myVivus.stop();
|
||||
expect(myVivus.handle).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should remove all unecessary styling on every path element', function () {
|
||||
var i, paths;
|
||||
myVivus.destroy();
|
||||
|
||||
paths = svgTag.querySelectorAll('path');
|
||||
for (i = 0; i < paths.length; i++) {
|
||||
expect(!!paths[i].style.strokeDashoffset).toEqual(false);
|
||||
expect(!!paths[i].style.strokeDasharray).toEqual(false);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Where are the tests about `util` methods?
|
||||
* Well....
|
||||
* to be honest, I've been struggling a bit for these kind of tests
|
||||
* which seems difficult to test from Karma.
|
||||
*/
|
||||
});
|
||||
|
||||
|
||||
});
|
Reference in New Issue
Block a user