Skip to content

Commit ebc0e42

Browse files
committed
update
0 parents  commit ebc0e42

File tree

7 files changed

+631
-0
lines changed

7 files changed

+631
-0
lines changed

.github/FUNDING.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: ["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QX3XJ942LDLMQ&source=url"]

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.github

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
### Finances App Firebase Backend
2+
CLI tool to animate svg paths
3+
4+
**[DEMO](https://nckdev.agency/lab/svg-lineart-animator/en)**
5+
6+
### Installation
7+
`npm install -g svg-lineart-animator`
8+
9+
### Usage
10+
`svgline --file test.svg`
11+
12+
### Options
13+
```
14+
Usage:
15+
svgline [options]
16+
17+
Options:
18+
-f, --file Path to original file
19+
-w, --delay Delay before start of animation in ms
20+
-d, --destination Path to save generated file
21+
-p, --direction Animation direction
22+
-s, --duration Duration of the animation in ms
23+
-h, --help This screen
24+
-i, --iteration Number of iteration for animation
25+
-t, --timing Timing of the animation
26+
27+
For more information on the animation properties. Check it out here: https://www.w3schools.com/cssref/css3_pr_animation.asp
28+
```
29+
### Support
30+
If you like this app, please consider donating to a small time developer (me)!
31+
32+
**[Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QX3XJ942LDLMQ&source=url)**

cli.js

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#!/usr/bin/env node
2+
3+
const arg = require('arg')
4+
const fs = require('fs')
5+
const { parse, stringify } = require('svgson')
6+
const path = require('svg-path-properties')
7+
8+
function parseArgumentsIntoOptions(rawArgs) {
9+
const args = arg({
10+
'--help': Boolean,
11+
'--delay': Number,
12+
'--destination': String,
13+
'--direction': String,
14+
'--duration': Number,
15+
'--file': String,
16+
'--iteration': String || Number,
17+
'--timing': String,
18+
'-h': '--help',
19+
'-w': '--delay',
20+
'-d': '--destination',
21+
'-p': '--direction',
22+
'-s': '--duration',
23+
'-f': '--file',
24+
'-i': '--iteration',
25+
'-t': '--timing'
26+
}, {
27+
argv: rawArgs.slice(2),
28+
})
29+
return {
30+
help: args['--help'] || false,
31+
delay: args['--delay'] || 0,
32+
destination:
33+
args['--destination']
34+
? args['--destination']
35+
: args['--file']
36+
? `${args['--file'].substr(0, args['--file'].lastIndexOf('.'))}-animated.svg`
37+
: false,
38+
direction: args['--direction'] || 'forwards',
39+
duration: args['--duration'] || 1500,
40+
file: args['--file'] || false,
41+
iteration: args['--iteration'] || 1,
42+
timing: args['--timing'] || 'linear'
43+
}
44+
}
45+
46+
let options = parseArgumentsIntoOptions(process.argv)
47+
48+
if ( options.help ) {
49+
console.group('\nUsage: ')
50+
console.log('svgline [options]')
51+
console.groupEnd()
52+
console.group('\nOptions:')
53+
console.log(`${'-f, --file'.padEnd(55)}Path to original file`)
54+
console.log(`${'-w, --delay'.padEnd(55)}Delay before start of animation in ms`)
55+
console.log(`${'-d, --destination'.padEnd(55)}Path to save generated file`)
56+
console.log(`${'-p, --direction'.padEnd(55)}Animation direction`)
57+
console.log(`${'-s, --duration'.padEnd(55)}Duration of the animation in ms`)
58+
console.log(`${'-h, --help'.padEnd(55)}This screen`)
59+
console.log(`${'-i, --iteration'.padEnd(55)}Number of iteration for animation`)
60+
console.log(`${'-t, --timing'.padEnd(55)}Timing of the animation`)
61+
console.groupEnd()
62+
console.log('\nFor more information on the animation properties. Check it out here: https://www.w3schools.com/cssref/css3_pr_animation.asp\n')
63+
return
64+
}
65+
66+
if ( ! options.file ) {
67+
console.error('--file option is required')
68+
console.info('Use --file "pathToFile.svg" or -f "pathToFile.svg"')
69+
return
70+
}
71+
72+
const svg = fs.readFileSync(options.file)
73+
parse(svg.toString()).then((json) => {
74+
const res = json
75+
const styleIndex = res.children.findIndex((el) => el.name == 'style')
76+
if ( styleIndex >= 0 ) {
77+
res.children[styleIndex] = {
78+
...res.children[styleIndex],
79+
children: [{
80+
...res.children[styleIndex].children[0],
81+
value: `${res.children[styleIndex].children[0].value}@keyframes animateLine{to{stroke-dashoffset: 0;}}`
82+
}]
83+
}
84+
} else {
85+
res.children = [{
86+
name: 'style',
87+
type: 'element',
88+
value: '',
89+
attributes: { type: 'text/css' },
90+
children: [{
91+
name: '',
92+
type: 'text',
93+
value: '@keyframes animateLine{stroke-dashoffset: 0;}',
94+
attributes: {},
95+
children: []
96+
}]
97+
}, ...res.children]
98+
}
99+
loop(res)
100+
fs.writeFile(options.destination, stringify(res), (err) => {
101+
if ( err ) throw err(err)
102+
console.log(`The new svg is saved under: ${options.destination}`);
103+
})
104+
})
105+
106+
function loop(el) {
107+
let length = 0
108+
switch (el.name) {
109+
case 'style':
110+
el.children = [{
111+
...el.children[0],
112+
value: `${el.children[0].value}@keyframes animateLine{to{stroke-dashoffset: 0;}}`
113+
}]
114+
break
115+
case 'circle':
116+
length = 2 * Math.PI * el.attributes.r
117+
el.attributes.style = `${el.attributes.style ? el.attributes.style + ';' : ''}stroke-dasharray:${length};stroke-dashoffset:${length};animation: animateLine ${options.duration}ms ${options.timing} ${options.delay}ms ${options.iteration} ${options.direction};`
118+
break
119+
case 'rect':
120+
length = Math.ceil(el.attributes.width * 2 + el.attributes.height * 2)
121+
el.attributes.style = `${el.attributes.style ? el.attributes.style + ';' : ''}stroke-dasharray:${length};stroke-dashoffset:${length};animation: animateLine ${options.duration}ms ${options.timing} ${options.delay}ms ${options.iteration} ${options.direction};`
122+
break
123+
case 'path':
124+
const pathProperties = new path.svgPathProperties(el.attributes.d)
125+
length = Math.ceil(pathProperties.getTotalLength())
126+
el.attributes.style = `${el.attributes.style ? el.attributes.style + ';' : ''}stroke-dasharray:${length};stroke-dashoffset:${length};animation: animateLine ${options.duration}ms ${options.timing} ${options.delay}ms ${options.iteration} ${options.direction};`
127+
break
128+
case 'polygon':
129+
case 'polyline':
130+
const helper = el.attributes.points.split(' ')
131+
let points = []
132+
if ( el.attributes.points.indexOf(',') >= 0 ) {
133+
for ( let i = 0; i < helper.length; i++ ) {
134+
points[i] = helper[i].split(',')
135+
}
136+
} else {
137+
for ( let i = 0; i < helper.length; i += 2 ) {
138+
let arr = []
139+
for ( let j = 0; j < 2; j++ ) {
140+
arr.push(helper[i + j])
141+
}
142+
points.push(arr)
143+
}
144+
}
145+
146+
let res = ''
147+
for( let i = 0; i < points.length; i++ ){
148+
res += (i && "L" || "M") + points[i]
149+
}
150+
res = `${res}z`
151+
const polyProperties = new path.svgPathProperties(res)
152+
length = Math.ceil(polyProperties.getTotalLength())
153+
el.attributes.style = `${el.attributes.style ? el.attributes.style + ';' : ''}stroke-dasharray:${length};stroke-dashoffset:${length};animation: animateLine ${options.duration}ms ${options.timing} ${options.delay}ms ${options.iteration} ${options.direction};`
154+
break
155+
case 'line':
156+
const x1 = el.attributes.x1 || 0
157+
const x2 = el.attributes.x2 || 0
158+
const y1 = el.attributes.y1 || 0
159+
const y2 = el.attributes.y2 || 0
160+
length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
161+
el.attributes.style = `${el.attributes.style ? el.attributes.style + ';' : ''}stroke-dasharray:${length};stroke-dashoffset:${length};animation: animateLine ${options.duration}ms ${options.timing} ${options.delay}ms ${options.iteration} ${options.direction};`
162+
break
163+
default:
164+
for ( let i = 0; i < el.children.length; i++ ) {
165+
loop(el.children[i])
166+
}
167+
break
168+
}
169+
}

0 commit comments

Comments
 (0)