Skip to content

Commit 3cbad16

Browse files
authored
Merge pull request #2 from DoubleJump/master
Updates
2 parents e4c9527 + 8ba07a4 commit 3cbad16

File tree

9 files changed

+66
-22
lines changed

9 files changed

+66
-22
lines changed

README.md

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,32 @@
33
A simple set of python functions to help working with animated SVGs exported from Illustrator. More features coming soon!
44
We used it to create animations like this.
55

6-
![Viva La Velo intro animation](vlv-intro-gif.gif)
76
[Viva La Velo](https://parall.ax/viva-le-velo)
87

8+
![Viva La Velo intro animation](vlv-intro-gif.gif)
9+
910

1011
## Overview
1112

1213
Part of animating with SVGs is getting references to elements in code and passing them to animation functions. For complicated animations this becomes difficult and hand editing SVG code is slow and gets overwritten when your artwork updates. We decided to write a post-processer for SVGs produced by Illustrator to help speed this up. Layer names are used to create attributes, classes and ID's making selecting them in JS or CSS far easier.
1314

15+
This is the what the svg code looks like before and after the processing step.
16+
17+
```xml
18+
<!-- Before post processer -->
19+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
20+
<rect id="_class_my-element_origin_144_234" data-name="#class=my-element, origin=144 234" x="144" y="234" width="148" height="148"/>
21+
<rect id="_id_my-unique-element" data-name="#id=my-unique-element" x="316" y="234" width="148" height="148" fill="#29abe2"/>
22+
<rect id="_class_my-element" data-name="#class=my-element" x="488" y="234" width="148" height="148" fill="#fbb03b"/>
23+
</svg>
24+
25+
<!-- After post processer -->
26+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
27+
<rect id="my-unique-element" x="316" y="234" width="148" height="148" fill="#29abe2"/>
28+
<rect class="my-element" data-svg-origin="144 234" x="144" y="234" width="148" height="148"/>
29+
<rect class="my-element" x="488" y="234" width="148" height="148" fill="#fbb03b"/>
30+
</svg>
31+
```
1432

1533
![Illustrator layers example](example-image.png)
1634

@@ -25,7 +43,7 @@ Create an Illustrator file, add an element and change its layer name to say `#cl
2543

2644
Create a HTML file as below. The import statements inline the SVG inline into our HTML file so we don't have to do any copy and pasting. Not strictly neccessary but makes the workflow a little easier. Save it as `animation.html`.
2745

28-
```
46+
```html
2947
<!DOCTYPE html>
3048
<html>
3149
<head>
@@ -42,7 +60,7 @@ Create a HTML file as below. The import statements inline the SVG inline into ou
4260

4361
Open the file called `run.py`. Here you can edit how the SVGs will be processed. The default looks like this. The sections below describe what the various options do.
4462

45-
```
63+
```javascript
4664
from svg import *
4765

4866
compile_svg('animation.svg', 'processed_animation.svg',
@@ -68,9 +86,11 @@ Processes a single SVG and places it in the supplied destination directory. The
6886
Converts layer names as defined in Illustator into attributes. Begin the layer name with a '#' to indicate the layer should be parsed.
6987
For example `#id=my-id, class=my-class my-other-class, role=my-role` ...etc.
7088
This is useful for fetching elements with Javascript as well as marking up elements for accessibility - see this [CSS Tricks Accessible SVG ](https://css-tricks.com/accessible-svgs/) article.
71-
You can also use `origin=100 100` to set origins for rotating/scaling with GSAP (expands to data-svg-origin).
7289
NOTE: Requires using commas to separate the attributes as that makes the parsing code a lot simpler :)
7390

91+
+ **expand_origin:**
92+
Allows you to use `origin=100 100` to set origins for rotating/scaling with GSAP (expands to data-svg-origin).
93+
7494
+ **namespace:**
7595
Appends a namespace to classes and IDs if one is provided. Useful for avoiding conflicts with other SVG files for things like masks and clipPaths.
7696

@@ -80,6 +100,18 @@ Removes unneeded whitespace. We don't do anything fancier than that so as to not
80100
+ **attributes:**
81101
An object of key:value strings that will be applied as attributes to the root SVG element.
82102

103+
+ **title:**
104+
Sets the title or removes it completely when set to `false`
105+
106+
+ **description:**
107+
Sets the description or removes it completely when set to `false`
108+
109+
+ **convert_svg_text_to_html:**
110+
Converts SVG text in HTML text via the foriegn object tag reducing file bloat and allowing you to style it with CSS. Requires the text be grouped inside a rectangle with the layer name set to `#TEXT`.
111+
112+
+ **spirit:**
113+
Expands `#spirit=my-id` to `data-spirit-id` when set to `true` for use with the [Spirit animation app](<https://spiritapp.io/>)
114+
83115

84116
### inline\_svg(src\_path, dst\_path)
85-
In order to animate SVGs code needs to be placed in-line. This function will look at the source HTML and include any references defined by `//import` statements to SVGs that it finds.
117+
In order to animate SVGs markup needs to be placed in-line with HTML. This function will look at the source HTML file and include any references defined by `//import` statements to SVGs that it finds.

example/output/animation.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
<svg viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
99
<title>animation</title>
10-
<rect class="example-my-element" height="148" origin="144 234" width="148" x="144" y="234"/>
11-
<rect fill="#29abe2" height="148" id="example-my-unique-element" width="148" x="316" y="234"/>
12-
<rect class="example-my-element" fill="#fbb03b" height="148" width="148" x="488" y="234"/>
10+
<rect class="my-element" height="148" origin="144 234" width="148" x="144" y="234"/>
11+
<rect fill="#29abe2" height="148" id="my-unique-element" width="148" x="316" y="234"/>
12+
<rect class="my-element" fill="#fbb03b" height="148" width="148" x="488" y="234"/>
1313
</svg>
1414

1515
</body>

example/parallax_svg_tools/run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
'namespace': 'example'
77
})
88

9-
inline_svg('animation.html', 'output/animation.html')
9+
inline_svg('animation.html', 'output/animation.html')

example/parallax_svg_tools/svg/__init__.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def parse_svg(path, namespace, options):
2424

2525
if namespace == None:
2626
namespace = ''
27+
else:
28+
namespace = namespace + '-'
2729

2830
# BeautifulSoup can't parse attributes with dashes so we replace them with underscores instead
2931
file_string = file_string.replace('data-name', 'data_name')
@@ -34,8 +36,8 @@ def parse_svg(path, namespace, options):
3436

3537
# Add namespaces to ids
3638
if namespace:
37-
file_string = file_string.replace('id="', 'id="' + namespace + '-')
38-
file_string = file_string.replace('url(#', 'url(#' + namespace + '-')
39+
file_string = file_string.replace('id="', 'id="' + namespace)
40+
file_string = file_string.replace('url(#', 'url(#' + namespace)
3941

4042
svg = BeautifulSoup(file_string, 'html.parser')
4143

@@ -48,7 +50,7 @@ def parse_svg(path, namespace, options):
4850
for element in use_elements:
4951
if namespace:
5052
href = element['xlink:href']
51-
element['xlink:href'] = href.replace('#', '#' + namespace + '-')
53+
element['xlink:href'] = href.replace('#', '#' + namespace)
5254

5355
del element['id']
5456

@@ -109,7 +111,7 @@ def parse_svg(path, namespace, options):
109111
if (len(split) < 2): continue
110112
key = split[0]
111113
value = split[1]
112-
if key == 'id': key = namespace + '-' + key
114+
if key == 'id': key = namespace + key
113115
foreign_object_tag[key] = value
114116

115117
foreign_object_tag.append(text_tag)
@@ -138,7 +140,7 @@ def parse_svg(path, namespace, options):
138140
if (len(split) < 2): continue
139141
key = split[0]
140142
value = split[1]
141-
if key == 'id' or key == 'class': value = namespace + '-' + value
143+
if key == 'id' or key == 'class': value = namespace + value
142144
element[key] = value
143145

144146

-8 Bytes
Binary file not shown.

example/processed_animation.svg

Lines changed: 3 additions & 3 deletions
Loading

parallax_svg_tools.zip

4 Bytes
Binary file not shown.

parallax_svg_tools/svg/__init__.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,24 @@ def parse_svg(path, namespace, options):
2424

2525
if namespace == None:
2626
namespace = ''
27+
else:
28+
namespace = namespace + '-'
2729

2830
# BeautifulSoup can't parse attributes with dashes so we replace them with underscores instead
2931
file_string = file_string.replace('data-name', 'data_name')
3032

3133
# Expand origin to data-svg-origin as its a pain in the ass to type
3234
if 'expand_origin' in options and options['expand_origin'] == True:
3335
file_string = file_string.replace('origin=', 'data-svg-origin=')
36+
37+
# Expand spirit to data-spirit-id for use with https://spiritapp.io/
38+
if 'spirit' in options and options['spirit'] == True:
39+
file_string = file_string.replace('spirit=', 'data-spirit-id=')
3440

3541
# Add namespaces to ids
3642
if namespace:
37-
file_string = file_string.replace('id="', 'id="' + namespace + '-')
38-
file_string = file_string.replace('url(#', 'url(#' + namespace + '-')
43+
file_string = file_string.replace('id="', 'id="' + namespace)
44+
file_string = file_string.replace('url(#', 'url(#' + namespace)
3945

4046
svg = BeautifulSoup(file_string, 'html.parser')
4147

@@ -48,7 +54,7 @@ def parse_svg(path, namespace, options):
4854
for element in use_elements:
4955
if namespace:
5056
href = element['xlink:href']
51-
element['xlink:href'] = href.replace('#', '#' + namespace + '-')
57+
element['xlink:href'] = href.replace('#', '#' + namespace)
5258

5359
del element['id']
5460

@@ -58,6 +64,10 @@ def parse_svg(path, namespace, options):
5864
titles = svg.select('title')
5965
for t in titles: t.extract()
6066

67+
# remove description
68+
if 'description' in options and options['description'] == False:
69+
descriptions = svg.select('desc')
70+
for d in descriptions: d.extract()
6171

6272
foreign_tags_to_add = []
6373
if 'convert_svg_text_to_html' in options and options['convert_svg_text_to_html'] == True:
@@ -109,7 +119,7 @@ def parse_svg(path, namespace, options):
109119
if (len(split) < 2): continue
110120
key = split[0]
111121
value = split[1]
112-
if key == 'id': key = namespace + '-' + key
122+
if key == 'id': key = namespace + key
113123
foreign_object_tag[key] = value
114124

115125
foreign_object_tag.append(text_tag)
@@ -138,7 +148,7 @@ def parse_svg(path, namespace, options):
138148
if (len(split) < 2): continue
139149
key = split[0]
140150
value = split[1]
141-
if key == 'id' or key == 'class': value = namespace + '-' + value
151+
if key == 'id' or key == 'class': value = namespace + value
142152
element[key] = value
143153

144154

parallax_svg_tools/svg/__init__.pyc

-7.45 KB
Binary file not shown.

0 commit comments

Comments
 (0)