wallside poast
This commit is contained in:
parent
8e64a09f01
commit
61d04f2321
5 changed files with 519 additions and 0 deletions
109
content/posts/WALL-side/index.md
Normal file
109
content/posts/WALL-side/index.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
+++
|
||||
date = "2022-05-29"
|
||||
draft = false
|
||||
path = "/blog/WALL-side"
|
||||
tags = ["art"]
|
||||
title = "WALL side"
|
||||
+++
|
||||
|
||||
{% image(name="wallside.png", colocated=true) %}
|
||||
poster with diagonal WALL side text in four different
|
||||
languages
|
||||
{% end %}
|
||||
|
||||
My partner has a brilliant poster they made of the backing of 3M command strips
|
||||
in their apartment, which I wanted to recreate as a vector image to make
|
||||
another. I initially tried inkscape, where I ran into issues with the tiled
|
||||
clone tool not supporting dragging to set spacing and more crucially not
|
||||
supporting absolute distances, which meant that it could not maintain proper
|
||||
spacing of things of different height (I later realized it could probably be
|
||||
done with a group, but there were unrelated factors of fiddliness at play such
|
||||
as difficulty working in a transformed coordinate system that made Inkscape
|
||||
infeasible to use).
|
||||
|
||||
I conceded and did this project as a simple Python SVG generator. First, I took
|
||||
a picture as reference, then included it in the SVG as an `<image>`. SVG is fun
|
||||
because it is *not* HTML, and is also strict XML. For instance, one difference
|
||||
is that the image tag is called `image` rather than `img` and uses an `href`,
|
||||
not a `src` (or indeed, `xlink:href` if you are using an older implementation
|
||||
such as inkscape).
|
||||
|
||||
With that out of the way, I made a `<g>` group that's rotated 45 degrees and
|
||||
translated some amount (`transform="rotate(-45) translate(-1000, 100)"`), then
|
||||
I created the four languages of `<text>` text elements inside. Regarding how to
|
||||
get the actual text to put in there, there are various ways to do this; I typed
|
||||
it in on my phone (including the Japanese! there's a drawing keyboard for
|
||||
Japanese in Google Keyboard, so even my dubious-quality non-Japanese-speaker
|
||||
scrawls got turned into characters pretty easily).
|
||||
|
||||
To get each text fragment into position easily,
|
||||
I nicked [some code to make them draggable][draggable],
|
||||
then noted down the transformation after dragging them into position. Next, I
|
||||
duplicated each language's element and moved the new one into the next
|
||||
horizontal position to figure out the horizontal (along the line) period and
|
||||
the next vertical position to figure out the cross-line period.
|
||||
|
||||
Then, I made these definitions reusable by giving them an `id` property and
|
||||
putting them in a `<defs>` block. This makes the original definition invisible,
|
||||
so you have to reference them as something like `<use xlink:href="#someId" />`.
|
||||
|
||||
Since I knew the spacings, I got Python out in earnest. To make my workflow
|
||||
more pleasant, I wanted to rebuild the image on every editor save. I found a
|
||||
tool [`entr`][entr] that can do this: `ls *.py | entr -r python wallside.py`.
|
||||
It takes a list of files to watch on standard input, and a command to run when
|
||||
any of them change.
|
||||
|
||||
With my setup sufficiently pleasant, I wrote some Python to generate a series
|
||||
of instances of the definition with the horizontal spacing for every language,
|
||||
with each looking like this:
|
||||
`<use x="{idx * SPACING[language]}" xlink:href="#{language}" />`.
|
||||
This forms one line of several copies of each of English, French, Spanish, and
|
||||
Japanese. I put this into a `<defs>` block as a group, then referenced it in
|
||||
the body of the document with a `<use>` to check my work.
|
||||
|
||||
After I was satisfied this worked, I then started generating that `<use>`
|
||||
automatically, with the `y` offset set to some multiple of the line spacing,
|
||||
and with some tweaks, that was that.
|
||||
|
||||
Next was the job of getting it to work on Inkscape since I was prototyping
|
||||
against Firefox, which, being a web browser, has a very advanced SVG renderer
|
||||
compared to non-browser programs. One thing I was doing that was not ideal for
|
||||
Inkscape was that I was rendering a bunch of text off-page. I fixed this with a
|
||||
clip path the size of the document like so:
|
||||
|
||||
```xml
|
||||
<clipPath id="viewRect">
|
||||
<rect height="100%" width="100%" />
|
||||
</clipPath>
|
||||
<!-- ... -->
|
||||
<g clip-path="url(#viewRect)">
|
||||
<g transform="..."><!-- all the text goes in here --></g>
|
||||
</g>
|
||||
```
|
||||
|
||||
Another thing that Inkscape disliked (to the point of not rendering anything)
|
||||
was the use of `href="..."` in my document. Its predecessor, `xlink:href`, was
|
||||
[noted on MDN][mdn xlink] as being deprecated, replaced in the SVG 2 standard
|
||||
by unprefixed `href`. I just had to switch to the older one and add
|
||||
`xmlns:xlink="http://www.w3.org/1999/xlink"` to my `<svg>` element to fix this.
|
||||
|
||||
The last bit of trouble I got from Inkscape was that it does not support the
|
||||
CSS `transform` property, so I had to convert to the `transform="..."` property
|
||||
directly on tags. Oh well, so much for the shiny features. But it works now and
|
||||
is more portable!
|
||||
|
||||
Finally, I have a SVG file that is exactly what I want and was not that painful
|
||||
to create. That was fun!
|
||||
|
||||
I've included the sources and SVG file below (note: it requires Source Han Sans
|
||||
installed on your computer, which is a nice open source sans-serif font with
|
||||
Chinese/Japanese/Korean support).
|
||||
|
||||
* [SVG file here](./wallside.svg)
|
||||
* [PDF for printing here (11x17 inch tabloid size)](./wallside.svg.pdf)
|
||||
|
||||
{{ codefile(path="wallside.py", colocated=true, code_lang="python", hide=true) }}
|
||||
|
||||
[draggable]: https://github.com/petercollingridge/code-for-blog/blob/master/svg-interaction/draggable/draggable_groups.svg
|
||||
[mdn xlink]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
|
||||
[entr]: https://github.com/eradman/entr
|
||||
BIN
content/posts/WALL-side/wallside.png
Normal file
BIN
content/posts/WALL-side/wallside.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 881 KiB |
174
content/posts/WALL-side/wallside.py
Normal file
174
content/posts/WALL-side/wallside.py
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
import contextlib
|
||||
|
||||
|
||||
class Periods:
|
||||
y = 106
|
||||
x = {
|
||||
'en': 106,
|
||||
'fr': 106,
|
||||
'es': 146,
|
||||
'jp': 82,
|
||||
}
|
||||
|
||||
|
||||
DEFS = """
|
||||
"""
|
||||
|
||||
HEADER = """
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="17in" width="11in" onload="makeDraggable(evt)">
|
||||
<style>
|
||||
.text {
|
||||
font-family: "Source Han Sans";
|
||||
font-size: 14pt;
|
||||
font-weight: bolder;
|
||||
letter-spacing: -1.5px;
|
||||
}
|
||||
.text.japanese {
|
||||
font-size: 16pt;
|
||||
letter-spacing: -0.8px;
|
||||
}
|
||||
.wallside {
|
||||
transform: rotate(-45deg)translate(-13in, 1.2in);
|
||||
}
|
||||
.draggable, .draggable-group {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
<!--<image href="./wallsideref.jpg" x="0" y="0" transform="scale(0.4, 0.4)" /> -->
|
||||
<clipPath id="viewRect">
|
||||
<rect height="17in" width="11in" />
|
||||
</clipPath>
|
||||
<rect height="17in" width="11in" stroke="black" fill="none" />
|
||||
"""
|
||||
|
||||
FOOTER = """
|
||||
<script type="text/javascript"><![CDATA[
|
||||
function makeDraggable(evt) {
|
||||
var svg = evt.target;
|
||||
|
||||
svg.addEventListener('mousedown', startDrag);
|
||||
svg.addEventListener('mousemove', drag);
|
||||
svg.addEventListener('mouseup', endDrag);
|
||||
svg.addEventListener('mouseleave', endDrag);
|
||||
svg.addEventListener('touchstart', startDrag);
|
||||
svg.addEventListener('touchmove', drag);
|
||||
svg.addEventListener('touchend', endDrag);
|
||||
svg.addEventListener('touchleave', endDrag);
|
||||
svg.addEventListener('touchcancel', endDrag);
|
||||
|
||||
function getMousePosition(evt) {
|
||||
var CTM = svg.getScreenCTM();
|
||||
if (evt.touches) { evt = evt.touches[0]; }
|
||||
return {
|
||||
x: (evt.clientX - CTM.e) / CTM.a,
|
||||
y: (evt.clientY - CTM.f) / CTM.d
|
||||
};
|
||||
}
|
||||
|
||||
var selectedElement, offset, transform;
|
||||
|
||||
function initialiseDragging(evt) {
|
||||
offset = getMousePosition(evt);
|
||||
|
||||
// Make sure the first transform on the element is a translate transform
|
||||
var transforms = selectedElement.transform.baseVal;
|
||||
|
||||
if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
|
||||
// Create an transform that translates by (0, 0)
|
||||
var translate = svg.createSVGTransform();
|
||||
translate.setTranslate(0, 0);
|
||||
selectedElement.transform.baseVal.insertItemBefore(translate, 0);
|
||||
}
|
||||
|
||||
// Get initial translation
|
||||
transform = transforms.getItem(0);
|
||||
offset.x -= transform.matrix.e;
|
||||
offset.y -= transform.matrix.f;
|
||||
}
|
||||
|
||||
function startDrag(evt) {
|
||||
if (evt.target.classList.contains('draggable')) {
|
||||
selectedElement = evt.target;
|
||||
initialiseDragging(evt);
|
||||
} else if (evt.target.parentNode.classList.contains('draggable-group')) {
|
||||
selectedElement = evt.target.parentNode;
|
||||
initialiseDragging(evt);
|
||||
}
|
||||
}
|
||||
|
||||
function drag(evt) {
|
||||
if (selectedElement) {
|
||||
evt.preventDefault();
|
||||
var coord = getMousePosition(evt);
|
||||
transform.setTranslate(coord.x - offset.x, coord.y - offset.y);
|
||||
}
|
||||
}
|
||||
|
||||
function endDrag(evt) {
|
||||
selectedElement = false;
|
||||
}
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
||||
</svg>
|
||||
"""
|
||||
|
||||
BODY = """
|
||||
<defs>
|
||||
<text id="en" x="0" y="0" transform="translate(0, -80)" class="text">WALL side</text>
|
||||
<text id="fr" x="0" y="0" transform="translate(-25, -56)" class="text">Côté MUR</text>
|
||||
<text id="es" x="0" y="0" transform="translate(-28, 0)" class="text">lado de la PARED</text>
|
||||
<text id="jp" x="0" y="0" transform="translate(-20, -27)" class="text japanese">かベ面</text>
|
||||
</defs>
|
||||
|
||||
<g class="wallside">
|
||||
<!--
|
||||
<use href="#en" />
|
||||
<use href="#en" x="106" class="draggable" />
|
||||
<use href="#en" y="106" class="draggable" />
|
||||
<use href="#fr" />
|
||||
<use href="#fr" x="106" class="draggable" />
|
||||
<use href="#es" />
|
||||
<use href="#es" x="146" class="draggable" />
|
||||
<use href="#jp" />
|
||||
<use href="#jp" x="82" class="draggable" />
|
||||
-->
|
||||
</g>
|
||||
"""
|
||||
|
||||
|
||||
def make_line_def(id):
|
||||
print(f'<defs><g id="{id}">')
|
||||
for (lang, per) in Periods.x.items():
|
||||
for i in range(30 if lang == 'jp' else 20):
|
||||
print(f'<use x="{i * per}" xlink:href="#{lang}" />')
|
||||
print('</g></defs>')
|
||||
|
||||
|
||||
def make_wallside():
|
||||
# 96px/in * {13in, 1.2in}
|
||||
print('<g clip-path="url(#viewRect)"><g transform="rotate(-45) translate(-1248, 115)">')
|
||||
for i in range(20):
|
||||
print(f'<use xlink:href="#line-10" y="{Periods.y * i}" />')
|
||||
print('</g></g>')
|
||||
|
||||
|
||||
def main():
|
||||
f = open('./wallside.svg', 'w')
|
||||
with contextlib.redirect_stdout(f):
|
||||
build()
|
||||
print('built svg')
|
||||
|
||||
|
||||
def build():
|
||||
print(HEADER)
|
||||
print(DEFS)
|
||||
make_line_def('line-10')
|
||||
make_wallside()
|
||||
print(BODY)
|
||||
print(FOOTER)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
236
content/posts/WALL-side/wallside.svg
Normal file
236
content/posts/WALL-side/wallside.svg
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="17in" width="11in" onload="makeDraggable(evt)">
|
||||
<style>
|
||||
.text {
|
||||
font-family: "Source Han Sans";
|
||||
font-size: 14pt;
|
||||
font-weight: bolder;
|
||||
letter-spacing: -1.5px;
|
||||
}
|
||||
.text.japanese {
|
||||
font-size: 16pt;
|
||||
letter-spacing: -0.8px;
|
||||
}
|
||||
.wallside {
|
||||
transform: rotate(-45deg)translate(-13in, 1.2in);
|
||||
}
|
||||
.draggable, .draggable-group {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
<!--<image href="./wallsideref.jpg" x="0" y="0" transform="scale(0.4, 0.4)" /> -->
|
||||
<clipPath id="viewRect">
|
||||
<rect height="100%" width="100%" />
|
||||
</clipPath>
|
||||
<rect height="17in" width="11in" stroke="black" fill="none" />
|
||||
|
||||
|
||||
|
||||
<defs><g id="line-10">
|
||||
<use x="0" xlink:href="#en" />
|
||||
<use x="106" xlink:href="#en" />
|
||||
<use x="212" xlink:href="#en" />
|
||||
<use x="318" xlink:href="#en" />
|
||||
<use x="424" xlink:href="#en" />
|
||||
<use x="530" xlink:href="#en" />
|
||||
<use x="636" xlink:href="#en" />
|
||||
<use x="742" xlink:href="#en" />
|
||||
<use x="848" xlink:href="#en" />
|
||||
<use x="954" xlink:href="#en" />
|
||||
<use x="1060" xlink:href="#en" />
|
||||
<use x="1166" xlink:href="#en" />
|
||||
<use x="1272" xlink:href="#en" />
|
||||
<use x="1378" xlink:href="#en" />
|
||||
<use x="1484" xlink:href="#en" />
|
||||
<use x="1590" xlink:href="#en" />
|
||||
<use x="1696" xlink:href="#en" />
|
||||
<use x="1802" xlink:href="#en" />
|
||||
<use x="1908" xlink:href="#en" />
|
||||
<use x="2014" xlink:href="#en" />
|
||||
<use x="0" xlink:href="#fr" />
|
||||
<use x="106" xlink:href="#fr" />
|
||||
<use x="212" xlink:href="#fr" />
|
||||
<use x="318" xlink:href="#fr" />
|
||||
<use x="424" xlink:href="#fr" />
|
||||
<use x="530" xlink:href="#fr" />
|
||||
<use x="636" xlink:href="#fr" />
|
||||
<use x="742" xlink:href="#fr" />
|
||||
<use x="848" xlink:href="#fr" />
|
||||
<use x="954" xlink:href="#fr" />
|
||||
<use x="1060" xlink:href="#fr" />
|
||||
<use x="1166" xlink:href="#fr" />
|
||||
<use x="1272" xlink:href="#fr" />
|
||||
<use x="1378" xlink:href="#fr" />
|
||||
<use x="1484" xlink:href="#fr" />
|
||||
<use x="1590" xlink:href="#fr" />
|
||||
<use x="1696" xlink:href="#fr" />
|
||||
<use x="1802" xlink:href="#fr" />
|
||||
<use x="1908" xlink:href="#fr" />
|
||||
<use x="2014" xlink:href="#fr" />
|
||||
<use x="0" xlink:href="#es" />
|
||||
<use x="146" xlink:href="#es" />
|
||||
<use x="292" xlink:href="#es" />
|
||||
<use x="438" xlink:href="#es" />
|
||||
<use x="584" xlink:href="#es" />
|
||||
<use x="730" xlink:href="#es" />
|
||||
<use x="876" xlink:href="#es" />
|
||||
<use x="1022" xlink:href="#es" />
|
||||
<use x="1168" xlink:href="#es" />
|
||||
<use x="1314" xlink:href="#es" />
|
||||
<use x="1460" xlink:href="#es" />
|
||||
<use x="1606" xlink:href="#es" />
|
||||
<use x="1752" xlink:href="#es" />
|
||||
<use x="1898" xlink:href="#es" />
|
||||
<use x="2044" xlink:href="#es" />
|
||||
<use x="2190" xlink:href="#es" />
|
||||
<use x="2336" xlink:href="#es" />
|
||||
<use x="2482" xlink:href="#es" />
|
||||
<use x="2628" xlink:href="#es" />
|
||||
<use x="2774" xlink:href="#es" />
|
||||
<use x="0" xlink:href="#jp" />
|
||||
<use x="82" xlink:href="#jp" />
|
||||
<use x="164" xlink:href="#jp" />
|
||||
<use x="246" xlink:href="#jp" />
|
||||
<use x="328" xlink:href="#jp" />
|
||||
<use x="410" xlink:href="#jp" />
|
||||
<use x="492" xlink:href="#jp" />
|
||||
<use x="574" xlink:href="#jp" />
|
||||
<use x="656" xlink:href="#jp" />
|
||||
<use x="738" xlink:href="#jp" />
|
||||
<use x="820" xlink:href="#jp" />
|
||||
<use x="902" xlink:href="#jp" />
|
||||
<use x="984" xlink:href="#jp" />
|
||||
<use x="1066" xlink:href="#jp" />
|
||||
<use x="1148" xlink:href="#jp" />
|
||||
<use x="1230" xlink:href="#jp" />
|
||||
<use x="1312" xlink:href="#jp" />
|
||||
<use x="1394" xlink:href="#jp" />
|
||||
<use x="1476" xlink:href="#jp" />
|
||||
<use x="1558" xlink:href="#jp" />
|
||||
<use x="1640" xlink:href="#jp" />
|
||||
<use x="1722" xlink:href="#jp" />
|
||||
<use x="1804" xlink:href="#jp" />
|
||||
<use x="1886" xlink:href="#jp" />
|
||||
<use x="1968" xlink:href="#jp" />
|
||||
<use x="2050" xlink:href="#jp" />
|
||||
<use x="2132" xlink:href="#jp" />
|
||||
<use x="2214" xlink:href="#jp" />
|
||||
<use x="2296" xlink:href="#jp" />
|
||||
<use x="2378" xlink:href="#jp" />
|
||||
</g></defs>
|
||||
<g clip-path="url(#viewRect)"><g transform="rotate(-45) translate(-1248, 115)">
|
||||
<use xlink:href="#line-10" y="0" />
|
||||
<use xlink:href="#line-10" y="106" />
|
||||
<use xlink:href="#line-10" y="212" />
|
||||
<use xlink:href="#line-10" y="318" />
|
||||
<use xlink:href="#line-10" y="424" />
|
||||
<use xlink:href="#line-10" y="530" />
|
||||
<use xlink:href="#line-10" y="636" />
|
||||
<use xlink:href="#line-10" y="742" />
|
||||
<use xlink:href="#line-10" y="848" />
|
||||
<use xlink:href="#line-10" y="954" />
|
||||
<use xlink:href="#line-10" y="1060" />
|
||||
<use xlink:href="#line-10" y="1166" />
|
||||
<use xlink:href="#line-10" y="1272" />
|
||||
<use xlink:href="#line-10" y="1378" />
|
||||
<use xlink:href="#line-10" y="1484" />
|
||||
<use xlink:href="#line-10" y="1590" />
|
||||
<use xlink:href="#line-10" y="1696" />
|
||||
<use xlink:href="#line-10" y="1802" />
|
||||
<use xlink:href="#line-10" y="1908" />
|
||||
<use xlink:href="#line-10" y="2014" />
|
||||
</g></g>
|
||||
|
||||
<defs>
|
||||
<text id="en" x="0" y="0" transform="translate(0, -80)" class="text">WALL side</text>
|
||||
<text id="fr" x="0" y="0" transform="translate(-25, -56)" class="text">Côté MUR</text>
|
||||
<text id="es" x="0" y="0" transform="translate(-28, 0)" class="text">lado de la PARED</text>
|
||||
<text id="jp" x="0" y="0" transform="translate(-20, -27)" class="text japanese">かベ面</text>
|
||||
</defs>
|
||||
|
||||
<g class="wallside">
|
||||
<!--
|
||||
<use href="#en" />
|
||||
<use href="#en" x="106" class="draggable" />
|
||||
<use href="#en" y="106" class="draggable" />
|
||||
<use href="#fr" />
|
||||
<use href="#fr" x="106" class="draggable" />
|
||||
<use href="#es" />
|
||||
<use href="#es" x="146" class="draggable" />
|
||||
<use href="#jp" />
|
||||
<use href="#jp" x="82" class="draggable" />
|
||||
-->
|
||||
</g>
|
||||
|
||||
|
||||
<script type="text/javascript"><![CDATA[
|
||||
function makeDraggable(evt) {
|
||||
var svg = evt.target;
|
||||
|
||||
svg.addEventListener('mousedown', startDrag);
|
||||
svg.addEventListener('mousemove', drag);
|
||||
svg.addEventListener('mouseup', endDrag);
|
||||
svg.addEventListener('mouseleave', endDrag);
|
||||
svg.addEventListener('touchstart', startDrag);
|
||||
svg.addEventListener('touchmove', drag);
|
||||
svg.addEventListener('touchend', endDrag);
|
||||
svg.addEventListener('touchleave', endDrag);
|
||||
svg.addEventListener('touchcancel', endDrag);
|
||||
|
||||
function getMousePosition(evt) {
|
||||
var CTM = svg.getScreenCTM();
|
||||
if (evt.touches) { evt = evt.touches[0]; }
|
||||
return {
|
||||
x: (evt.clientX - CTM.e) / CTM.a,
|
||||
y: (evt.clientY - CTM.f) / CTM.d
|
||||
};
|
||||
}
|
||||
|
||||
var selectedElement, offset, transform;
|
||||
|
||||
function initialiseDragging(evt) {
|
||||
offset = getMousePosition(evt);
|
||||
|
||||
// Make sure the first transform on the element is a translate transform
|
||||
var transforms = selectedElement.transform.baseVal;
|
||||
|
||||
if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
|
||||
// Create an transform that translates by (0, 0)
|
||||
var translate = svg.createSVGTransform();
|
||||
translate.setTranslate(0, 0);
|
||||
selectedElement.transform.baseVal.insertItemBefore(translate, 0);
|
||||
}
|
||||
|
||||
// Get initial translation
|
||||
transform = transforms.getItem(0);
|
||||
offset.x -= transform.matrix.e;
|
||||
offset.y -= transform.matrix.f;
|
||||
}
|
||||
|
||||
function startDrag(evt) {
|
||||
if (evt.target.classList.contains('draggable')) {
|
||||
selectedElement = evt.target;
|
||||
initialiseDragging(evt);
|
||||
} else if (evt.target.parentNode.classList.contains('draggable-group')) {
|
||||
selectedElement = evt.target.parentNode;
|
||||
initialiseDragging(evt);
|
||||
}
|
||||
}
|
||||
|
||||
function drag(evt) {
|
||||
if (selectedElement) {
|
||||
evt.preventDefault();
|
||||
var coord = getMousePosition(evt);
|
||||
transform.setTranslate(coord.x - offset.x, coord.y - offset.y);
|
||||
}
|
||||
}
|
||||
|
||||
function endDrag(evt) {
|
||||
selectedElement = false;
|
||||
}
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
BIN
content/posts/WALL-side/wallside.svg.pdf
Normal file
BIN
content/posts/WALL-side/wallside.svg.pdf
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue