this repo has no description
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

๐Ÿšš Move artworks to examples.rs

authored by

Gwenn Le Bihan and committed by
Ewen Le Bihan
29f0a6b4 6d15149a

+783 -107
examples/dna-analysis-machine.png

This is a binary file and will not be displayed.

out.png

This is a binary file and will not be displayed.

+575
out.svg
··· 1 + <svg height="470" viewBox="-10 -10 470 470" width="470" xmlns="http://www.w3.org/2000/svg"> 2 + <rect fill="#000000" height="470" width="470" x="-10" y="-10"/> 3 + <g class="layer" data-layer="root"> 4 + <g data-object="4-6" style="fill: url(#pattern-hatched-bottom-up-white-6.5);"> 5 + <circle cx="200" cy="300" r="2"/> 6 + </g> 7 + <g data-object="4-5" style="fill: url(#pattern-hatched-bottom-up-white-5.5);"> 8 + <circle cx="200" cy="250" r="2"/> 9 + </g> 10 + <g data-object="2-0" style="fill: url(#pattern-hatched-bottom-up-white-0.3);"> 11 + <circle cx="100" cy="0" r="2"/> 12 + </g> 13 + <g data-object="5-4" style="fill: url(#pattern-hatched-bottom-up-white-4.6);"> 14 + <circle cx="250" cy="200" r="2"/> 15 + </g> 16 + <g data-object="5-1" style="fill: url(#pattern-hatched-bottom-up-white-1.6);"> 17 + <circle cx="250" cy="50" r="2"/> 18 + </g> 19 + <g data-object="6-1" style="fill: url(#pattern-hatched-bottom-up-white-1.7);"> 20 + <circle cx="300" cy="50" r="2"/> 21 + </g> 22 + <g data-object="0-5" style="fill: url(#pattern-hatched-bottom-up-white-5.1);"> 23 + <circle cx="0" cy="250" r="2"/> 24 + </g> 25 + <g data-object="8-3" style="fill: url(#pattern-hatched-bottom-up-white-3.9);"> 26 + <circle cx="400" cy="150" r="2"/> 27 + </g> 28 + <g data-object="5-6" style="fill: url(#pattern-hatched-bottom-up-white-6.6);"> 29 + <circle cx="250" cy="300" r="2"/> 30 + </g> 31 + <g data-object="1-6" style="fill: url(#pattern-hatched-bottom-up-white-6.2);"> 32 + <circle cx="50" cy="300" r="2"/> 33 + </g> 34 + <g data-object="8-2" style="fill: url(#pattern-hatched-bottom-up-white-2.9);"> 35 + <circle cx="400" cy="100" r="2"/> 36 + </g> 37 + <g data-object="0-3" style="fill: url(#pattern-hatched-bottom-up-white-3.1);"> 38 + <circle cx="0" cy="150" r="2"/> 39 + </g> 40 + <g data-object="0-4" style="fill: url(#pattern-hatched-bottom-up-white-4.1);"> 41 + <circle cx="0" cy="200" r="2"/> 42 + </g> 43 + <g data-object="7-2" style="fill: url(#pattern-hatched-bottom-up-white-2.8);"> 44 + <circle cx="350" cy="100" r="2"/> 45 + </g> 46 + <g data-object="1-3" style="fill: url(#pattern-hatched-bottom-up-white-3.2);"> 47 + <circle cx="50" cy="150" r="2"/> 48 + </g> 49 + <g data-object="3-1" style="fill: url(#pattern-hatched-bottom-up-white-1.4);"> 50 + <circle cx="150" cy="50" r="2"/> 51 + </g> 52 + <g data-object="2-2" style="fill: url(#pattern-hatched-bottom-up-white-2.3);"> 53 + <circle cx="100" cy="100" r="2"/> 54 + </g> 55 + <g data-object="3-3" style="fill: url(#pattern-hatched-bottom-up-white-3.4);"> 56 + <circle cx="150" cy="150" r="2"/> 57 + </g> 58 + <g data-object="5-3" style="fill: url(#pattern-hatched-bottom-up-white-3.6);"> 59 + <circle cx="250" cy="150" r="2"/> 60 + </g> 61 + <g data-object="7-3" style="fill: url(#pattern-hatched-bottom-up-white-3.8);"> 62 + <circle cx="350" cy="150" r="2"/> 63 + </g> 64 + <g data-object="1-4" style="fill: url(#pattern-hatched-bottom-up-white-4.2);"> 65 + <circle cx="50" cy="200" r="2"/> 66 + </g> 67 + <g data-object="2-4" style="fill: url(#pattern-hatched-bottom-up-white-4.3);"> 68 + <circle cx="100" cy="200" r="2"/> 69 + </g> 70 + <g data-object="0-6" style="fill: url(#pattern-hatched-bottom-up-white-6.1);"> 71 + <circle cx="0" cy="300" r="2"/> 72 + </g> 73 + <g data-object="1-8" style="fill: url(#pattern-hatched-bottom-up-white-8.2);"> 74 + <circle cx="50" cy="400" r="2"/> 75 + </g> 76 + <g data-object="3-0" style="fill: url(#pattern-hatched-bottom-up-white-0.4);"> 77 + <circle cx="150" cy="0" r="2"/> 78 + </g> 79 + <g data-object="4-4" style="fill: url(#pattern-hatched-bottom-up-white-4.5);"> 80 + <circle cx="200" cy="200" r="2"/> 81 + </g> 82 + <g data-object="6-6" style="fill: url(#pattern-hatched-bottom-up-white-6.7);"> 83 + <circle cx="300" cy="300" r="2"/> 84 + </g> 85 + <g data-object="5-2" style="fill: url(#pattern-hatched-bottom-up-white-2.6);"> 86 + <circle cx="250" cy="100" r="2"/> 87 + </g> 88 + <g data-object="4-7" style="fill: url(#pattern-hatched-bottom-up-white-7.5);"> 89 + <circle cx="200" cy="350" r="2"/> 90 + </g> 91 + <g data-object="7-6" style="fill: url(#pattern-hatched-bottom-up-white-6.8);"> 92 + <circle cx="350" cy="300" r="2"/> 93 + </g> 94 + <g data-object="6-0" style="fill: url(#pattern-hatched-bottom-up-white-0.7);"> 95 + <circle cx="300" cy="0" r="2"/> 96 + </g> 97 + <g data-object="0-2" style="fill: url(#pattern-hatched-bottom-up-white-2.1);"> 98 + <circle cx="0" cy="100" r="2"/> 99 + </g> 100 + <g data-object="0-8" style="fill: url(#pattern-hatched-bottom-up-white-8.1);"> 101 + <circle cx="0" cy="400" r="2"/> 102 + </g> 103 + <g data-object="7-5" style="fill: url(#pattern-hatched-bottom-up-white-5.8);"> 104 + <circle cx="350" cy="250" r="2"/> 105 + </g> 106 + <g data-object="8-5" style="fill: url(#pattern-hatched-bottom-up-white-5.9);"> 107 + <circle cx="400" cy="250" r="2"/> 108 + </g> 109 + <g data-object="8-0" style="fill: url(#pattern-hatched-bottom-up-white-0.9);"> 110 + <circle cx="400" cy="0" r="2"/> 111 + </g> 112 + <g data-object="8-1" style="fill: url(#pattern-hatched-bottom-up-white-1.9);"> 113 + <circle cx="400" cy="50" r="2"/> 114 + </g> 115 + <g data-object="3-4" style="fill: url(#pattern-hatched-bottom-up-white-4.4);"> 116 + <circle cx="150" cy="200" r="2"/> 117 + </g> 118 + <g data-object="3-7" style="fill: url(#pattern-hatched-bottom-up-white-7.4);"> 119 + <circle cx="150" cy="350" r="2"/> 120 + </g> 121 + <g data-object="7-1" style="fill: url(#pattern-hatched-bottom-up-white-1.8);"> 122 + <circle cx="350" cy="50" r="2"/> 123 + </g> 124 + <g data-object="2-8" style="fill: url(#pattern-hatched-bottom-up-white-8.3);"> 125 + <circle cx="100" cy="400" r="2"/> 126 + </g> 127 + <g data-object="2-7" style="fill: url(#pattern-hatched-bottom-up-white-7.3);"> 128 + <circle cx="100" cy="350" r="2"/> 129 + </g> 130 + <g data-object="1-2" style="fill: url(#pattern-hatched-bottom-up-white-2.2);"> 131 + <circle cx="50" cy="100" r="2"/> 132 + </g> 133 + <g data-object="4-0" style="fill: url(#pattern-hatched-bottom-up-white-0.5);"> 134 + <circle cx="200" cy="0" r="2"/> 135 + </g> 136 + <g data-object="5-0" style="fill: url(#pattern-hatched-bottom-up-white-0.6);"> 137 + <circle cx="250" cy="0" r="2"/> 138 + </g> 139 + <g data-object="8-4" style="fill: url(#pattern-hatched-bottom-up-white-4.9);"> 140 + <circle cx="400" cy="200" r="2"/> 141 + </g> 142 + <g data-object="4-1" style="fill: url(#pattern-hatched-bottom-up-white-1.5);"> 143 + <circle cx="200" cy="50" r="2"/> 144 + </g> 145 + <g data-object="6-3" style="fill: url(#pattern-hatched-bottom-up-white-3.7);"> 146 + <circle cx="300" cy="150" r="2"/> 147 + </g> 148 + <g data-object="8-7" style="fill: url(#pattern-hatched-bottom-up-white-7.9);"> 149 + <circle cx="400" cy="350" r="2"/> 150 + </g> 151 + <g data-object="6-5" style="fill: url(#pattern-hatched-bottom-up-white-5.7);"> 152 + <circle cx="300" cy="250" r="2"/> 153 + </g> 154 + <g data-object="5-7" style="fill: url(#pattern-hatched-bottom-up-white-7.6);"> 155 + <circle cx="250" cy="350" r="2"/> 156 + </g> 157 + <g data-object="8-6" style="fill: url(#pattern-hatched-bottom-up-white-6.9);"> 158 + <circle cx="400" cy="300" r="2"/> 159 + </g> 160 + <g data-object="7-7" style="fill: url(#pattern-hatched-bottom-up-white-7.8);"> 161 + <circle cx="350" cy="350" r="2"/> 162 + </g> 163 + <g data-object="3-6" style="fill: url(#pattern-hatched-bottom-up-white-6.4);"> 164 + <circle cx="150" cy="300" r="2"/> 165 + </g> 166 + <g data-object="7-0" style="fill: url(#pattern-hatched-bottom-up-white-0.8);"> 167 + <circle cx="350" cy="0" r="2"/> 168 + </g> 169 + <g data-object="0-7" style="fill: url(#pattern-hatched-bottom-up-white-7.1);"> 170 + <circle cx="0" cy="350" r="2"/> 171 + </g> 172 + <g data-object="5-8" style="fill: url(#pattern-hatched-bottom-up-white-8.6);"> 173 + <circle cx="250" cy="400" r="2"/> 174 + </g> 175 + <g data-object="2-1" style="fill: url(#pattern-hatched-bottom-up-white-1.3);"> 176 + <circle cx="100" cy="50" r="2"/> 177 + </g> 178 + <g data-object="7-8" style="fill: url(#pattern-hatched-bottom-up-white-8.8);"> 179 + <circle cx="350" cy="400" r="2"/> 180 + </g> 181 + <g data-object="3-5" style="fill: url(#pattern-hatched-bottom-up-white-5.4);"> 182 + <circle cx="150" cy="250" r="2"/> 183 + </g> 184 + <g data-object="6-2" style="fill: url(#pattern-hatched-bottom-up-white-2.7);"> 185 + <circle cx="300" cy="100" r="2"/> 186 + </g> 187 + <g data-object="6-7" style="fill: url(#pattern-hatched-bottom-up-white-7.7);"> 188 + <circle cx="300" cy="350" r="2"/> 189 + </g> 190 + <g data-object="1-1" style="fill: url(#pattern-hatched-bottom-up-white-1.2);"> 191 + <circle cx="50" cy="50" r="2"/> 192 + </g> 193 + <g data-object="2-3" style="fill: url(#pattern-hatched-bottom-up-white-3.3);"> 194 + <circle cx="100" cy="150" r="2"/> 195 + </g> 196 + <g data-object="4-8" style="fill: url(#pattern-hatched-bottom-up-white-8.5);"> 197 + <circle cx="200" cy="400" r="2"/> 198 + </g> 199 + <g data-object="2-6" style="fill: url(#pattern-hatched-bottom-up-white-6.3);"> 200 + <circle cx="100" cy="300" r="2"/> 201 + </g> 202 + <g data-object="1-7" style="fill: url(#pattern-hatched-bottom-up-white-7.2);"> 203 + <circle cx="50" cy="350" r="2"/> 204 + </g> 205 + <g data-object="4-2" style="fill: url(#pattern-hatched-bottom-up-white-2.5);"> 206 + <circle cx="200" cy="100" r="2"/> 207 + </g> 208 + <g data-object="7-4" style="fill: url(#pattern-hatched-bottom-up-white-4.8);"> 209 + <circle cx="350" cy="200" r="2"/> 210 + </g> 211 + <g data-object="6-8" style="fill: url(#pattern-hatched-bottom-up-white-8.7);"> 212 + <circle cx="300" cy="400" r="2"/> 213 + </g> 214 + <g data-object="6-4" style="fill: url(#pattern-hatched-bottom-up-white-4.7);"> 215 + <circle cx="300" cy="200" r="2"/> 216 + </g> 217 + <g data-object="1-0" style="fill: url(#pattern-hatched-bottom-up-white-0.2);"> 218 + <circle cx="50" cy="0" r="2"/> 219 + </g> 220 + <g data-object="0-1" style="fill: url(#pattern-hatched-bottom-up-white-1.1);"> 221 + <circle cx="0" cy="50" r="2"/> 222 + </g> 223 + <g data-object="3-2" style="fill: url(#pattern-hatched-bottom-up-white-2.4);"> 224 + <circle cx="150" cy="100" r="2"/> 225 + </g> 226 + <g data-object="4-3" style="fill: url(#pattern-hatched-bottom-up-white-3.5);"> 227 + <circle cx="200" cy="150" r="2"/> 228 + </g> 229 + <g data-object="2-5" style="fill: url(#pattern-hatched-bottom-up-white-5.3);"> 230 + <circle cx="100" cy="250" r="2"/> 231 + </g> 232 + <g data-object="1-5" style="fill: url(#pattern-hatched-bottom-up-white-5.2);"> 233 + <circle cx="50" cy="250" r="2"/> 234 + </g> 235 + <g data-object="5-5" style="fill: url(#pattern-hatched-bottom-up-white-5.6);"> 236 + <circle cx="250" cy="250" r="2"/> 237 + </g> 238 + <g data-object="3-8" style="fill: url(#pattern-hatched-bottom-up-white-8.4);"> 239 + <circle cx="150" cy="400" r="2"/> 240 + </g> 241 + <g data-object="0-0" style="fill: url(#pattern-hatched-bottom-up-white-0.1);"> 242 + <circle cx="0" cy="0" r="2"/> 243 + </g> 244 + <g data-object="8-8" style="fill: url(#pattern-hatched-bottom-up-white-8.9);"> 245 + <circle cx="400" cy="400" r="2"/> 246 + </g> 247 + </g> 248 + <g class="layer" data-layer="root"/> 249 + <defs> 250 + <pattern height="13" id="pattern-hatched-bottom-up-white-6.5" patternUnits="userSpaceOnUse" viewBox="0,0,6.5,6.5" width="13"> 251 + <polygon fill="#ffffff" points="0,0 1.625,0 0,1.625"/> 252 + <polygon fill="#ffffff" points="0,6.5 6.5,0 6.5,1.625 1.625,6.5"/> 253 + </pattern> 254 + <pattern height="11" id="pattern-hatched-bottom-up-white-5.5" patternUnits="userSpaceOnUse" viewBox="0,0,5.5,5.5" width="11"> 255 + <polygon fill="#ffffff" points="0,0 1.375,0 0,1.375"/> 256 + <polygon fill="#ffffff" points="0,5.5 5.5,0 5.5,1.375 1.375,5.5"/> 257 + </pattern> 258 + <pattern height="0.6" id="pattern-hatched-bottom-up-white-0.3" patternUnits="userSpaceOnUse" viewBox="0,0,0.3,0.3" width="0.6"> 259 + <polygon fill="#ffffff" points="0,0 0.075,0 0,0.075"/> 260 + <polygon fill="#ffffff" points="0,0.3 0.3,0 0.3,0.075 0.075,0.3"/> 261 + </pattern> 262 + <pattern height="9.2" id="pattern-hatched-bottom-up-white-4.6" patternUnits="userSpaceOnUse" viewBox="0,0,4.6,4.6" width="9.2"> 263 + <polygon fill="#ffffff" points="0,0 1.15,0 0,1.15"/> 264 + <polygon fill="#ffffff" points="0,4.6 4.6,0 4.6,1.15 1.15,4.6"/> 265 + </pattern> 266 + <pattern height="3.2" id="pattern-hatched-bottom-up-white-1.6" patternUnits="userSpaceOnUse" viewBox="0,0,1.6,1.6" width="3.2"> 267 + <polygon fill="#ffffff" points="0,0 0.4,0 0,0.4"/> 268 + <polygon fill="#ffffff" points="0,1.6 1.6,0 1.6,0.4 0.4,1.6"/> 269 + </pattern> 270 + <pattern height="3.4" id="pattern-hatched-bottom-up-white-1.7" patternUnits="userSpaceOnUse" viewBox="0,0,1.7,1.7" width="3.4"> 271 + <polygon fill="#ffffff" points="0,0 0.425,0 0,0.425"/> 272 + <polygon fill="#ffffff" points="0,1.7 1.7,0 1.7,0.425 0.425,1.7"/> 273 + </pattern> 274 + <pattern height="10.2" id="pattern-hatched-bottom-up-white-5.1" patternUnits="userSpaceOnUse" viewBox="0,0,5.1,5.1" width="10.2"> 275 + <polygon fill="#ffffff" points="0,0 1.275,0 0,1.275"/> 276 + <polygon fill="#ffffff" points="0,5.1 5.1,0 5.1,1.275 1.275,5.1"/> 277 + </pattern> 278 + <pattern height="7.8" id="pattern-hatched-bottom-up-white-3.9" patternUnits="userSpaceOnUse" viewBox="0,0,3.9,3.9" width="7.8"> 279 + <polygon fill="#ffffff" points="0,0 0.975,0 0,0.975"/> 280 + <polygon fill="#ffffff" points="0,3.9 3.9,0 3.9,0.975 0.975,3.9"/> 281 + </pattern> 282 + <pattern height="13.2" id="pattern-hatched-bottom-up-white-6.6" patternUnits="userSpaceOnUse" viewBox="0,0,6.6,6.6" width="13.2"> 283 + <polygon fill="#ffffff" points="0,0 1.65,0 0,1.65"/> 284 + <polygon fill="#ffffff" points="0,6.6 6.6,0 6.6,1.65 1.65,6.6"/> 285 + </pattern> 286 + <pattern height="12.4" id="pattern-hatched-bottom-up-white-6.2" patternUnits="userSpaceOnUse" viewBox="0,0,6.2,6.2" width="12.4"> 287 + <polygon fill="#ffffff" points="0,0 1.55,0 0,1.55"/> 288 + <polygon fill="#ffffff" points="0,6.2 6.2,0 6.2,1.55 1.55,6.2"/> 289 + </pattern> 290 + <pattern height="5.8" id="pattern-hatched-bottom-up-white-2.9" patternUnits="userSpaceOnUse" viewBox="0,0,2.9,2.9" width="5.8"> 291 + <polygon fill="#ffffff" points="0,0 0.725,0 0,0.725"/> 292 + <polygon fill="#ffffff" points="0,2.9 2.9,0 2.9,0.725 0.725,2.9"/> 293 + </pattern> 294 + <pattern height="6.2" id="pattern-hatched-bottom-up-white-3.1" patternUnits="userSpaceOnUse" viewBox="0,0,3.1,3.1" width="6.2"> 295 + <polygon fill="#ffffff" points="0,0 0.775,0 0,0.775"/> 296 + <polygon fill="#ffffff" points="0,3.1 3.1,0 3.1,0.775 0.775,3.1"/> 297 + </pattern> 298 + <pattern height="8.2" id="pattern-hatched-bottom-up-white-4.1" patternUnits="userSpaceOnUse" viewBox="0,0,4.1,4.1" width="8.2"> 299 + <polygon fill="#ffffff" points="0,0 1.025,0 0,1.025"/> 300 + <polygon fill="#ffffff" points="0,4.1 4.1,0 4.1,1.025 1.025,4.1"/> 301 + </pattern> 302 + <pattern height="5.6" id="pattern-hatched-bottom-up-white-2.8" patternUnits="userSpaceOnUse" viewBox="0,0,2.8,2.8" width="5.6"> 303 + <polygon fill="#ffffff" points="0,0 0.7,0 0,0.7"/> 304 + <polygon fill="#ffffff" points="0,2.8 2.8,0 2.8,0.7 0.7,2.8"/> 305 + </pattern> 306 + <pattern height="6.4" id="pattern-hatched-bottom-up-white-3.2" patternUnits="userSpaceOnUse" viewBox="0,0,3.2,3.2" width="6.4"> 307 + <polygon fill="#ffffff" points="0,0 0.8,0 0,0.8"/> 308 + <polygon fill="#ffffff" points="0,3.2 3.2,0 3.2,0.8 0.8,3.2"/> 309 + </pattern> 310 + <pattern height="2.8" id="pattern-hatched-bottom-up-white-1.4" patternUnits="userSpaceOnUse" viewBox="0,0,1.4,1.4" width="2.8"> 311 + <polygon fill="#ffffff" points="0,0 0.35,0 0,0.35"/> 312 + <polygon fill="#ffffff" points="0,1.4 1.4,0 1.4,0.35 0.35,1.4"/> 313 + </pattern> 314 + <pattern height="4.6" id="pattern-hatched-bottom-up-white-2.3" patternUnits="userSpaceOnUse" viewBox="0,0,2.3,2.3" width="4.6"> 315 + <polygon fill="#ffffff" points="0,0 0.575,0 0,0.575"/> 316 + <polygon fill="#ffffff" points="0,2.3 2.3,0 2.3,0.575 0.575,2.3"/> 317 + </pattern> 318 + <pattern height="6.8" id="pattern-hatched-bottom-up-white-3.4" patternUnits="userSpaceOnUse" viewBox="0,0,3.4,3.4" width="6.8"> 319 + <polygon fill="#ffffff" points="0,0 0.85,0 0,0.85"/> 320 + <polygon fill="#ffffff" points="0,3.4 3.4,0 3.4,0.85 0.85,3.4"/> 321 + </pattern> 322 + <pattern height="7.2" id="pattern-hatched-bottom-up-white-3.6" patternUnits="userSpaceOnUse" viewBox="0,0,3.6,3.6" width="7.2"> 323 + <polygon fill="#ffffff" points="0,0 0.9,0 0,0.9"/> 324 + <polygon fill="#ffffff" points="0,3.6 3.6,0 3.6,0.9 0.9,3.6"/> 325 + </pattern> 326 + <pattern height="7.6" id="pattern-hatched-bottom-up-white-3.8" patternUnits="userSpaceOnUse" viewBox="0,0,3.8,3.8" width="7.6"> 327 + <polygon fill="#ffffff" points="0,0 0.95,0 0,0.95"/> 328 + <polygon fill="#ffffff" points="0,3.8 3.8,0 3.8,0.95 0.95,3.8"/> 329 + </pattern> 330 + <pattern height="8.4" id="pattern-hatched-bottom-up-white-4.2" patternUnits="userSpaceOnUse" viewBox="0,0,4.2,4.2" width="8.4"> 331 + <polygon fill="#ffffff" points="0,0 1.05,0 0,1.05"/> 332 + <polygon fill="#ffffff" points="0,4.2 4.2,0 4.2,1.05 1.05,4.2"/> 333 + </pattern> 334 + <pattern height="8.6" id="pattern-hatched-bottom-up-white-4.3" patternUnits="userSpaceOnUse" viewBox="0,0,4.3,4.3" width="8.6"> 335 + <polygon fill="#ffffff" points="0,0 1.075,0 0,1.075"/> 336 + <polygon fill="#ffffff" points="0,4.3 4.3,0 4.3,1.075 1.075,4.3"/> 337 + </pattern> 338 + <pattern height="12.2" id="pattern-hatched-bottom-up-white-6.1" patternUnits="userSpaceOnUse" viewBox="0,0,6.1,6.1" width="12.2"> 339 + <polygon fill="#ffffff" points="0,0 1.525,0 0,1.525"/> 340 + <polygon fill="#ffffff" points="0,6.1 6.1,0 6.1,1.525 1.525,6.1"/> 341 + </pattern> 342 + <pattern height="16.4" id="pattern-hatched-bottom-up-white-8.2" patternUnits="userSpaceOnUse" viewBox="0,0,8.2,8.2" width="16.4"> 343 + <polygon fill="#ffffff" points="0,0 2.05,0 0,2.05"/> 344 + <polygon fill="#ffffff" points="0,8.2 8.2,0 8.2,2.05 2.05,8.2"/> 345 + </pattern> 346 + <pattern height="0.8" id="pattern-hatched-bottom-up-white-0.4" patternUnits="userSpaceOnUse" viewBox="0,0,0.4,0.4" width="0.8"> 347 + <polygon fill="#ffffff" points="0,0 0.1,0 0,0.1"/> 348 + <polygon fill="#ffffff" points="0,0.4 0.4,0 0.4,0.1 0.1,0.4"/> 349 + </pattern> 350 + <pattern height="9" id="pattern-hatched-bottom-up-white-4.5" patternUnits="userSpaceOnUse" viewBox="0,0,4.5,4.5" width="9"> 351 + <polygon fill="#ffffff" points="0,0 1.125,0 0,1.125"/> 352 + <polygon fill="#ffffff" points="0,4.5 4.5,0 4.5,1.125 1.125,4.5"/> 353 + </pattern> 354 + <pattern height="13.4" id="pattern-hatched-bottom-up-white-6.7" patternUnits="userSpaceOnUse" viewBox="0,0,6.7,6.7" width="13.4"> 355 + <polygon fill="#ffffff" points="0,0 1.675,0 0,1.675"/> 356 + <polygon fill="#ffffff" points="0,6.7 6.7,0 6.7,1.675 1.675,6.7"/> 357 + </pattern> 358 + <pattern height="5.2" id="pattern-hatched-bottom-up-white-2.6" patternUnits="userSpaceOnUse" viewBox="0,0,2.6,2.6" width="5.2"> 359 + <polygon fill="#ffffff" points="0,0 0.65,0 0,0.65"/> 360 + <polygon fill="#ffffff" points="0,2.6 2.6,0 2.6,0.65 0.65,2.6"/> 361 + </pattern> 362 + <pattern height="15" id="pattern-hatched-bottom-up-white-7.5" patternUnits="userSpaceOnUse" viewBox="0,0,7.5,7.5" width="15"> 363 + <polygon fill="#ffffff" points="0,0 1.875,0 0,1.875"/> 364 + <polygon fill="#ffffff" points="0,7.5 7.5,0 7.5,1.875 1.875,7.5"/> 365 + </pattern> 366 + <pattern height="13.6" id="pattern-hatched-bottom-up-white-6.8" patternUnits="userSpaceOnUse" viewBox="0,0,6.8,6.8" width="13.6"> 367 + <polygon fill="#ffffff" points="0,0 1.7,0 0,1.7"/> 368 + <polygon fill="#ffffff" points="0,6.8 6.8,0 6.8,1.7 1.7,6.8"/> 369 + </pattern> 370 + <pattern height="1.4" id="pattern-hatched-bottom-up-white-0.7" patternUnits="userSpaceOnUse" viewBox="0,0,0.7,0.7" width="1.4"> 371 + <polygon fill="#ffffff" points="0,0 0.175,0 0,0.175"/> 372 + <polygon fill="#ffffff" points="0,0.7 0.7,0 0.7,0.175 0.175,0.7"/> 373 + </pattern> 374 + <pattern height="4.2" id="pattern-hatched-bottom-up-white-2.1" patternUnits="userSpaceOnUse" viewBox="0,0,2.1,2.1" width="4.2"> 375 + <polygon fill="#ffffff" points="0,0 0.525,0 0,0.525"/> 376 + <polygon fill="#ffffff" points="0,2.1 2.1,0 2.1,0.525 0.525,2.1"/> 377 + </pattern> 378 + <pattern height="16.2" id="pattern-hatched-bottom-up-white-8.1" patternUnits="userSpaceOnUse" viewBox="0,0,8.1,8.1" width="16.2"> 379 + <polygon fill="#ffffff" points="0,0 2.025,0 0,2.025"/> 380 + <polygon fill="#ffffff" points="0,8.1 8.1,0 8.1,2.025 2.025,8.1"/> 381 + </pattern> 382 + <pattern height="11.6" id="pattern-hatched-bottom-up-white-5.8" patternUnits="userSpaceOnUse" viewBox="0,0,5.8,5.8" width="11.6"> 383 + <polygon fill="#ffffff" points="0,0 1.45,0 0,1.45"/> 384 + <polygon fill="#ffffff" points="0,5.8 5.8,0 5.8,1.45 1.45,5.8"/> 385 + </pattern> 386 + <pattern height="11.8" id="pattern-hatched-bottom-up-white-5.9" patternUnits="userSpaceOnUse" viewBox="0,0,5.9,5.9" width="11.8"> 387 + <polygon fill="#ffffff" points="0,0 1.475,0 0,1.475"/> 388 + <polygon fill="#ffffff" points="0,5.9 5.9,0 5.9,1.475 1.475,5.9"/> 389 + </pattern> 390 + <pattern height="1.8" id="pattern-hatched-bottom-up-white-0.9" patternUnits="userSpaceOnUse" viewBox="0,0,0.9,0.9" width="1.8"> 391 + <polygon fill="#ffffff" points="0,0 0.225,0 0,0.225"/> 392 + <polygon fill="#ffffff" points="0,0.9 0.9,0 0.9,0.225 0.225,0.9"/> 393 + </pattern> 394 + <pattern height="3.8" id="pattern-hatched-bottom-up-white-1.9" patternUnits="userSpaceOnUse" viewBox="0,0,1.9,1.9" width="3.8"> 395 + <polygon fill="#ffffff" points="0,0 0.475,0 0,0.475"/> 396 + <polygon fill="#ffffff" points="0,1.9 1.9,0 1.9,0.475 0.475,1.9"/> 397 + </pattern> 398 + <pattern height="8.8" id="pattern-hatched-bottom-up-white-4.4" patternUnits="userSpaceOnUse" viewBox="0,0,4.4,4.4" width="8.8"> 399 + <polygon fill="#ffffff" points="0,0 1.1,0 0,1.1"/> 400 + <polygon fill="#ffffff" points="0,4.4 4.4,0 4.4,1.1 1.1,4.4"/> 401 + </pattern> 402 + <pattern height="14.8" id="pattern-hatched-bottom-up-white-7.4" patternUnits="userSpaceOnUse" viewBox="0,0,7.4,7.4" width="14.8"> 403 + <polygon fill="#ffffff" points="0,0 1.85,0 0,1.85"/> 404 + <polygon fill="#ffffff" points="0,7.4 7.4,0 7.4,1.85 1.85,7.4"/> 405 + </pattern> 406 + <pattern height="3.6" id="pattern-hatched-bottom-up-white-1.8" patternUnits="userSpaceOnUse" viewBox="0,0,1.8,1.8" width="3.6"> 407 + <polygon fill="#ffffff" points="0,0 0.45,0 0,0.45"/> 408 + <polygon fill="#ffffff" points="0,1.8 1.8,0 1.8,0.45 0.45,1.8"/> 409 + </pattern> 410 + <pattern height="16.6" id="pattern-hatched-bottom-up-white-8.3" patternUnits="userSpaceOnUse" viewBox="0,0,8.3,8.3" width="16.6"> 411 + <polygon fill="#ffffff" points="0,0 2.075,0 0,2.075"/> 412 + <polygon fill="#ffffff" points="0,8.3 8.3,0 8.3,2.075 2.075,8.3"/> 413 + </pattern> 414 + <pattern height="14.6" id="pattern-hatched-bottom-up-white-7.3" patternUnits="userSpaceOnUse" viewBox="0,0,7.3,7.3" width="14.6"> 415 + <polygon fill="#ffffff" points="0,0 1.825,0 0,1.825"/> 416 + <polygon fill="#ffffff" points="0,7.3 7.3,0 7.3,1.825 1.825,7.3"/> 417 + </pattern> 418 + <pattern height="4.4" id="pattern-hatched-bottom-up-white-2.2" patternUnits="userSpaceOnUse" viewBox="0,0,2.2,2.2" width="4.4"> 419 + <polygon fill="#ffffff" points="0,0 0.55,0 0,0.55"/> 420 + <polygon fill="#ffffff" points="0,2.2 2.2,0 2.2,0.55 0.55,2.2"/> 421 + </pattern> 422 + <pattern height="1" id="pattern-hatched-bottom-up-white-0.5" patternUnits="userSpaceOnUse" viewBox="0,0,0.5,0.5" width="1"> 423 + <polygon fill="#ffffff" points="0,0 0.125,0 0,0.125"/> 424 + <polygon fill="#ffffff" points="0,0.5 0.5,0 0.5,0.125 0.125,0.5"/> 425 + </pattern> 426 + <pattern height="1.2" id="pattern-hatched-bottom-up-white-0.6" patternUnits="userSpaceOnUse" viewBox="0,0,0.6,0.6" width="1.2"> 427 + <polygon fill="#ffffff" points="0,0 0.15,0 0,0.15"/> 428 + <polygon fill="#ffffff" points="0,0.6 0.6,0 0.6,0.15 0.15,0.6"/> 429 + </pattern> 430 + <pattern height="9.8" id="pattern-hatched-bottom-up-white-4.9" patternUnits="userSpaceOnUse" viewBox="0,0,4.9,4.9" width="9.8"> 431 + <polygon fill="#ffffff" points="0,0 1.225,0 0,1.225"/> 432 + <polygon fill="#ffffff" points="0,4.9 4.9,0 4.9,1.225 1.225,4.9"/> 433 + </pattern> 434 + <pattern height="3" id="pattern-hatched-bottom-up-white-1.5" patternUnits="userSpaceOnUse" viewBox="0,0,1.5,1.5" width="3"> 435 + <polygon fill="#ffffff" points="0,0 0.375,0 0,0.375"/> 436 + <polygon fill="#ffffff" points="0,1.5 1.5,0 1.5,0.375 0.375,1.5"/> 437 + </pattern> 438 + <pattern height="7.4" id="pattern-hatched-bottom-up-white-3.7" patternUnits="userSpaceOnUse" viewBox="0,0,3.7,3.7" width="7.4"> 439 + <polygon fill="#ffffff" points="0,0 0.925,0 0,0.925"/> 440 + <polygon fill="#ffffff" points="0,3.7 3.7,0 3.7,0.925 0.925,3.7"/> 441 + </pattern> 442 + <pattern height="15.8" id="pattern-hatched-bottom-up-white-7.9" patternUnits="userSpaceOnUse" viewBox="0,0,7.9,7.9" width="15.8"> 443 + <polygon fill="#ffffff" points="0,0 1.975,0 0,1.975"/> 444 + <polygon fill="#ffffff" points="0,7.9 7.9,0 7.9,1.975 1.975,7.9"/> 445 + </pattern> 446 + <pattern height="11.4" id="pattern-hatched-bottom-up-white-5.7" patternUnits="userSpaceOnUse" viewBox="0,0,5.7,5.7" width="11.4"> 447 + <polygon fill="#ffffff" points="0,0 1.425,0 0,1.425"/> 448 + <polygon fill="#ffffff" points="0,5.7 5.7,0 5.7,1.425 1.425,5.7"/> 449 + </pattern> 450 + <pattern height="15.2" id="pattern-hatched-bottom-up-white-7.6" patternUnits="userSpaceOnUse" viewBox="0,0,7.6,7.6" width="15.2"> 451 + <polygon fill="#ffffff" points="0,0 1.9,0 0,1.9"/> 452 + <polygon fill="#ffffff" points="0,7.6 7.6,0 7.6,1.9 1.9,7.6"/> 453 + </pattern> 454 + <pattern height="13.8" id="pattern-hatched-bottom-up-white-6.9" patternUnits="userSpaceOnUse" viewBox="0,0,6.9,6.9" width="13.8"> 455 + <polygon fill="#ffffff" points="0,0 1.725,0 0,1.725"/> 456 + <polygon fill="#ffffff" points="0,6.9 6.9,0 6.9,1.725 1.725,6.9"/> 457 + </pattern> 458 + <pattern height="15.6" id="pattern-hatched-bottom-up-white-7.8" patternUnits="userSpaceOnUse" viewBox="0,0,7.8,7.8" width="15.6"> 459 + <polygon fill="#ffffff" points="0,0 1.95,0 0,1.95"/> 460 + <polygon fill="#ffffff" points="0,7.8 7.8,0 7.8,1.95 1.95,7.8"/> 461 + </pattern> 462 + <pattern height="12.8" id="pattern-hatched-bottom-up-white-6.4" patternUnits="userSpaceOnUse" viewBox="0,0,6.4,6.4" width="12.8"> 463 + <polygon fill="#ffffff" points="0,0 1.6,0 0,1.6"/> 464 + <polygon fill="#ffffff" points="0,6.4 6.4,0 6.4,1.6 1.6,6.4"/> 465 + </pattern> 466 + <pattern height="1.6" id="pattern-hatched-bottom-up-white-0.8" patternUnits="userSpaceOnUse" viewBox="0,0,0.8,0.8" width="1.6"> 467 + <polygon fill="#ffffff" points="0,0 0.2,0 0,0.2"/> 468 + <polygon fill="#ffffff" points="0,0.8 0.8,0 0.8,0.2 0.2,0.8"/> 469 + </pattern> 470 + <pattern height="14.2" id="pattern-hatched-bottom-up-white-7.1" patternUnits="userSpaceOnUse" viewBox="0,0,7.1,7.1" width="14.2"> 471 + <polygon fill="#ffffff" points="0,0 1.775,0 0,1.775"/> 472 + <polygon fill="#ffffff" points="0,7.1 7.1,0 7.1,1.775 1.775,7.1"/> 473 + </pattern> 474 + <pattern height="17.2" id="pattern-hatched-bottom-up-white-8.6" patternUnits="userSpaceOnUse" viewBox="0,0,8.6,8.6" width="17.2"> 475 + <polygon fill="#ffffff" points="0,0 2.15,0 0,2.15"/> 476 + <polygon fill="#ffffff" points="0,8.6 8.6,0 8.6,2.15 2.15,8.6"/> 477 + </pattern> 478 + <pattern height="2.6" id="pattern-hatched-bottom-up-white-1.3" patternUnits="userSpaceOnUse" viewBox="0,0,1.3,1.3" width="2.6"> 479 + <polygon fill="#ffffff" points="0,0 0.325,0 0,0.325"/> 480 + <polygon fill="#ffffff" points="0,1.3 1.3,0 1.3,0.325 0.325,1.3"/> 481 + </pattern> 482 + <pattern height="17.6" id="pattern-hatched-bottom-up-white-8.8" patternUnits="userSpaceOnUse" viewBox="0,0,8.8,8.8" width="17.6"> 483 + <polygon fill="#ffffff" points="0,0 2.2,0 0,2.2"/> 484 + <polygon fill="#ffffff" points="0,8.8 8.8,0 8.8,2.2 2.2,8.8"/> 485 + </pattern> 486 + <pattern height="10.8" id="pattern-hatched-bottom-up-white-5.4" patternUnits="userSpaceOnUse" viewBox="0,0,5.4,5.4" width="10.8"> 487 + <polygon fill="#ffffff" points="0,0 1.35,0 0,1.35"/> 488 + <polygon fill="#ffffff" points="0,5.4 5.4,0 5.4,1.35 1.35,5.4"/> 489 + </pattern> 490 + <pattern height="5.4" id="pattern-hatched-bottom-up-white-2.7" patternUnits="userSpaceOnUse" viewBox="0,0,2.7,2.7" width="5.4"> 491 + <polygon fill="#ffffff" points="0,0 0.675,0 0,0.675"/> 492 + <polygon fill="#ffffff" points="0,2.7 2.7,0 2.7,0.675 0.675,2.7"/> 493 + </pattern> 494 + <pattern height="15.4" id="pattern-hatched-bottom-up-white-7.7" patternUnits="userSpaceOnUse" viewBox="0,0,7.7,7.7" width="15.4"> 495 + <polygon fill="#ffffff" points="0,0 1.925,0 0,1.925"/> 496 + <polygon fill="#ffffff" points="0,7.7 7.7,0 7.7,1.925 1.925,7.7"/> 497 + </pattern> 498 + <pattern height="2.4" id="pattern-hatched-bottom-up-white-1.2" patternUnits="userSpaceOnUse" viewBox="0,0,1.2,1.2" width="2.4"> 499 + <polygon fill="#ffffff" points="0,0 0.3,0 0,0.3"/> 500 + <polygon fill="#ffffff" points="0,1.2 1.2,0 1.2,0.3 0.3,1.2"/> 501 + </pattern> 502 + <pattern height="6.6" id="pattern-hatched-bottom-up-white-3.3" patternUnits="userSpaceOnUse" viewBox="0,0,3.3,3.3" width="6.6"> 503 + <polygon fill="#ffffff" points="0,0 0.825,0 0,0.825"/> 504 + <polygon fill="#ffffff" points="0,3.3 3.3,0 3.3,0.825 0.825,3.3"/> 505 + </pattern> 506 + <pattern height="17" id="pattern-hatched-bottom-up-white-8.5" patternUnits="userSpaceOnUse" viewBox="0,0,8.5,8.5" width="17"> 507 + <polygon fill="#ffffff" points="0,0 2.125,0 0,2.125"/> 508 + <polygon fill="#ffffff" points="0,8.5 8.5,0 8.5,2.125 2.125,8.5"/> 509 + </pattern> 510 + <pattern height="12.6" id="pattern-hatched-bottom-up-white-6.3" patternUnits="userSpaceOnUse" viewBox="0,0,6.3,6.3" width="12.6"> 511 + <polygon fill="#ffffff" points="0,0 1.575,0 0,1.575"/> 512 + <polygon fill="#ffffff" points="0,6.3 6.3,0 6.3,1.575 1.575,6.3"/> 513 + </pattern> 514 + <pattern height="14.4" id="pattern-hatched-bottom-up-white-7.2" patternUnits="userSpaceOnUse" viewBox="0,0,7.2,7.2" width="14.4"> 515 + <polygon fill="#ffffff" points="0,0 1.8,0 0,1.8"/> 516 + <polygon fill="#ffffff" points="0,7.2 7.2,0 7.2,1.8 1.8,7.2"/> 517 + </pattern> 518 + <pattern height="5" id="pattern-hatched-bottom-up-white-2.5" patternUnits="userSpaceOnUse" viewBox="0,0,2.5,2.5" width="5"> 519 + <polygon fill="#ffffff" points="0,0 0.625,0 0,0.625"/> 520 + <polygon fill="#ffffff" points="0,2.5 2.5,0 2.5,0.625 0.625,2.5"/> 521 + </pattern> 522 + <pattern height="9.6" id="pattern-hatched-bottom-up-white-4.8" patternUnits="userSpaceOnUse" viewBox="0,0,4.8,4.8" width="9.6"> 523 + <polygon fill="#ffffff" points="0,0 1.2,0 0,1.2"/> 524 + <polygon fill="#ffffff" points="0,4.8 4.8,0 4.8,1.2 1.2,4.8"/> 525 + </pattern> 526 + <pattern height="17.4" id="pattern-hatched-bottom-up-white-8.7" patternUnits="userSpaceOnUse" viewBox="0,0,8.7,8.7" width="17.4"> 527 + <polygon fill="#ffffff" points="0,0 2.175,0 0,2.175"/> 528 + <polygon fill="#ffffff" points="0,8.7 8.7,0 8.7,2.175 2.175,8.7"/> 529 + </pattern> 530 + <pattern height="9.4" id="pattern-hatched-bottom-up-white-4.7" patternUnits="userSpaceOnUse" viewBox="0,0,4.7,4.7" width="9.4"> 531 + <polygon fill="#ffffff" points="0,0 1.175,0 0,1.175"/> 532 + <polygon fill="#ffffff" points="0,4.7 4.7,0 4.7,1.175 1.175,4.7"/> 533 + </pattern> 534 + <pattern height="0.4" id="pattern-hatched-bottom-up-white-0.2" patternUnits="userSpaceOnUse" viewBox="0,0,0.2,0.2" width="0.4"> 535 + <polygon fill="#ffffff" points="0,0 0.05,0 0,0.05"/> 536 + <polygon fill="#ffffff" points="0,0.2 0.2,0 0.2,0.05 0.05,0.2"/> 537 + </pattern> 538 + <pattern height="2.2" id="pattern-hatched-bottom-up-white-1.1" patternUnits="userSpaceOnUse" viewBox="0,0,1.1,1.1" width="2.2"> 539 + <polygon fill="#ffffff" points="0,0 0.275,0 0,0.275"/> 540 + <polygon fill="#ffffff" points="0,1.1 1.1,0 1.1,0.275 0.275,1.1"/> 541 + </pattern> 542 + <pattern height="4.8" id="pattern-hatched-bottom-up-white-2.4" patternUnits="userSpaceOnUse" viewBox="0,0,2.4,2.4" width="4.8"> 543 + <polygon fill="#ffffff" points="0,0 0.6,0 0,0.6"/> 544 + <polygon fill="#ffffff" points="0,2.4 2.4,0 2.4,0.6 0.6,2.4"/> 545 + </pattern> 546 + <pattern height="7" id="pattern-hatched-bottom-up-white-3.5" patternUnits="userSpaceOnUse" viewBox="0,0,3.5,3.5" width="7"> 547 + <polygon fill="#ffffff" points="0,0 0.875,0 0,0.875"/> 548 + <polygon fill="#ffffff" points="0,3.5 3.5,0 3.5,0.875 0.875,3.5"/> 549 + </pattern> 550 + <pattern height="10.6" id="pattern-hatched-bottom-up-white-5.3" patternUnits="userSpaceOnUse" viewBox="0,0,5.3,5.3" width="10.6"> 551 + <polygon fill="#ffffff" points="0,0 1.325,0 0,1.325"/> 552 + <polygon fill="#ffffff" points="0,5.3 5.3,0 5.3,1.325 1.325,5.3"/> 553 + </pattern> 554 + <pattern height="10.4" id="pattern-hatched-bottom-up-white-5.2" patternUnits="userSpaceOnUse" viewBox="0,0,5.2,5.2" width="10.4"> 555 + <polygon fill="#ffffff" points="0,0 1.3,0 0,1.3"/> 556 + <polygon fill="#ffffff" points="0,5.2 5.2,0 5.2,1.3 1.3,5.2"/> 557 + </pattern> 558 + <pattern height="11.2" id="pattern-hatched-bottom-up-white-5.6" patternUnits="userSpaceOnUse" viewBox="0,0,5.6,5.6" width="11.2"> 559 + <polygon fill="#ffffff" points="0,0 1.4,0 0,1.4"/> 560 + <polygon fill="#ffffff" points="0,5.6 5.6,0 5.6,1.4 1.4,5.6"/> 561 + </pattern> 562 + <pattern height="16.8" id="pattern-hatched-bottom-up-white-8.4" patternUnits="userSpaceOnUse" viewBox="0,0,8.4,8.4" width="16.8"> 563 + <polygon fill="#ffffff" points="0,0 2.1,0 0,2.1"/> 564 + <polygon fill="#ffffff" points="0,8.4 8.4,0 8.4,2.1 2.1,8.4"/> 565 + </pattern> 566 + <pattern height="0.2" id="pattern-hatched-bottom-up-white-0.1" patternUnits="userSpaceOnUse" viewBox="0,0,0.1,0.1" width="0.2"> 567 + <polygon fill="#ffffff" points="0,0 0.025,0 0,0.025"/> 568 + <polygon fill="#ffffff" points="0,0.1 0.1,0 0.1,0.025 0.025,0.1"/> 569 + </pattern> 570 + <pattern height="17.8" id="pattern-hatched-bottom-up-white-8.9" patternUnits="userSpaceOnUse" viewBox="0,0,8.9,8.9" width="17.8"> 571 + <polygon fill="#ffffff" points="0,0 2.225,0 0,2.225"/> 572 + <polygon fill="#ffffff" points="0,8.9 8.9,0 8.9,2.225 2.225,8.9"/> 573 + </pattern> 574 + </defs> 575 + </svg>
+8
src/anchors.rs
··· 1 1 use wasm_bindgen::prelude::wasm_bindgen; 2 2 3 + use crate::Point; 4 + 3 5 #[wasm_bindgen] 4 6 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 5 7 pub struct Anchor(pub i32, pub i32); ··· 89 91 CenterAnchor(-1, -1) 90 92 } 91 93 } 94 + 95 + impl From<Point> for CenterAnchor { 96 + fn from(value: Point) -> Self { 97 + CenterAnchor(value.0 as i32, value.1 as i32) 98 + } 99 + }
+18 -5
src/canvas.rs
··· 8 8 9 9 use crate::{ 10 10 layer::Layer, objects::Object, random_color, web::console_log, Anchor, CenterAnchor, Color, 11 - ColorMapping, ColoredObject, Fill, Filter, HatchDirection, LineSegment, ObjectSizes, Point, 12 - Region, 11 + ColorMapping, ColoredObject, Containable, Fill, Filter, HatchDirection, LineSegment, 12 + ObjectSizes, Point, Region, 13 13 }; 14 14 15 15 #[derive(Debug, Clone)] ··· 197 197 self.random_linelikes_within(layer_name, &self.world_region) 198 198 } 199 199 200 - pub fn random_linelikes_within(&self, layer_name: &str, region: &Region) -> Layer { 200 + pub fn n_random_linelikes_within( 201 + &self, 202 + layer_name: &str, 203 + region: &Region, 204 + count: usize, 205 + ) -> Layer { 201 206 let mut objects: HashMap<String, ColoredObject> = HashMap::new(); 202 - let number_of_objects = rand::thread_rng().gen_range(self.objects_count_range.clone()); 203 - for i in 0..number_of_objects { 207 + for i in 0..count { 204 208 let object = self.random_linelike_within(region); 205 209 let hatchable = object.fillable(); 206 210 objects.insert( ··· 222 226 objects, 223 227 _render_cache: None, 224 228 } 229 + } 230 + 231 + pub fn random_linelikes_within(&self, layer_name: &str, region: &Region) -> Layer { 232 + let number_of_objects = rand::thread_rng().gen_range(self.objects_count_range.clone()); 233 + self.n_random_linelikes_within(layer_name, region, number_of_objects) 225 234 } 226 235 227 236 pub fn random_object_within(&self, region: &Region) -> Object { ··· 424 433 425 434 pub fn height(&self) -> usize { 426 435 self.cell_size * (self.grid_size.1 - 1) + 2 * self.canvas_outter_padding 436 + } 437 + 438 + pub fn aspect_ratio(&self) -> f32 { 439 + return self.height() as f32 / self.width() as f32; 427 440 } 428 441 429 442 /// returns a list of all unique filters used throughout the canvas
+71
src/examples.rs
··· 1 + use rand::Rng; 2 + 3 + use crate::*; 4 + 5 + pub fn dna_analysis_machine() -> Canvas { 6 + let mut canvas = Canvas::new(vec!["root"]); 7 + canvas.set_grid_size(16, 9); 8 + canvas.set_background(Color::Black); 9 + let mut hatches_layer = Layer::new("root"); 10 + 11 + let draw_in = canvas.world_region.resized(-1, -1).enlarged(-2, -2); 12 + let splines_area = 13 + Region::from_bottomleft(canvas.world_region.bottomleft(), (3, 3)).translated(3, -3); 14 + let red_circle_in = Region::from(( 15 + Point(splines_area.topright().0 + 3, draw_in.topright().1), 16 + draw_in.bottomright(), 17 + )); 18 + 19 + println!("splines_area: {:?}", splines_area); 20 + println!("red_circle_in: {:?}", red_circle_in); 21 + 22 + let red_circle_at = red_circle_in.random_point_within(); 23 + 24 + println!("Red circle at {:?}", red_circle_at); 25 + 26 + for (i, point) in draw_in.iter().enumerate() { 27 + if splines_area.contains(&point) { 28 + continue; 29 + } 30 + 31 + if point == red_circle_at { 32 + hatches_layer.add_object( 33 + "redpoint", 34 + Object::BigCircle(point.into()) 35 + .color(Fill::Solid(Color::Red)) 36 + .filter(Filter::glow(5.0)), 37 + ); 38 + continue; 39 + } 40 + 41 + let Point(x, y) = point; 42 + 43 + hatches_layer.add_object( 44 + &format!("{}-{}", x, y), 45 + if rand::thread_rng().gen_bool(0.5) { 46 + Object::BigCircle((x, y).into()) 47 + } else { 48 + // XXX the .translated is a hack, centeranchor needs to disappear 49 + Object::Rectangle((x, y).into(), Anchor::from((x, y)).translated(1, 1)) 50 + } 51 + .color(Fill::Hatched( 52 + Color::White, 53 + HatchDirection::BottomUpDiagonal, 54 + (i + 1) as f32 / 10.0, 55 + 0.25, 56 + )), 57 + ); 58 + } 59 + canvas.layers.push(hatches_layer); 60 + let mut splines = canvas.n_random_linelikes_within("splines", &splines_area, 30); 61 + for (i, ColoredObject(_, ref mut fill, _)) in splines.objects.values_mut().enumerate() { 62 + *fill = Some(Fill::Solid(if i % 2 == 0 { 63 + Color::Cyan 64 + } else { 65 + Color::Pink 66 + })) 67 + } 68 + splines.filter_all_objects(Filter::glow(4.0)); 69 + canvas.layers.push(splines); 70 + canvas 71 + }
+1
src/lib.rs
··· 1 1 mod color; 2 + pub mod examples; 2 3 pub mod cli; 3 4 mod objects; 4 5 pub use color::*;
+10 -54
src/main.rs
··· 13 13 let mut canvas = canvas_from_cli(&args); 14 14 15 15 if args.cmd_image && !args.cmd_video { 16 - let mut layer = Layer::new("root"); 17 - 18 - let red_circle_at = canvas.world_region.enlarged(-1, -1).random_point_within(); 19 - 20 - for (i, Point(x, y)) in canvas 21 - .world_region 22 - .resized(-1, -1) 23 - .enlarged(-2, -2) 24 - .iter() 25 - .enumerate() 26 - { 27 - layer.add_object( 28 - &format!("{}-{}", x, y), 29 - if rand::thread_rng().gen_bool(0.5) && red_circle_at != Point(x, y) { 30 - Object::BigCircle((x, y).into()) 31 - } else { 32 - Object::Rectangle((x, y).into(), Anchor::from((x, y)).translated(1, 1)) 33 - } 34 - .color(if red_circle_at == Point(x, y) { 35 - Fill::Solid(Color::Red) 36 - } else { 37 - Fill::Hatched( 38 - Color::White, 39 - HatchDirection::BottomUpDiagonal, 40 - (i + 1) as f32 / 10.0, 41 - 0.25, 42 - ) 43 - }), 44 - // .filter(Filter::glow(7.0)), 45 - ); 46 - } 47 - canvas.layers.push(layer); 48 - canvas.set_background(Color::Black); 49 - // canvas.layer("root").add_object( 50 - // "feur", 51 - // Object::Rectangle(Anchor(0, 0), Anchor(2, 2)), 52 - // Some(Fill::Hatched( 53 - // Color::Red, 54 - // HatchDirection::BottomUpDiagonal, 55 - // 2.0, 56 - // 0.25, 57 - // )), 58 - // ); 59 - // canvas.layers[0].paint_all_objects(Fill::Hatched( 60 - // Color::Red, 61 - // HatchDirection::BottomUpDiagonal, 62 - // 3.0, 63 - // )); 64 - let aspect_ratio = canvas.grid_size.0 as f32 / canvas.grid_size.1 as f32; 65 - 16 + canvas.root().add_object( 17 + "hello", 18 + Object::Text(Anchor(3, 4), "hello world!".into(), 16.0) 19 + .color(Fill::Solid(Color::Black)), 20 + ); 21 + canvas.set_background(Color::White); 66 22 let rendered = canvas.render(&vec!["*"], true); 67 23 if args.arg_file.ends_with(".svg") { 68 24 std::fs::write(args.arg_file, rendered).unwrap(); 69 25 } else { 70 26 match Canvas::save_as( 71 27 &args.arg_file, 72 - aspect_ratio, 28 + canvas.aspect_ratio(), 73 29 args.flag_resolution.unwrap_or(1000), 74 30 rendered, 75 31 ) { ··· 88 44 video = video 89 45 .init(&|canvas: _, context: _| { 90 46 context.extra = State { 91 - bass_pattern_at: Region::from_origin_and_size((6, 3), (3, 3)), 47 + bass_pattern_at: Region::from_topleft(Point(6, 3), (3, 3)), 92 48 first_kick_happened: false, 93 49 }; 94 50 canvas.set_background(Color::Black); ··· 299 255 let mut region = if let Some(current) = current { 300 256 current.clone() 301 257 } else { 302 - Region::from_origin_and_size((1, 1), (2, 2)) 258 + Region::from_topleft(Point(1, 1), (2, 2)) 303 259 }; 304 260 305 261 let size = (region.width(), region.height()); ··· 313 269 } 314 270 // Else go to origin 315 271 else { 316 - region = Region::from_origin_and_size((1, 1), size) 272 + region = Region::from_topleft(Point(1, 1), size) 317 273 } 318 274 region 319 275 }
+98 -13
src/region.rs
··· 7 7 #[derive(Debug, Clone, Copy, Default, PartialEq)] 8 8 pub struct Point(pub usize, pub usize); 9 9 10 + impl Point { 11 + pub fn translated(&self, dx: i32, dy: i32) -> Self { 12 + Self((self.0 as i32 + dx) as usize, (self.1 as i32 + dy) as usize) 13 + } 14 + } 15 + 10 16 impl From<(usize, usize)> for Point { 11 17 fn from(value: (usize, usize)) -> Self { 12 18 Self(value.0, value.1) ··· 40 46 pub fn random_point_within(&self) -> Point { 41 47 Point::from(self.random_coordinates_within()) 42 48 } 49 + 50 + pub fn random_point_within_except(&self, except: &Region) -> Point { 51 + // XXX this is probably not a good idea lmao 52 + loop { 53 + let point = self.random_point_within(); 54 + if !except.contains(&point) { 55 + return point; 56 + } 57 + } 58 + } 43 59 } 44 60 45 61 pub struct RegionIterator { ··· 73 89 } 74 90 } 75 91 92 + impl From<(&Point, &Point)> for Region { 93 + fn from(value: (&Point, &Point)) -> Self { 94 + Self { 95 + start: value.0.clone(), 96 + end: value.1.clone(), 97 + } 98 + } 99 + } 100 + 101 + impl From<(Point, Point)> for Region { 102 + fn from(value: (Point, Point)) -> Self { 103 + Self { 104 + start: value.0, 105 + end: value.1, 106 + } 107 + } 108 + } 109 + 76 110 impl From<((usize, usize), (usize, usize))> for Region { 77 111 fn from(value: ((usize, usize), (usize, usize))) -> Self { 78 112 Region { ··· 113 147 114 148 #[test] 115 149 fn test_sub_and_transate_coherence() { 116 - let a = Region::from_origin((3, 3)); 150 + let a = Region::from_origin(Point(3, 3)); 117 151 let mut b = a.clone(); 118 152 b.translate(2, 3); 119 153 ··· 130 164 region 131 165 } 132 166 167 + pub fn bottomleft(&self) -> Point { 168 + Point(self.start.0, self.end.1) 169 + } 170 + 171 + pub fn bottomright(&self) -> Point { 172 + Point(self.end.0, self.end.1) 173 + } 174 + 175 + pub fn topleft(&self) -> Point { 176 + Point(self.start.0, self.start.1) 177 + } 178 + 179 + pub fn topright(&self) -> Point { 180 + Point(self.end.0, self.start.1) 181 + } 182 + 133 183 pub fn max<'a>(&'a self, other: &'a Region) -> &'a Region { 134 184 if self.within(other) { 135 185 other ··· 145 195 ) 146 196 } 147 197 148 - pub fn from_origin(end: (usize, usize)) -> Self { 198 + pub fn from_origin(end: Point) -> Self { 149 199 Self::new(0, 0, end.0, end.1) 150 200 } 151 201 152 - pub fn from_origin_and_size(origin: (usize, usize), size: (usize, usize)) -> Self { 202 + pub fn from_topleft(origin: Point, size: (usize, usize)) -> Self { 153 203 Self::new( 154 204 origin.0, 155 205 origin.1, ··· 158 208 ) 159 209 } 160 210 161 - pub fn from_center_and_size(center: (usize, usize), size: (usize, usize)) -> Self { 211 + pub fn from_bottomleft(origin: Point, size: (usize, usize)) -> Self { 212 + Self::new(origin.0, origin.1 - size.1, origin.0 + size.0, origin.1) 213 + } 214 + 215 + pub fn from_bottomright(origin: Point, size: (usize, usize)) -> Self { 216 + Self::new( 217 + origin.0 - size.0, 218 + origin.1 - size.1, 219 + origin.0 + 1, 220 + origin.1 + 1, 221 + ) 222 + } 223 + 224 + pub fn from_topright(origin: Point, size: (usize, usize)) -> Self { 225 + Self::new( 226 + origin.0 - size.0, 227 + origin.1, 228 + origin.0 + 1, 229 + origin.1 + size.1 + 1, 230 + ) 231 + } 232 + 233 + pub fn from_center_and_size(center: Point, size: (usize, usize)) -> Self { 162 234 let half_size = (size.0 / 2, size.1 / 2); 163 235 Self::new( 164 236 center.0 - half_size.0, ··· 217 289 self.translated(-dx, -dy).enlarged(dx, dy) 218 290 } 219 291 220 - pub fn x_range(&self) -> std::ops::Range<usize> { 221 - self.start.0..self.end.0 292 + pub fn x_range(&self) -> std::ops::RangeInclusive<usize> { 293 + self.start.0..=self.end.0 222 294 } 223 - pub fn y_range(&self) -> std::ops::Range<usize> { 224 - self.start.1..self.end.1 295 + pub fn y_range(&self) -> std::ops::RangeInclusive<usize> { 296 + self.start.1..=self.end.1 225 297 } 226 298 227 299 pub fn x_range_without_last(&self) -> std::ops::Range<usize> { 228 - self.start.0..self.end.0 - 1 300 + self.start.0..self.end.0 229 301 } 230 302 231 303 pub fn y_range_without_last(&self) -> std::ops::Range<usize> { 232 - self.start.1..self.end.1 - 1 304 + self.start.1..self.end.1 233 305 } 234 306 235 307 pub fn within(&self, other: &Region) -> bool { ··· 268 340 let h = self.height() as i32; 269 341 -h..=h 270 342 } 343 + } 271 344 272 - pub fn contains(&self, anchor: &Anchor) -> bool { 273 - self.x_range().contains(&(anchor.0 as usize)) 274 - && self.y_range().contains(&(anchor.1 as usize)) 345 + pub trait Containable<T> { 346 + fn contains(&self, value: &T) -> bool; 347 + } 348 + 349 + impl Containable<Point> for Region { 350 + fn contains(&self, value: &Point) -> bool { 351 + self.x_range_without_last().contains(&value.0) 352 + && self.y_range_without_last().contains(&value.1) 353 + } 354 + } 355 + 356 + impl Containable<Anchor> for Region { 357 + fn contains(&self, anchor: &Anchor) -> bool { 358 + self.x_range_without_last().contains(&(anchor.0 as usize)) 359 + && self.y_range_without_last().contains(&(anchor.1 as usize)) 275 360 } 276 361 }
+2 -35
src/web.rs
··· 7 7 use wasm_bindgen::{JsValue, UnwrapThrowExt}; 8 8 9 9 use crate::{ 10 - layer, Anchor, Canvas, CenterAnchor, Color, ColorMapping, Fill, Filter, FilterType, 10 + examples, layer, Anchor, Canvas, CenterAnchor, Color, ColorMapping, Fill, Filter, FilterType, 11 11 HatchDirection, Layer, Object, Point, 12 12 }; 13 13 ··· 43 43 44 44 #[wasm_bindgen] 45 45 pub fn render_image(opacity: f32, color: Color) -> Result<(), JsValue> { 46 - let mut canvas = Canvas::default_settings(); 46 + let mut canvas = examples::dna_analysis_machine(); 47 47 canvas.colormap = ColorMapping { 48 48 black: "#ffffff".into(), 49 49 white: "#ffffff".into(), ··· 58 58 gray: "#81a0a8".into(), 59 59 cyan: "#4fecec".into(), 60 60 }; 61 - canvas.set_grid_size(16, 9); 62 61 63 - let mut layer = Layer::new("root"); 64 - 65 - let draw_in = canvas.world_region.resized(-1, -1).enlarged(-2, -2); 66 - let red_circle_at = draw_in.random_point_within(); 67 - 68 - console_log!("Red circle at {:?}", red_circle_at); 69 - 70 - for (i, Point(x, y)) in draw_in.iter().enumerate() { 71 - console_log!("Adding object at ({}, {})", x, y); 72 - layer.add_object( 73 - &format!("{}-{}", x, y), 74 - if rand::thread_rng().gen_bool(0.5) && red_circle_at != Point(x, y) { 75 - Object::BigCircle((x, y).into()) 76 - } else { 77 - Object::Rectangle((x, y).into(), Anchor::from((x, y)).translated(1, 1)) 78 - } 79 - .color(if red_circle_at == Point(x, y) { 80 - Fill::Solid(Color::Red) 81 - } else { 82 - Fill::Hatched( 83 - Color::White, 84 - HatchDirection::BottomUpDiagonal, 85 - (i + 1) as f32 / 10.0, 86 - 0.25, 87 - ) 88 - }), 89 - // .filter(Filter::glow(7.0)), 90 - ); 91 - } 92 - console_log!("Registering layer"); 93 - canvas.layers.push(layer); 94 - canvas.set_background(Color::Black); 95 62 *WEB_CANVAS.lock().unwrap() = canvas; 96 63 render_canvas_at(String::from("body")); 97 64