first commit
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
.make.*
|
||||
.DS_Store
|
||||
output/
|
275
aperiodical-logo.svg
Normal file
|
@ -0,0 +1,275 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="30cm"
|
||||
height="30cm"
|
||||
id="svg3055"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
inkscape:export-filename="/home/christian/Pictures/t-shirts/aperiodical-logo.png"
|
||||
inkscape:export-xdpi="500.04132"
|
||||
inkscape:export-ydpi="500.04132"
|
||||
sodipodi:docname="aperiodical-logo.svg">
|
||||
<defs
|
||||
id="defs3057">
|
||||
<clipPath
|
||||
id="clipPath6473"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6471"
|
||||
d="M 14,13.755905 H 179 V 178.7559 H 14 Z" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="mask6475"
|
||||
height="1"
|
||||
width="1"
|
||||
y="0"
|
||||
x="0"
|
||||
maskUnits="userSpaceOnUse">
|
||||
<g
|
||||
id="g6481">
|
||||
<g
|
||||
id="g6479"
|
||||
clip-path="url(#clipPath6473)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6477"
|
||||
style="fill:#000000;fill-opacity:0.98999999;fill-rule:nonzero;stroke:none"
|
||||
d="M 14,13.755905 H 179 V 178.75591 H 14 Z" />
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="clipPath6489"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6487"
|
||||
d="M 14,13.755905 H 179 V 178.7559 H 14 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6493"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6491"
|
||||
d="M 14,14 H 179 V 179 H 14 Z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48821792"
|
||||
inkscape:cx="766.91375"
|
||||
inkscape:cy="418.92832"
|
||||
inkscape:current-layer="g6802"
|
||||
showgrid="true"
|
||||
inkscape:document-units="cm"
|
||||
inkscape:grid-bbox="true"
|
||||
borderlayer="true"
|
||||
inkscape:window-width="1853"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="cm" />
|
||||
<metadata
|
||||
id="metadata3060">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,1069.8582)">
|
||||
<g
|
||||
transform="matrix(1.0666667,0,0,1.0666667,140.35172,-1149.7625)"
|
||||
id="layer1-7"
|
||||
inkscape:label="Layer 1">
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="circle4362"
|
||||
d="m 296.42131,912.47121 c 0,41.94782 23.22002,77.83443 63.74699,88.65949 55.63769,14.8615 115.75463,-26.94246 131.25687,-45.49392"
|
||||
style="opacity:0.98999999;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.33398107;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<g
|
||||
id="g6802"
|
||||
transform="translate(21.752994,-20.17165)">
|
||||
<g
|
||||
aria-label="aperiodical.com"
|
||||
transform="matrix(5.5903503,0,0,5.5903503,-1700.6466,-4656.1358)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.19848442px;line-height:0%;font-family:montserrat;-inkscape-font-specification:'montserrat, Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4338">
|
||||
<path
|
||||
d="m 292.83429,932.37217 c -1.10093,0.0554 -3.05483,0.87544 -2.94718,3.01378 0.065,1.29148 0.46466,2.90571 1.584,4.0592 -0.69014,0.20455 -1.22249,0.59218 -1.11591,2.70934 l 0.0298,0.59281 c 0.0224,0.44461 0.15794,0.60758 0.66606,0.582 l 0.35991,-0.0181 c 0.50812,-0.0256 0.58109,-0.26274 0.5619,-0.64383 -0.0396,-1.20785 0.0546,-1.44606 0.54044,-1.49175 l 4.42488,-0.22276 c 2.837,-0.14282 3.4163,-2.54922 3.30865,-4.68756 -0.0618,-1.22795 -0.23938,-3.49012 -1.89077,-3.40699 -0.65632,0.033 -1.07641,0.54237 -1.04657,1.13518 0.0192,0.38109 0.28725,1.06803 1.24104,1.04124 0.0361,0.29534 0.0765,0.67536 0.0999,1.14114 0.032,0.63515 0.0449,1.31371 -0.26506,1.9024 -0.42528,0.82797 -1.07947,0.90335 -1.56642,0.92787 l -0.48695,0.0245 c -0.14815,-2.94286 -0.97834,-6.78531 -3.49777,-6.65847 z m 0.14146,1.96683 c 0.76219,-0.0384 1.88457,0.75414 2.1707,4.75133 l -1.5667,0.0789 c -1.58788,0.0799 -1.97488,-1.70474 -2.01964,-2.59395 -0.0789,-1.5667 0.80167,-2.20534 1.41564,-2.23625 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path892"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 288.00037,944.77432 -1.589,0.26585 0.84653,5.05971 1.589,-0.26585 -0.26235,-1.5681 3.63797,-0.60866 c -0.53255,1.05629 -0.89068,2.38431 -0.62482,3.9733 0.38478,2.29987 2.24004,4.26774 5.8571,3.66258 2.90619,-0.48623 4.77311,-2.17414 4.38482,-4.49491 -0.19589,-1.17084 -0.70238,-3.04198 -1.88818,-4.47706 l 1.10811,-0.1854 -0.80716,-3.41132 -1.589,0.26585 0.0385,0.22999 c 0.1854,1.10811 0.11584,1.33468 -0.48699,1.45704 l -9.95215,1.66507 z m 6.752,2.45969 2.9271,-0.48973 c 0.14636,-0.0245 0.31362,-0.0525 0.45306,0.0102 0.48454,0.19835 1.47485,1.10732 1.7512,2.75904 0.32182,1.92352 -0.76459,3.39487 -2.83446,3.74118 -2.21624,0.3708 -3.71907,-0.90378 -4.0374,-2.8064 -0.27285,-1.63081 0.86237,-3.06734 1.7405,-3.21426 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path894"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:type="inkscape:offset"
|
||||
inkscape:radius="0"
|
||||
inkscape:original="M 299.94922 956.58398 C 299.2853 956.52897 298.5784 956.60299 297.8457 956.81641 C 294.69103 957.73527 293.54297 960.54351 294.38477 963.43359 C 295.17321 966.1405 297.72032 966.70122 298.31055 966.5293 C 298.6769 966.4226 298.59701 966.07029 298.48438 965.68359 L 298.43164 965.5 C 298.39014 965.35753 298.34243 965.19404 298.20508 965.10156 C 297.92449 964.89626 296.64982 965.0691 296.19336 963.50195 C 295.17372 960.00128 297.56828 959.128 298.2832 958.85352 L 300.19141 965.40625 C 300.31847 965.76667 300.4404 965.95289 300.94922 965.80469 C 302.92343 965.22966 305.15594 963.65199 304.17188 960.27344 C 303.53164 958.07534 301.94097 956.74903 299.94922 956.58398 z M 299.61523 958.57617 C 301.88268 958.40148 302.49235 960.18763 302.64648 960.7168 C 303.23336 962.73172 301.87959 963.54526 301.16211 963.88672 L 299.61523 958.57617 z "
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path896"
|
||||
d="m 299.94922,956.58398 c -0.66392,-0.055 -1.37082,0.019 -2.10352,0.23243 -3.15467,0.91886 -4.30273,3.7271 -3.46093,6.61718 0.78844,2.70691 3.33555,3.26763 3.92578,3.09571 0.36635,-0.1067 0.28646,-0.45901 0.17383,-0.84571 L 298.43164,965.5 c -0.0415,-0.14247 -0.0892,-0.30596 -0.22656,-0.39844 -0.28059,-0.2053 -1.55526,-0.0325 -2.01172,-1.59961 -1.01964,-3.50067 1.37492,-4.37395 2.08984,-4.64843 l 1.90821,6.55273 c 0.12706,0.36042 0.24899,0.54664 0.75781,0.39844 1.97421,-0.57503 4.20672,-2.1527 3.22266,-5.53125 -0.64024,-2.1981 -2.23091,-3.52441 -4.22266,-3.68946 z m -0.33399,1.99219 c 2.26745,-0.17469 2.87712,1.61146 3.03125,2.14063 0.58688,2.01492 -0.76689,2.82846 -1.48437,3.16992 z" />
|
||||
<path
|
||||
d="m 296.19102,968.84316 2.05225,5.06957 1.47371,-0.59658 -0.73976,-1.82741 2.55443,-1.03407 c 0.13755,-0.0557 0.28679,-0.13897 0.42433,-0.19465 1.86671,-0.75568 3.41111,-0.44322 4.33378,0.87561 -0.76165,0.49129 -0.60161,1.11259 -0.51411,1.32873 0.20682,0.51089 0.77902,0.85099 1.38815,0.60441 0.84493,-0.34205 1.10033,-1.40596 0.75033,-2.27054 l -0.008,-0.0196 c -0.23864,-0.58949 -0.88058,-1.61032 -2.62195,-1.95738 l 0.67978,-0.29806 0.88422,-0.35795 -1.4809,-3.03677 -1.49336,0.60454 0.0716,0.17685 c 0.47727,1.17897 0.42675,1.33664 -0.24134,1.60709 l -5.4429,2.20338 -0.59659,-1.47371 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path898"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 312.20874,972.50179 c -0.64265,0.32631 -0.99796,1.12486 -0.61407,1.88092 0.32632,0.64265 1.14377,0.98837 1.88093,0.61407 0.73716,-0.3743 0.96888,-1.22897 0.63297,-1.89052 -0.3743,-0.73716 -1.25718,-0.93079 -1.89983,-0.60447 z m -12.24442,5.29002 2.22661,4.38514 1.41761,-0.71981 -0.64303,-1.26639 7.61729,-3.86777 -1.7531,-2.93756 -1.43652,0.7294 0.0768,0.15122 c 0.54706,1.07738 0.49123,1.24837 -0.13252,1.56509 l -5.2357,2.65848 -0.71981,-1.41761 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path900"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 306.96975,980.99314 c -2.52423,1.63997 -3.05806,4.51475 -1.26795,7.27007 1.8132,2.79087 4.6453,3.45355 7.16953,1.81358 2.63088,-1.70926 3.24205,-4.65957 1.46349,-7.39711 -1.80166,-2.77309 -4.73419,-3.39581 -7.36507,-1.68654 z m 1.3629,1.59193 c 1.52876,-0.99322 3.21377,-1.27901 4.6805,0.97857 1.44363,2.22203 0.46844,3.63927 -1.04254,4.62095 -1.63542,1.06251 -3.37998,1.41227 -4.84672,-0.84531 -1.45518,-2.2398 -0.40888,-3.70324 1.20876,-4.75421 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path902"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 313.74193,991.21445 c -2.92175,2.61605 -2.23626,5.18048 -1.01347,6.56111 1.18062,1.33301 2.49637,1.92336 3.77041,2.21084 l -1.01563,0.8995 2.42654,2.5799 1.19019,-1.0541 -0.16866,-0.1905 c -0.78708,-0.8886 -0.77439,-1.0981 -0.26657,-1.5479 l 9.22002,-8.16592 -2.47959,-2.44795 -1.20606,1.06818 0.0843,0.0952 c 0.78708,0.88867 0.89227,1.13532 0.39851,1.60095 l -2.30104,2.03798 c -0.24572,-1.39647 -1.00377,-2.76393 -1.94546,-3.82717 -1.95364,-2.20582 -4.63052,-1.64729 -6.69352,0.17986 z m 1.36153,1.56924 c 1.36475,-1.20873 3.11397,-1.8235 4.92707,0.22362 1.02602,1.15846 0.987,2.29739 0.95299,2.61069 -0.034,0.3133 -0.073,0.4611 -0.37452,0.72815 l -2.18995,1.93959 c -0.72999,0.64653 -2.65919,0.51456 -3.85387,-0.83433 -1.04007,-1.17432 -1.55646,-2.81246 0.53828,-4.66772 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path904"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 328.8858,995.29632 c -0.47936,0.53823 -0.51894,1.41137 0.11427,1.97532 0.53823,0.47937 1.42547,0.50312 1.97532,-0.11426 0.54986,-0.61738 0.45389,-1.4977 -0.10017,-1.99116 -0.61738,-0.54986 -1.51006,-0.40813 -1.98942,0.1301 z m -9.47149,9.39158 3.67262,3.2709 1.05741,-1.1873 -1.06062,-0.9446 5.68186,-6.37958 -2.70376,-2.09579 -1.07152,1.2031 0.12664,0.11279 c 0.90233,0.80364 0.91272,0.98321 0.44745,1.50558 l -3.90539,4.385 -1.18727,-1.0574 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path906"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 327.33674,1005.0768 c -1.85964,2.5792 -1.22912,5.4381 1.24699,7.2234 2.63086,1.8968 4.98755,0.042 5.13632,-0.1645 0.13638,-0.1892 0.006,-0.3352 -0.21712,-0.4963 l -0.22354,-0.1612 c -0.44707,-0.3223 -0.48146,-0.3471 -0.60463,-0.3575 -0.35231,-0.019 -1.27653,1.118 -2.61776,0.151 -1.27244,-0.9174 -2.63442,-2.7618 -1.02273,-4.9972 1.81005,-2.5105 3.69354,-1.5706 4.86281,-0.7276 0.34391,0.248 0.67541,0.5131 1.00692,0.7783 l 0.0172,0.012 c -0.45952,0.8185 0.004,1.3356 0.24467,1.5092 0.48147,0.3471 1.1497,0.254 1.53403,-0.2791 0.96702,-1.3412 -0.85287,-2.7317 -1.91897,-3.5004 -3.50782,-2.5291 -6.22922,-0.6757 -7.44419,1.0095 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path908"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.80675,1012.9089 c -0.52252,0.9706 -0.83244,3.0668 1.05279,4.0817 1.1386,0.6129 2.72658,1.1067 4.29294,0.7461 -0.18227,0.6964 -0.12622,1.3525 1.74035,2.3574 l 0.52263,0.2813 c 0.39198,0.211 0.6016,0.1794 0.84276,-0.2685 l 0.17082,-0.3174 c 0.24116,-0.4479 0.076,-0.6331 -0.25995,-0.814 -1.05389,-0.5914 -1.20897,-0.7953 -0.99652,-1.2346 l 2.10012,-3.9012 c 1.34648,-2.5012 -0.41247,-4.2425 -2.2977,-5.2574 -1.0826,-0.5828 -3.10997,-1.602 -3.89375,-0.1461 -0.3115,0.5786 -0.0932,1.2017 0.42943,1.4831 0.33599,0.1809 1.06248,0.3071 1.53333,-0.5228 0.27136,0.122 0.61739,0.2842 1.02804,0.5053 0.55997,0.3015 1.14722,0.6417 1.49041,1.2116 0.48823,0.7925 0.21406,1.3912 -0.0171,1.8206 l -0.23111,0.4293 c -2.59452,-1.3968 -6.31178,-2.6757 -7.50754,-0.4544 z m 1.756,0.8971 c 0.36174,-0.6719 1.62083,-1.2219 5.18883,0.6025 l -0.74358,1.3813 c -0.75363,1.3999 -2.48089,0.8071 -3.26485,0.3851 -1.38125,-0.7436 -1.47181,-1.8276 -1.1804,-2.3689 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path910"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 344.02905,1020.9695 4.70793,1.9286 0.60268,-1.4712 -1.47122,-0.6027 4.98223,-12.1621 -3.32509,-1.1101 -0.61073,1.4908 0.21578,0.088 c 1.05928,0.4339 1.18762,0.624 0.97419,1.2009 l -4.00185,9.7689 -1.47123,-0.6027 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path912"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 351.76642,1022.4491 c -0.22365,0.6851 0.10339,1.5278 0.90948,1.7909 0.66502,0.217 1.51422,-0.1302 1.77075,-0.9161 0.25654,-0.7859 -0.21073,-1.5405 -0.8959,-1.7642 -0.68518,-0.2236 -1.5278,0.1034 -1.78433,0.8894 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path914"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 357.76823,1020.6593 c -0.70514,3.1006 0.99145,5.4865 3.96803,6.1635 3.16262,0.7192 4.6081,-1.9087 4.66451,-2.1567 0.0517,-0.2274 -0.12493,-0.3111 -0.39364,-0.3722 l -0.26872,-0.061 c -0.53744,-0.1222 -0.57878,-0.1316 -0.69624,-0.093 -0.3317,0.1202 -0.73874,1.5277 -2.35106,1.161 -1.52963,-0.3478 -3.50358,-1.5142 -2.89246,-4.2014 0.68634,-3.0179 2.78728,-2.8879 4.19289,-2.5683 0.41341,0.094 0.82212,0.2088 1.23084,0.3234 h 0.0207 c -0.10349,0.9331 0.52506,1.2282 0.81445,1.294 0.57878,0.1316 1.15763,-0.215 1.30336,-0.8558 0.36667,-1.6123 -1.85166,-2.182 -3.13324,-2.4735 -4.21682,-0.959 -5.9987,1.8098 -6.45939,3.8355 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path916"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 367.63255,1022.9958 c -0.32106,2.993 1.57189,5.2215 4.83892,5.5719 3.30917,0.355 5.61065,-1.4235 5.93172,-4.4165 0.33463,-3.1195 -1.5681,-5.4556 -4.81404,-5.8038 -3.2881,-0.3528 -5.62196,1.5289 -5.9566,4.6484 z m 2.095,-0.053 c 0.19445,-1.8126 1.03625,-3.3 3.7131,-3.0129 2.63469,0.2827 3.11852,1.9336 2.92633,3.7252 -0.20802,1.9391 -1.03778,3.5131 -3.71463,3.2259 -2.65577,-0.2849 -3.13056,-2.0201 -2.9248,-3.9382 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path918"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 379.55366,1029.3426 5.12524,-0.2217 -0.0687,-1.5884 -1.5884,0.069 -0.17409,-4.0239 c -0.10078,-2.3297 1.31463,-2.9638 2.45828,-3.0133 2.05525,-0.068 2.28159,0.75 2.32648,1.7878 l 0.21807,5.0405 -1.5884,0.069 0.0687,1.5884 5.12524,-0.2217 -0.0687,-1.5884 -1.5884,0.069 -0.17408,-4.0239 c -0.10079,-2.3297 1.33581,-2.9647 2.45828,-3.0133 1.97053,-0.064 2.25582,0.6451 2.3053,1.7887 l 0.21806,5.0405 -1.5884,0.069 0.0687,1.5884 5.12524,-0.2217 -0.0687,-1.5884 -1.5884,0.069 -0.21989,-5.0828 c -0.0623,-1.4402 -0.27642,-3.4467 -3.45322,-3.3092 -2.20258,0.095 -3.20563,1.433 -3.56669,1.9154 -0.30739,-0.7294 -0.90201,-1.7221 -3.21049,-1.6222 -2.13904,0.092 -3.16418,1.4099 -3.48563,1.827 l -0.0724,-1.6731 -3.42086,0.3814 0.0696,1.6096 0.19061,-0.01 c 1.27072,-0.055 1.40237,0.045 1.43352,0.7655 l 0.2538,5.8665 -1.5884,0.069 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'CMU Concrete';-inkscape-font-specification:'CMU Concrete Bold'"
|
||||
id="path920"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4352"
|
||||
transform="matrix(4.5334558,-0.15331679,0.15331679,4.5334558,-251.17595,-3633.3261)">
|
||||
<circle
|
||||
id="path3958"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000080;stroke-width:3.38588524;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
cx="391.24078"
|
||||
cy="854.32007"
|
||||
r="90.433044"
|
||||
transform="rotate(17.239481)" />
|
||||
<path
|
||||
sodipodi:end="2.6410428"
|
||||
sodipodi:start="0.56114361"
|
||||
d="M 147.49559,948.64735 A 30.697403,30.697403 0 0 1 120.57583,962.9949 30.697403,30.697403 0 0 1 94.574313,947.04351 l 26.931407,-14.73193 z"
|
||||
sodipodi:ry="30.697403"
|
||||
sodipodi:rx="30.697403"
|
||||
sodipodi:cy="932.31158"
|
||||
sodipodi:cx="121.50572"
|
||||
id="path3970"
|
||||
style="fill:#ffcc00;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3966"
|
||||
d="M 40.853279,976.2691 124.10437,931.28934"
|
||||
style="fill:none;stroke:#000080;stroke-width:3.30837727;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:9.12878418;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 123.30841,929.82718 0.0405,3.72615 72.48488,47.34908 1.80202,-2.77381 z"
|
||||
id="path3968"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3962"
|
||||
d="M 42.058202,975.48597 197.695,979.70377"
|
||||
style="fill:none;stroke:#000000;stroke-width:3.30837727;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.61675437, 3.30837718;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ff0000;stroke:none"
|
||||
id="path3975"
|
||||
sodipodi:cx="104.40775"
|
||||
sodipodi:cy="843.73779"
|
||||
sodipodi:rx="35.758743"
|
||||
sodipodi:ry="35.758743"
|
||||
d="m 123.86203,873.74144 a 35.758743,35.758743 0 0 1 -33.947564,2.6863 l 14.493284,-32.68995 z"
|
||||
sodipodi:start="0.99554875"
|
||||
sodipodi:end="1.9881115" />
|
||||
<path
|
||||
inkscape:transform-center-y="26.582871"
|
||||
inkscape:transform-center-x="15.139863"
|
||||
sodipodi:end="2.0160023"
|
||||
sodipodi:start="0.99554875"
|
||||
transform="rotate(22.319341)"
|
||||
d="m 504.37304,759.55705 a 35.758743,35.758743 0 0 1 -34.85356,2.26941 l 15.39928,-32.27305 z"
|
||||
sodipodi:ry="35.758743"
|
||||
sodipodi:rx="35.758743"
|
||||
sodipodi:cy="729.55341"
|
||||
sodipodi:cx="484.91876"
|
||||
id="path3979"
|
||||
style="fill:#000080;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3964"
|
||||
d="M 42.048374,975.54047 104.05984,844.7342 196.42961,978.86021 171.54466,859.91828 Z"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.98502636;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 22 KiB |
130
index.html
Normal file
|
@ -0,0 +1,130 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Design an aperiodic monotile thing</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<script src="script.js" defer></script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<section id="drawing">
|
||||
<svg viewBox="-100 -100 200 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<path id="spectre" class="spectre"
|
||||
d="m 1.5,-0.8660254 c 0.5735127,0.00665 0.2925127,0.4933532 0.8660254,0.5 0.281,0.5 -0.281,0.5 0,1 0.5,-0.281 0.5,0.281 1,0 0.4933531,0.2925127 0.00665,0.5735127 0.5,0.8660254 C 3.5735127,1.9933532 3.2925127,1.50665 3,2.0000001 2.4264873,1.9933501 2.7074873,1.5066468 2.1339746,1.5 c -0.00665,0.5735128 -0.4933532,0.2925128 -0.5,0.8660255 -0.5,0.281 -0.5,-0.281 -1,0 -0.5,0.281 -0.5,-0.281 -1,0 C -0.8593785,2.0735128 -0.3726754,1.7925128 -0.8660254,1.5 -0.5735127,1.0066468 -0.2925127,1.49335 0,1 -0.281,0.5 0.281,0.5 0,0 0.5,-0.281 0.5,0.281 0.99999998,0 1.00665,-0.5735127 1.4933531,-0.2925127 1.5,-0.8660254 Z"
|
||||
stroke="black"
|
||||
stroke-width="0.1"
|
||||
stroke-opacity="0.5"
|
||||
stroke-linejoin="round"
|
||||
fill="currentColor"></path>
|
||||
</defs>
|
||||
<g id="display">
|
||||
<g id="board" transform="translate(0 -120) rotate(90)"></g>
|
||||
<g id="guides">
|
||||
<line x1="-1000" x2="1000" stroke="black" style="transform: translate(0, calc(1px * var(--y0-hue)))"/>
|
||||
<line x1="-1000" x2="1000" stroke="black" style="transform: translate(0, calc(1px * var(--y1-hue)))"/>
|
||||
<line x1="-1000" x2="1000" stroke="black" style="transform: translate(0, calc(1px * var(--y0-lum)))"/>
|
||||
<line x1="-1000" x2="1000" stroke="black" style="transform: translate(0, calc(1px * var(--y1-lum)))"/>
|
||||
</g>
|
||||
<g id="draggables">
|
||||
<image class="draggable template hoodie" id="hoodie-back" href="template/hoodie_back_template.png" x="14" y="-71" />
|
||||
<image class="draggable template hoodie" id="hoodie-front" href="template/hoodie_front_template.png" x="54" y="-71" />
|
||||
<image class="draggable template hoodie" id="hoodie-front-pocket" href="template/hoodie_front_pocket_template.png" x="-17" y="-79" />
|
||||
<image class="draggable template hoodie" id="hoodie-hood" href="template/hoodie_hood_template.png" x="28" y="-111" />
|
||||
<image class="draggable template hoodie" id="hoodie-label-panel" href="template/hoodie_label_panel_template.png" x="71" y="-96" />
|
||||
<image class="draggable template hoodie" id="hoodie-left-sleeve" href="template/hoodie_left_sleeve_template.png" x="90" y="-70" />
|
||||
<image class="draggable template hoodie" id="hoodie-right-sleeve" href="template/hoodie_right_sleeve_template.png" x="121" y="-70" />
|
||||
<image class="draggable template tshirt" id="tshirt-right-sleeve" href="template/TShirt_Right_Sleeve.png" x="83" y="-60" />
|
||||
<image class="draggable template tshirt" id="tshirt-left-sleeve" href="template/TShirt_Left_Sleeve.png" x="42" y="-60" />
|
||||
<image class="draggable template tshirt" id="tshirt-front" href="template/TShirt_Front.png" x="2" y="-60" />
|
||||
<image class="draggable template tshirt" id="tshirt-back" href="template/TShirt_Back.png" x="-39" y="-60" />
|
||||
<circle class="draggable" id="y0-lum" cx="0" cy="30" r="5"/>
|
||||
<circle class="draggable" id="y1-lum" cx="0" cy="-150" r="5"/>
|
||||
<circle class="draggable" id="y0-hue" cx="30" cy="-100" r="5"/>
|
||||
<circle class="draggable" id="y1-hue" cx="30" cy="-30" r="5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</section>
|
||||
|
||||
<section id="controls">
|
||||
<details open>
|
||||
<summary>Instructions</summary>
|
||||
<p>Use the controls to change the colours.</p>
|
||||
<p>Drag the circles around to change the gradients of hue and lightness.</p>
|
||||
<p>Drag the templates for the pieces of the garment that will be cut out.</p>
|
||||
<p>When you're done, click the <em>Finish</em> button and <a href="mailto:christian+clothes@lawson-perfect.uk?subject=Please+make+this+for+me">send the file to me</a>.</p>
|
||||
</details>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend>View</legend>
|
||||
<label for="zoom">
|
||||
Zoom
|
||||
</label>
|
||||
<input type="range" min="0.2" max="10" value="1" step="0.01" id="zoom">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Colours</legend>
|
||||
<label for="min-hue">
|
||||
Hue 1
|
||||
</label>
|
||||
<div class="colour-input-wrapper">
|
||||
<input type="range" name="min-hue" id="min-hue" value="150" min="0" max="360">
|
||||
</div>
|
||||
<output for="min-hue"></output>
|
||||
|
||||
<label for="max-hue">
|
||||
Hue 2
|
||||
</label>
|
||||
<div class="colour-input-wrapper">
|
||||
<input type="range" id="max-hue" value="260" min="0" max="360">
|
||||
</div>
|
||||
<output for="max-hue"></output>
|
||||
|
||||
<label for="interpolation-long">
|
||||
Long way round
|
||||
</label>
|
||||
<input type="radio" name="hue-interpolation" value="longer hue" id="interpolation-long">
|
||||
|
||||
<label for="interpolation-short">
|
||||
Short way round
|
||||
</label>
|
||||
<input type="radio" checked name="hue-interpolation" value="shorter hue" id="interpolation-short">
|
||||
|
||||
<label for="sat-scale">
|
||||
Saturation scale:
|
||||
</label>
|
||||
<input type="range" min="0" max="5" step="0.001" id="sat-scale" value="1.5">
|
||||
<output for="sat-scale"></output>
|
||||
|
||||
<label for="randomisation">
|
||||
Randomisation:
|
||||
</label>
|
||||
<input type="range" min="0" max="1" step="0.01" id="randomisation" value="0.2">
|
||||
<output for="randomisation"></output>
|
||||
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Tiling</legend>
|
||||
<label for="num_iterations">Number of iterations</label>
|
||||
<input type="number" min="1" max="5" value="4" id="num_iterations">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Pieces</legend>
|
||||
<label for="template-name">Template</label>
|
||||
<select name="template-name" id="template-name">
|
||||
<option value="hoodie" selected>Hoodie</option>
|
||||
<option value="tshirt">T-shirt</option>
|
||||
</select>
|
||||
<label for="template-scale">Template scale</label>
|
||||
<input type="range" min="0.2" max="5" value="2" step="0.01" id="template-scale">
|
||||
</fieldset>
|
||||
|
||||
<button type="button" id="finish">Finish</button>
|
||||
<a id="link" download="aperiodic-monotile-design.svg">Download</a>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</html>
|
760
script.js
Normal file
|
@ -0,0 +1,760 @@
|
|||
// derived from https://cs.uwaterloo.ca/~csk/spectre/spectre.js
|
||||
|
||||
|
||||
const {PI, cos, sin} = Math;
|
||||
|
||||
const ident = [1,0,0,0,1,0];
|
||||
|
||||
let pan = {x: -100, y: 100};
|
||||
|
||||
function radians(degrees) {
|
||||
return degrees * PI / 180;
|
||||
}
|
||||
|
||||
let to_screen = [20, 0, 0, 0, -20, 0];
|
||||
let lw_scale = 1;
|
||||
|
||||
let sys;
|
||||
|
||||
let scale_centre;
|
||||
let scale_start;
|
||||
let scale_ts;
|
||||
|
||||
let reset_but;
|
||||
let tile_sel;
|
||||
let shape_sel;
|
||||
let colscheme_sel;
|
||||
|
||||
let subst_button;
|
||||
let translate_button;
|
||||
let scale_button;
|
||||
let dragging = false;
|
||||
let uibox = true;
|
||||
|
||||
const spectre = [
|
||||
pt(0, 0),
|
||||
pt(1.0, 0.0),
|
||||
pt(1.5, -0.8660254037844386),
|
||||
pt(2.366025403784439, -0.36602540378443865),
|
||||
pt(2.366025403784439, 0.6339745962155614),
|
||||
pt(3.366025403784439, 0.6339745962155614),
|
||||
pt(3.866025403784439, 1.5),
|
||||
pt(3.0, 2.0),
|
||||
pt(2.133974596215561, 1.5),
|
||||
pt(1.6339745962155614, 2.3660254037844393),
|
||||
pt(0.6339745962155614, 2.3660254037844393),
|
||||
pt(-0.3660254037844386, 2.3660254037844393),
|
||||
pt(-0.866025403784439, 1.5),
|
||||
pt(0.0, 1.0)
|
||||
];
|
||||
|
||||
const base_quad = [spectre[3], spectre[5], spectre[7], spectre[11]];
|
||||
|
||||
|
||||
const tile_names = [
|
||||
'Gamma', 'Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi' ];
|
||||
|
||||
const svg_point = ({x,y}) => `${x.toFixed(3)},${y.toFixed(3)}`;
|
||||
|
||||
function lerp(a,b,t) {
|
||||
return t*b + (1-t)*a;
|
||||
}
|
||||
|
||||
function pt( x, y )
|
||||
{
|
||||
return { x : x, y : y };
|
||||
}
|
||||
|
||||
// Affine matrix inverse
|
||||
function inv( T ) {
|
||||
const det = T[0]*T[4] - T[1]*T[3];
|
||||
return [T[4]/det, -T[1]/det, (T[1]*T[5]-T[2]*T[4])/det,
|
||||
-T[3]/det, T[0]/det, (T[2]*T[3]-T[0]*T[5])/det];
|
||||
};
|
||||
|
||||
// Affine matrix multiply
|
||||
function mul( A, B )
|
||||
{
|
||||
return [A[0]*B[0] + A[1]*B[3],
|
||||
A[0]*B[1] + A[1]*B[4],
|
||||
A[0]*B[2] + A[1]*B[5] + A[2],
|
||||
|
||||
A[3]*B[0] + A[4]*B[3],
|
||||
A[3]*B[1] + A[4]*B[4],
|
||||
A[3]*B[2] + A[4]*B[5] + A[5]];
|
||||
}
|
||||
|
||||
function padd( p, q )
|
||||
{
|
||||
return { x : p.x + q.x, y : p.y + q.y };
|
||||
}
|
||||
|
||||
function psub( p, q )
|
||||
{
|
||||
return { x : p.x - q.x, y : p.y - q.y };
|
||||
}
|
||||
|
||||
function pframe( o, p, q, a, b )
|
||||
{
|
||||
return { x : o.x + a*p.x + b*q.x, y : o.y + a*p.y + b*q.y };
|
||||
}
|
||||
|
||||
// Rotation matrix
|
||||
function trot( ang )
|
||||
{
|
||||
const c = cos( ang );
|
||||
const s = sin( ang );
|
||||
return [c, -s, 0, s, c, 0];
|
||||
}
|
||||
|
||||
//Scale matrix
|
||||
function tscale(x,y) {
|
||||
return [x,0,0,0,y,0];
|
||||
}
|
||||
|
||||
// Translation matrix
|
||||
function ttrans( tx, ty )
|
||||
{
|
||||
return [1, 0, tx, 0, 1, ty];
|
||||
}
|
||||
|
||||
// Translation matrix moving p to q
|
||||
function transTo( p, q )
|
||||
{
|
||||
return ttrans( q.x - p.x, q.y - p.y );
|
||||
}
|
||||
|
||||
|
||||
// Matrix * point
|
||||
function transPt( M, P )
|
||||
{
|
||||
return pt(M[0]*P.x + M[1]*P.y + M[2], M[3]*P.x + M[4]*P.y + M[5]);
|
||||
}
|
||||
|
||||
class Shape {
|
||||
constructor( pts, quad) {
|
||||
this.pts = pts;
|
||||
this.quad = quad;
|
||||
|
||||
let blah = true;
|
||||
|
||||
this.pts = [pts[pts.length-1]];
|
||||
for( const p of pts ) {
|
||||
const prev = this.pts[this.pts.length-1];
|
||||
const v = psub( p, prev );
|
||||
const w = pt( -v.y, v.x );
|
||||
if( blah ) {
|
||||
this.pts.push( pframe( prev, v, w, 0.33, 0.6 ) );
|
||||
this.pts.push( pframe( prev, v, w, 0.67, 0.6 ) );
|
||||
} else {
|
||||
this.pts.push( pframe( prev, v, w, 0.33, -0.6 ) );
|
||||
this.pts.push( pframe( prev, v, w, 0.67, -0.6 ) );
|
||||
}
|
||||
blah = !blah;
|
||||
this.pts.push( p );
|
||||
}
|
||||
}
|
||||
|
||||
streamSVG( S, stream ) {
|
||||
const tpts = this.pts.map(p => transPt( S, p ));
|
||||
|
||||
const [a,c,e,b,d,f] = S;
|
||||
const matS = [a,b,c,d,e,f].map(p=>p.toFixed(3));
|
||||
const s = `<use href="#spectre" transform="matrix(${matS.join(',')})"/>`;
|
||||
|
||||
stream.push( s );
|
||||
}
|
||||
|
||||
bounds(S) {
|
||||
const points = this.pts.map(p => transPt(S,p));
|
||||
return {
|
||||
minx: Math.min(...points.map(p => p.x)),
|
||||
miny: Math.min(...points.map(p => p.y)),
|
||||
maxx: Math.max(...points.map(p => p.x)),
|
||||
maxy: Math.max(...points.map(p => p.y)),
|
||||
};
|
||||
}
|
||||
|
||||
* flatten(S) {
|
||||
const points = this.pts.map(p => transPt(S,p));
|
||||
const ymax = Math.max(...points.map(p => p.y));
|
||||
yield {points, ymax, shape: this};
|
||||
}
|
||||
}
|
||||
|
||||
class Meta
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.geoms = [];
|
||||
this.quad = [];
|
||||
}
|
||||
|
||||
addChild( g, T )
|
||||
{
|
||||
this.geoms.push( { geom : g, xform: T } );
|
||||
}
|
||||
|
||||
draw( S )
|
||||
{
|
||||
for( let g of this.geoms ) {
|
||||
g.geom.draw( mul( S, g.xform ) );
|
||||
}
|
||||
}
|
||||
|
||||
streamSVG( S, stream )
|
||||
{
|
||||
const {minx,miny,maxx,maxy} = this.bounds(S);
|
||||
|
||||
const [a,c,e,b,d,f] = S;
|
||||
const matS = [a,b,c,d,e,f].map(p=>p.toFixed(3));
|
||||
stream.push(`<g transform="matrix(${matS.join(',')})">`);
|
||||
const quad_points = this.quad.map(({x,y}) => `${x},${y}`).join(' ');
|
||||
// stream.push(`<polygon fill="blue" fill-opacity="0.2" points="${quad_points}"></polygon>`);
|
||||
for( let g of this.geoms ) {
|
||||
g.geom.streamSVG( g.xform, stream );
|
||||
}
|
||||
stream.push('</g>');
|
||||
|
||||
}
|
||||
|
||||
bounds(S) {
|
||||
const sub_bounds = this.geoms.map(g => g.geom.bounds(mul(S,g.xform)));
|
||||
return {
|
||||
minx: Math.min(...sub_bounds.map(b=>b.minx)),
|
||||
miny: Math.min(...sub_bounds.map(b=>b.miny)),
|
||||
maxx: Math.max(...sub_bounds.map(b=>b.maxx)),
|
||||
maxy: Math.max(...sub_bounds.map(b=>b.maxy)),
|
||||
};
|
||||
}
|
||||
|
||||
* flatten(S) {
|
||||
for(let g of this.geoms) {
|
||||
yield* g.geom.flatten(mul(S, g.xform));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tiles(level, label) {
|
||||
let quad;
|
||||
let out = [];
|
||||
let transform;
|
||||
if(level == 0) {
|
||||
transform = ident;
|
||||
quad = base_quad;
|
||||
switch(label) {
|
||||
case 'Delta':
|
||||
case 'Theta':
|
||||
case 'Lambda':
|
||||
case 'Xi':
|
||||
case 'Pi':
|
||||
case 'Sigma':
|
||||
case 'Phi':
|
||||
case 'Psi':
|
||||
out.push(ident);
|
||||
case 'Gamma':
|
||||
const mystic = new Meta();
|
||||
out.push(ident);
|
||||
out.push(mul( ttrans( spectre[8].x, spectre[8].y ), trot( PI / 6 ) ));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Each of the subtiles is identical, but rotated and translated.
|
||||
*
|
||||
* Produce transformation matrices Ts for each of the subtiles: they're formed by rotating the quad and then matching up a pair of points.
|
||||
*
|
||||
* The whole thing is then reflected.
|
||||
*
|
||||
* The layout of subtiles depends on the larger tile.
|
||||
*
|
||||
*/
|
||||
const labels = ['Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi'];
|
||||
|
||||
const sublevels = Object.fromEntries(labels.map(label => tiles(level-1, label)));
|
||||
const subquad = sublevels['Delta'].quad;
|
||||
|
||||
const reflection = tscale(-1,1);
|
||||
|
||||
|
||||
// How to get from each subtile to the next.
|
||||
const t_rules = [
|
||||
[60, 3, 1], [0, 2, 0], [60, 3, 1], [60, 3, 1],
|
||||
[0, 2, 0], [60, 3, 1], [-120, 3, 3] ];
|
||||
|
||||
|
||||
let Ts = [ident];
|
||||
let total_ang = 0;
|
||||
let rot = ident;
|
||||
let tquad = [...subquad];
|
||||
for( const [ang,from,to] of t_rules ) {
|
||||
total_ang += ang;
|
||||
if( ang != 0 ) {
|
||||
rot = trot( radians( total_ang ) );
|
||||
tquad = subquad.map(q => transPt(rot,q));
|
||||
}
|
||||
|
||||
const ttt = transTo( tquad[to], transPt( Ts[Ts.length-1], subquad[from] ) );
|
||||
Ts.push( mul( ttt, rot ) );
|
||||
}
|
||||
|
||||
Ts = Ts.map(t => mul(reflection, t));
|
||||
|
||||
|
||||
// Now build the actual supertiles, labelling appropriately.
|
||||
const super_rules = {
|
||||
'Gamma' : ['Pi','Delta','null','Theta','Sigma','Xi','Phi','Gamma'],
|
||||
'Delta' : ['Xi','Delta','Xi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Theta' : ['Psi','Delta','Pi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Lambda' : ['Psi','Delta','Xi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Xi' : ['Psi','Delta','Pi','Phi','Sigma','Psi','Phi','Gamma'],
|
||||
'Pi' : ['Psi','Delta','Xi','Phi','Sigma','Psi','Phi','Gamma'],
|
||||
'Sigma' : ['Xi','Delta','Xi','Phi','Sigma','Pi','Lambda','Gamma'],
|
||||
'Phi' : ['Psi','Delta','Psi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Psi' : ['Psi','Delta','Psi','Phi','Sigma','Psi','Phi','Gamma'] };
|
||||
const super_quad = [
|
||||
transPt( Ts[6], subquad[2] ),
|
||||
transPt( Ts[5], subquad[1] ),
|
||||
transPt( Ts[3], subquad[2] ),
|
||||
transPt( Ts[0], subquad[1] ) ];
|
||||
}
|
||||
return {quad, tiles: out};
|
||||
}
|
||||
|
||||
|
||||
function buildSpectreBase() {
|
||||
const ret = {};
|
||||
|
||||
for( lab of ['Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi'] ) {
|
||||
ret[lab] = new Shape( spectre, base_quad, lab );
|
||||
}
|
||||
|
||||
const mystic = new Meta();
|
||||
mystic.addChild( new Shape( spectre, base_quad, 'Gamma1' ), ident );
|
||||
mystic.addChild( new Shape( spectre, base_quad, 'Gamma2' ),
|
||||
mul( ttrans( spectre[8].x, spectre[8].y ), trot( PI / 6 ) ) );
|
||||
mystic.quad = base_quad;
|
||||
ret['Gamma'] = mystic;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function buildHatTurtleBase( hat_dominant )
|
||||
{
|
||||
const r3 = 1.7320508075688772;
|
||||
const hr3 = 0.8660254037844386;
|
||||
|
||||
function hexPt( x, y )
|
||||
{
|
||||
return pt( x + 0.5*y, -hr3*y );
|
||||
}
|
||||
|
||||
function hexPt2( x, y )
|
||||
{
|
||||
return pt( x + hr3*y, -0.5*y );
|
||||
}
|
||||
|
||||
const hat = [
|
||||
hexPt(-1, 2), hexPt(0, 2), hexPt(0, 3), hexPt(2, 2), hexPt(3, 0),
|
||||
hexPt(4, 0), hexPt(5,-1), hexPt(4,-2), hexPt(2,-1), hexPt(2,-2),
|
||||
hexPt( 1, -2), hexPt(0,-2), hexPt(-1,-1), hexPt(0, 0) ];
|
||||
|
||||
const turtle = [
|
||||
hexPt(0,0), hexPt(2,-1), hexPt(3,0), hexPt(4,-1), hexPt(4,-2),
|
||||
hexPt(6,-3), hexPt(7,-5), hexPt(6,-5), hexPt(5,-4), hexPt(4,-5),
|
||||
hexPt(2,-4), hexPt(0,-3), hexPt(-1,-1), hexPt(0,-1)
|
||||
];
|
||||
|
||||
const hat_keys = [
|
||||
hat[3], hat[5], hat[7], hat[11]
|
||||
];
|
||||
const turtle_keys = [
|
||||
turtle[3], turtle[5], turtle[7], turtle[11]
|
||||
];
|
||||
|
||||
const ret = {};
|
||||
|
||||
if( hat_dominant ) {
|
||||
for( lab of ['Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi'] ) {
|
||||
ret[lab] = new Shape( hat, hat_keys, lab );
|
||||
}
|
||||
|
||||
const mystic = new Meta();
|
||||
mystic.addChild( new Shape( hat, hat_keys, 'Gamma1' ), ident );
|
||||
mystic.addChild( new Shape( turtle, turtle_keys, 'Gamma2' ),
|
||||
ttrans( hat[8].x, hat[8].y ) );
|
||||
mystic.quad = hat_keys;
|
||||
ret['Gamma'] = mystic;
|
||||
} else {
|
||||
for( lab of ['Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi'] ) {
|
||||
ret[lab] = new Shape( turtle, turtle_keys, lab );
|
||||
}
|
||||
|
||||
const mystic = new Meta();
|
||||
mystic.addChild( new Shape( turtle, turtle_keys, 'Gamma1' ), ident );
|
||||
mystic.addChild( new Shape( hat, hat_keys, 'Gamma2' ),
|
||||
mul( ttrans( turtle[9].x, turtle[9].y ), trot( PI/3 ) ) );
|
||||
mystic.quad = turtle_keys;
|
||||
ret['Gamma'] = mystic;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function buildHexBase()
|
||||
{
|
||||
const hr3 = 0.8660254037844386;
|
||||
|
||||
const hex = [
|
||||
pt(0, 0),
|
||||
pt(1.0, 0.0),
|
||||
pt(1.5, hr3),
|
||||
pt(1, 2*hr3),
|
||||
pt(0, 2*hr3),
|
||||
pt(-0.5, hr3)
|
||||
];
|
||||
|
||||
const hex_keys = [ hex[1], hex[2], hex[3], hex[5] ];
|
||||
|
||||
const ret = {};
|
||||
|
||||
for( lab of ['Gamma', 'Delta', 'Theta', 'Lambda', 'Xi',
|
||||
'Pi', 'Sigma', 'Phi', 'Psi'] ) {
|
||||
ret[lab] = new Shape( hex, hex_keys, lab );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function buildSupertiles( sys )
|
||||
{
|
||||
// First, use any of the nine-unit tiles in sys to obtain
|
||||
// a list of transformation matrices for placing tiles within
|
||||
// supertiles.
|
||||
|
||||
const quad = sys['Delta'].quad;
|
||||
const R = [-1,0,0,0,1,0];
|
||||
|
||||
const t_rules = [
|
||||
[60, 3, 1], [0, 2, 0], [60, 3, 1], [60, 3, 1],
|
||||
[0, 2, 0], [60, 3, 1], [-120, 3, 3] ];
|
||||
|
||||
const Ts = [ident];
|
||||
let total_ang = 0;
|
||||
let rot = ident;
|
||||
const tquad = [...quad];
|
||||
for( const [ang,from,to] of t_rules ) {
|
||||
total_ang += ang;
|
||||
if( ang != 0 ) {
|
||||
rot = trot( radians( total_ang ) );
|
||||
for( i = 0; i < 4; ++i ) {
|
||||
tquad[i] = transPt( rot, quad[i] );
|
||||
}
|
||||
}
|
||||
|
||||
const ttt = transTo( tquad[to],
|
||||
transPt( Ts[Ts.length-1], quad[from] ) );
|
||||
Ts.push( mul( ttt, rot ) );
|
||||
}
|
||||
|
||||
for( let idx = 0; idx < Ts.length; ++idx ) {
|
||||
Ts[idx] = mul( R, Ts[idx] );
|
||||
}
|
||||
|
||||
// Now build the actual supertiles, labelling appropriately.
|
||||
const super_rules = {
|
||||
'Gamma' : ['Pi','Delta','null','Theta','Sigma','Xi','Phi','Gamma'],
|
||||
'Delta' : ['Xi','Delta','Xi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Theta' : ['Psi','Delta','Pi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Lambda' : ['Psi','Delta','Xi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Xi' : ['Psi','Delta','Pi','Phi','Sigma','Psi','Phi','Gamma'],
|
||||
'Pi' : ['Psi','Delta','Xi','Phi','Sigma','Psi','Phi','Gamma'],
|
||||
'Sigma' : ['Xi','Delta','Xi','Phi','Sigma','Pi','Lambda','Gamma'],
|
||||
'Phi' : ['Psi','Delta','Psi','Phi','Sigma','Pi','Phi','Gamma'],
|
||||
'Psi' : ['Psi','Delta','Psi','Phi','Sigma','Psi','Phi','Gamma'] };
|
||||
const super_quad = [
|
||||
transPt( Ts[6], quad[2] ),
|
||||
transPt( Ts[5], quad[1] ),
|
||||
transPt( Ts[3], quad[2] ),
|
||||
transPt( Ts[0], quad[1] ) ];
|
||||
|
||||
const ret = {};
|
||||
|
||||
for( const [lab, subs] of Object.entries( super_rules ) ) {
|
||||
const sup = new Meta();
|
||||
for( let idx = 0; idx < 8; ++idx ) {
|
||||
if( subs[idx] == 'null' ) {
|
||||
continue;
|
||||
}
|
||||
sup.addChild( sys[subs[idx]], Ts[idx] );
|
||||
}
|
||||
sup.quad = super_quad;
|
||||
|
||||
ret[lab] = sup;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* modified from https://css-tricks.com/converting-color-spaces-in-javascript/
|
||||
*/
|
||||
function hexToHSL(H) {
|
||||
const [r,g,b] = [0,1,2].map(i=>H.slice(2*i+1,2*i+3)).map(n=>parseInt(n,16)/255);
|
||||
let cmin = Math.min(r,g,b),
|
||||
cmax = Math.max(r,g,b),
|
||||
delta = cmax - cmin,
|
||||
h = 0,
|
||||
s = 0,
|
||||
l = 0;
|
||||
|
||||
if (delta == 0)
|
||||
h = 0;
|
||||
else if (cmax == r)
|
||||
h = ((g - b) / delta) % 6;
|
||||
else if (cmax == g)
|
||||
h = (b - r) / delta + 2;
|
||||
else
|
||||
h = (r - g) / delta + 4;
|
||||
|
||||
h = Math.round(h * 60);
|
||||
|
||||
if (h < 0)
|
||||
h += 360;
|
||||
|
||||
l = (cmax + cmin) / 2;
|
||||
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
||||
s = +(s * 100).toFixed(1);
|
||||
l = +(l * 100).toFixed(1);
|
||||
|
||||
return {h,s,l};
|
||||
}
|
||||
|
||||
let last_num_iterations;
|
||||
|
||||
function get_settings() {
|
||||
return Object.fromEntries(
|
||||
Array.from(document.querySelectorAll('input,textarea')).map(i => [i.id, i.type=='number' ? i.valueAsNumber : i.value])
|
||||
);
|
||||
}
|
||||
|
||||
function rebuild() {
|
||||
const svg = document.querySelector('svg');
|
||||
const settings = get_settings();
|
||||
let sys = buildSpectreBase(false);
|
||||
|
||||
for(let i=0;i<settings.num_iterations;i++) {
|
||||
sys = buildSupertiles( sys );
|
||||
}
|
||||
|
||||
sys = sys['Delta'];
|
||||
window.sys = sys;
|
||||
|
||||
const drawing = [];
|
||||
const board = svg.querySelector('#board');
|
||||
board.innerHTML = '';
|
||||
sys.streamSVG(ident, drawing);
|
||||
board.innerHTML = drawing.join(' ');
|
||||
|
||||
const viewbox = svg.getBoundingClientRect();
|
||||
const rule = new Function('t','x','y', settings.colouring_rule);
|
||||
function visit(g, t) {
|
||||
for(let c of g.children) {
|
||||
visit(c, t+Math.random()*10-5);
|
||||
}
|
||||
if(g.tagName.toLowerCase()=='use') {
|
||||
const e = document.querySelector('defs .spectre').cloneNode(true);
|
||||
const b = g.getBoundingClientRect();
|
||||
const point = svg.createSVGPoint();
|
||||
point.x = b.x;
|
||||
point.y = b.y;
|
||||
const position = point.matrixTransform(svg.querySelector('#display').getScreenCTM().inverse());
|
||||
e.style.setProperty('--t',t);
|
||||
e.style.setProperty('--r',Math.random());
|
||||
e.style.setProperty('--x',position.x);
|
||||
e.style.setProperty('--y',position.y);
|
||||
e.removeAttribute('id');
|
||||
|
||||
g.replaceWith(e);
|
||||
e.setAttribute('transform', g.getAttribute('transform'));
|
||||
}
|
||||
}
|
||||
visit(board,30);
|
||||
make_download();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
const svg = document.querySelector('svg');
|
||||
const viewbox = svg.getBoundingClientRect();
|
||||
make_download();
|
||||
document.getElementById('link').click();
|
||||
}
|
||||
|
||||
function setup() {
|
||||
const settings = get_settings();
|
||||
const svg = document.querySelector('svg');
|
||||
const raw_zoom = document.getElementById('zoom').valueAsNumber;
|
||||
const zoom = raw_zoom;
|
||||
//const bounds = sys.bounds(ident);
|
||||
svg.querySelector('#display').setAttribute('transform',`scale(${zoom}) translate(${pan.x} ${pan.y})`);
|
||||
svg.style.setProperty('--zoom', zoom);
|
||||
svg.style.setProperty('--pan-x', pan.x);
|
||||
svg.style.setProperty('--pan-y', pan.y);
|
||||
|
||||
if(settings.num_iterations != last_num_iterations) {
|
||||
rebuild();
|
||||
last_num_iterations = settings.num_iterations;
|
||||
}
|
||||
}
|
||||
|
||||
for(let i of document.querySelectorAll('input')) {
|
||||
i.addEventListener('input', setup);
|
||||
i.addEventListener('change', setup)
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
document.getElementById('finish').addEventListener('click', () => finish());
|
||||
|
||||
function make_download() {
|
||||
const svg = document.querySelector('svg').cloneNode(true);
|
||||
document.body.append(svg);
|
||||
Array.from(svg.querySelectorAll('.spectre')).forEach(s => {
|
||||
s.setAttribute('fill', getComputedStyle(s).fill);
|
||||
});
|
||||
for(let e of svg.querySelectorAll('#guides, #draggables circle')) {
|
||||
e.parentElement.removeChild(e);
|
||||
}
|
||||
for(let img of svg.querySelectorAll('image.template')) {
|
||||
img.setAttribute('width', getComputedStyle(img).width);
|
||||
}
|
||||
document.body.removeChild(svg);
|
||||
const f = new File([svg.outerHTML],'aperiodic-monotile-clothes.svg',{type:'image/svg+xml'});
|
||||
const url = URL.createObjectURL(f);
|
||||
document.getElementById('link').setAttribute('href',url);
|
||||
}
|
||||
|
||||
function set_colours() {
|
||||
const svg = document.querySelector('svg');
|
||||
const fd = new FormData(document.querySelector('form'));
|
||||
console.log(fd);
|
||||
|
||||
svg.style.setProperty('--y0-lum', document.getElementById('y0-lum').cy.baseVal.value);
|
||||
svg.style.setProperty('--y1-lum', document.getElementById('y1-lum').cy.baseVal.value);
|
||||
svg.style.setProperty('--y0-hue', document.getElementById('y0-hue').cy.baseVal.value);
|
||||
svg.style.setProperty('--y1-hue', document.getElementById('y1-hue').cy.baseVal.value);
|
||||
|
||||
'back front front-pocket hood label-panel left-sleeve right-sleeve'.split(' ').forEach(w => {
|
||||
const img = document.getElementById(`hoodie-${w}`);
|
||||
svg.style.setProperty(`--hoodie-${w}-x`, img.x.baseVal.value);
|
||||
svg.style.setProperty(`--hoodie-${w}-y`, img.y.baseVal.value);
|
||||
});
|
||||
|
||||
svg.style.setProperty('--hue-interpolation', fd.get('hue-interpolation'));
|
||||
|
||||
svg.dataset.template = fd.get('template-name');
|
||||
|
||||
'min-hue max-hue sat-scale randomisation template-scale'.split(' ').forEach(w => {
|
||||
const n = document.getElementById(w).valueAsNumber;
|
||||
svg.style.setProperty(`--${w}`, n);
|
||||
const o = document.querySelector(`output[for="${w}"]`);
|
||||
if(o) {
|
||||
o.textContent = n;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Array.from(document.querySelectorAll('form :is(input,select)')).map(i => {
|
||||
i.addEventListener('input', set_colours);
|
||||
});
|
||||
set_colours();
|
||||
|
||||
function getsvg(event) {
|
||||
let t = event.target;
|
||||
while(t && t.tagName.toLowerCase() != 'svg') {
|
||||
t = t.parentElement;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function getcoords(svg, event) {
|
||||
const point = svg.createSVGPoint();
|
||||
point.x = event.clientX;
|
||||
point.y = event.clientY;
|
||||
const position = point.matrixTransform(svg.querySelector('#display').getScreenCTM().inverse());
|
||||
return position;
|
||||
}
|
||||
|
||||
function init_draggables() {
|
||||
let dragging = false;
|
||||
let off = null;
|
||||
const svg = document.querySelector('svg');
|
||||
|
||||
function coord_attributes(element) {
|
||||
switch(element.tagName.toLowerCase()) {
|
||||
case 'circle':
|
||||
return ['cx', 'cy'];
|
||||
default:
|
||||
return ['x', 'y'];
|
||||
}
|
||||
}
|
||||
|
||||
function get_element_centre(element) {
|
||||
const [xattr, yattr] = coord_attributes(element);
|
||||
return {x: element[xattr].baseVal.value, y: element[yattr].baseVal.value};
|
||||
}
|
||||
|
||||
function set_element_centre(element, p) {
|
||||
const [xattr, yattr] = coord_attributes(element);
|
||||
element.setAttribute(xattr, p.x - off.x);
|
||||
element.setAttribute(yattr, p.y - off.y);
|
||||
}
|
||||
|
||||
svg.addEventListener('pointerdown', e => {
|
||||
if(e.buttons == 1 && e.target.classList.contains('draggable')) {
|
||||
dragging = e.target;
|
||||
const p = getcoords(svg, e);
|
||||
const {x,y} = get_element_centre(dragging);
|
||||
off = {x: p.x - x, y: p.y - y};
|
||||
} else {
|
||||
dragging = svg;
|
||||
const z = svg.querySelector('#display').getScreenCTM().a;
|
||||
off = {x: e.clientX - pan.x*z, y: e.clientY - pan.y*z};
|
||||
}
|
||||
});
|
||||
|
||||
document.body.addEventListener('pointermove', e => {
|
||||
if(!dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dragging.classList.contains('draggable')) {
|
||||
const p = getcoords(svg, e);
|
||||
set_element_centre(dragging, p);
|
||||
set_colours();
|
||||
} else {
|
||||
const z = svg.querySelector('#display').getScreenCTM().a;
|
||||
pan.x = (e.clientX - off.x) / z;
|
||||
pan.y = (e.clientY - off.y) / z;
|
||||
setup();
|
||||
}
|
||||
});
|
||||
document.body.addEventListener('pointerup', () => {
|
||||
dragging = false;
|
||||
});
|
||||
|
||||
svg.addEventListener('wheel', e => {
|
||||
const dy = e.deltaY / 1000;
|
||||
const zoom_input = document.getElementById('zoom');
|
||||
zoom_input.value = zoom_input.valueAsNumber - dy;
|
||||
setup();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
set_colours();
|
||||
}
|
||||
|
||||
init_draggables();
|
33
spectre.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg312810"
|
||||
sodipodi:docname="spectre.svg"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.2.1 (9c6d41e, 2022-07-14)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs312814" /><sodipodi:namedview
|
||||
id="namedview312812"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="109.19085"
|
||||
inkscape:cx="1.657648"
|
||||
inkscape:cy="0.98451471"
|
||||
inkscape:window-width="1379"
|
||||
inkscape:window-height="847"
|
||||
inkscape:window-x="61"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg312810" /><path
|
||||
id="tile"
|
||||
d="m 1.5,-0.8660254 c 0.5735127,0.00665 0.2925127,0.4933532 0.8660254,0.5 0.281,0.5 -0.281,0.5 0,1 0.5,-0.281 0.5,0.281 1,0 0.4933531,0.2925127 0.00665,0.5735127 0.5,0.8660254 C 3.5735127,1.9933532 3.2925127,1.50665 3,2.0000001 2.4264873,1.9933501 2.7074873,1.5066468 2.1339746,1.5 c -0.00665,0.5735128 -0.4933532,0.2925128 -0.5,0.8660255 -0.5,0.281 -0.5,-0.281 -1,0 -0.5,0.281 -0.5,-0.281 -1,0 C -0.8593785,2.0735128 -0.3726754,1.7925128 -0.8660254,1.5 -0.5735127,1.0066468 -0.2925127,1.49335 0,1 -0.281,0.5 0.281,0.5 0,0 0.5,-0.281 0.5,0.281 0.99999998,0 1.00665,-0.5735127 1.4933531,-0.2925127 1.5,-0.8660254 Z"
|
||||
style="fill:#ff0000" /></svg>
|
After Width: | Height: | Size: 1.7 KiB |
102
style.css
Normal file
|
@ -0,0 +1,102 @@
|
|||
:root {
|
||||
--min-hue: 150;
|
||||
--max-hue: 260;
|
||||
--sat-scale: 1.5;
|
||||
--y0-lum: 800;
|
||||
--y1-lum: 0;
|
||||
--y0-hue: 800;
|
||||
--y1-hue: 0;
|
||||
--scale-y: 0.01;
|
||||
--randomisation: 0.2;
|
||||
--template-scale: 1;
|
||||
--hue-interpolation: longer hue;
|
||||
}
|
||||
|
||||
|
||||
svg {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
border: 1px solid black;
|
||||
}
|
||||
body {
|
||||
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
grid-template:
|
||||
"drawing controls" / 1fr 1fr;
|
||||
gap: 1em;
|
||||
}
|
||||
fieldset {
|
||||
display: grid;
|
||||
gap: 1em;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
|
||||
& label {
|
||||
justify-self: end;
|
||||
grid-column: 1;
|
||||
}
|
||||
& input {
|
||||
grid-column: 2;
|
||||
}
|
||||
& output {
|
||||
justify-self: start;
|
||||
grid-column: 3;
|
||||
}
|
||||
}
|
||||
.colour-input-wrapper {
|
||||
display: inline-block;
|
||||
background-image: linear-gradient(in hsl longer hue to right, hsl(0, 100%, 50%), hsl(360, 100%, 50%));
|
||||
|
||||
& input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.spectre {
|
||||
--sat: calc(var(--t) * var(--sat-scale) * 1%);
|
||||
--min-r: calc(1 - var(--randomisation));
|
||||
--max-r: calc(1 + var(--randomisation));
|
||||
--random: calc(var(--min-r) + (var(--max-r) - var(--min-r)) * var(--r));
|
||||
--lum: calc(100% * ((var(--y) - var(--y0-lum)) / (var(--y1-lum) - var(--y0-lum))) * var(--random));
|
||||
--mix: calc(100% * ((var(--y) - var(--y0-hue)) / (var(--y1-hue) - var(--y0-hue))));
|
||||
|
||||
--col1: hsl(var(--min-hue), var(--sat), var(--lum));
|
||||
--col2: hsl(var(--max-hue), var(--sat), var(--lum));
|
||||
fill: color-mix(in hsl var(--hue-interpolation), var(--col1), var(--col2) var(--mix));
|
||||
}
|
||||
|
||||
#draggables circle {
|
||||
r: calc(5px / var(--zoom));
|
||||
stroke-width: calc(0.5px / var(--zoom));
|
||||
stroke: white;
|
||||
fill: black;
|
||||
|
||||
&#y1-lum {
|
||||
fill: white;
|
||||
stroke: black;
|
||||
}
|
||||
|
||||
&#y0-hue {
|
||||
fill: hsl(var(--min-hue), 100%, 50%);
|
||||
}
|
||||
|
||||
&#y1-hue {
|
||||
fill: hsl(var(--max-hue), 100%, 50%);
|
||||
}
|
||||
}
|
||||
|
||||
#draggables image {
|
||||
width: calc(20px * var(--template-scale));
|
||||
}
|
||||
|
||||
svg:not([data-template="hoodie"]) #draggables image.template.hoodie {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg:not([data-template="tshirt"]) #draggables image.template.tshirt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#link {
|
||||
display: none;
|
||||
}
|
BIN
template/TShirt_Back.png
Normal file
After Width: | Height: | Size: 350 KiB |
BIN
template/TShirt_Front.png
Normal file
After Width: | Height: | Size: 386 KiB |
BIN
template/TShirt_Left_Sleeve.png
Normal file
After Width: | Height: | Size: 269 KiB |
BIN
template/TShirt_Right_Sleeve.png
Normal file
After Width: | Height: | Size: 271 KiB |
BIN
template/hoodie_back_template.png
Normal file
After Width: | Height: | Size: 437 KiB |
BIN
template/hoodie_front_pocket_template.png
Normal file
After Width: | Height: | Size: 308 KiB |
BIN
template/hoodie_front_template.png
Normal file
After Width: | Height: | Size: 522 KiB |
BIN
template/hoodie_hood_template.png
Normal file
After Width: | Height: | Size: 870 KiB |
BIN
template/hoodie_label_panel_template.png
Normal file
After Width: | Height: | Size: 311 KiB |
BIN
template/hoodie_left_sleeve_template.png
Normal file
After Width: | Height: | Size: 509 KiB |
BIN
template/hoodie_right_sleeve_template.png
Normal file
After Width: | Height: | Size: 513 KiB |