├── .github ├── FUNDING.yml └── workflows │ └── pages.yml ├── .gitignore ├── LICENSE ├── README.md ├── codepen ├── index.html ├── main.acdee0f23b41d0dbded7.css └── main.acdee0f23b41d0dbded7.js ├── package.json ├── screenshot.png └── src ├── app.svelte ├── basic.css ├── components ├── about.svelte ├── back.svelte ├── collection.svelte ├── color.svelte ├── doodle.svelte ├── editor.svelte ├── graph.svelte ├── nav.svelte ├── popup.svelte ├── theme-switcher.svelte └── toggler.svelte ├── index.html ├── index.js ├── shapes.js └── theme.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: css-doodle 2 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy GitHub Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | jobs: 19 | # Single deploy job since we're just deploying 20 | deploy: 21 | environment: 22 | name: github-pages 23 | url: ${{ steps.deployment.outputs.page_url }} 24 | 25 | runs-on: ubuntu-latest 26 | 27 | strategy: 28 | matrix: 29 | os: [ubuntu-latest] 30 | node-version: [19.x] 31 | 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v3 35 | - name: Setup Pages 36 | uses: actions/configure-pages@v2 37 | - name: Use Node.js ${{ matrix.node-version }} 38 | uses: actions/setup-node@v2 39 | with: 40 | node-version: ${{ matrix.node-version }} 41 | - run: yarn install 42 | - run: yarn build 43 | - name: Upload artifact 44 | uses: actions/upload-pages-artifact@v1 45 | with: 46 | # Upload entire repository 47 | path: './dist' 48 | - name: Deploy to GitHub Pages 49 | id: deployment 50 | uses: actions/deploy-pages@v1 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | temp.* 4 | package-lock.json 5 | .cache 6 | dist 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2023 Yuan Chuan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shapes 2 | 3 | A tool for discovering new CSS polygon shapes generated 4 | with [css-doodle](https://css-doodle.com) `@shape()` function and mathematical expressions. Read more about its usage: [https://yuanchuan.dev/polygon-shapes](https://yuanchuan.dev/polygon-shapes). 5 | 6 |
7 | 8 | screenshot of interface 9 |
10 | 11 | ### Commands 12 | * `fill`: nonzero | evenodd; 13 | * `frame`: number for frame size; 14 | * `points`: number between 3 - 3600; 15 | * `rotate`: number in degree for rotation; 16 | * `scale`: number for scale factor; 17 | * `move`: a pair of value for translating x, y coords; 18 | * `turn`: angle between start/end point, defaults to be 1; 19 | * `x`: x coordinate for cartesian equation; 20 | * `y`: y coordinate for cartesian equation; 21 | * `r`: polar equation; 22 | 23 | 24 | ### Operations 25 | 26 | * Operations available: `+`, `-`, `*`, `/`, `%`, `^`, `|`, `&`, `>>`, `<<`. 27 | * All JavaScript Math functions and constants can be used. Such as `sin`, `cos`, `tan`, `PI` or `π` etc. 28 | 29 | ### Variables 30 | 31 | Everything declared is considered a variable. 32 | 33 | 34 | ### Website 35 | 36 | [https://css-doodle.com/shapes](https://css-doodle.com/shapes) 37 | -------------------------------------------------------------------------------- /codepen/index.html: -------------------------------------------------------------------------------- 1 | Discover CSS polygon shapes
-------------------------------------------------------------------------------- /codepen/main.acdee0f23b41d0dbded7.css: -------------------------------------------------------------------------------- 1 | *, *::after, *::before { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | --color-link-active: rgba(255, 87, 34, .08); 9 | --color-toggle-bg-active: rgba(255, 87, 34, .08); 10 | --color-toggle-bg: rgba(var(--color-rgb), .1); 11 | --color-editor-bg: #ffffff; 12 | color: #4B4E68; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-overflow-scrolling: touch; 15 | text-rendering: optimizeLegibility; 16 | font-family: /* songti */ Georgia, "Nimbus Roman No9 L", "Songti SC", STSong, "AR PL New Sung", "AR PL SungtiL GB", NSimSun, SimSun, "TW\-Sung", "WenQuanYi Bitmap Song", "AR PL UMing CN", "AR PL UMing HK", "AR PL UMing TW", "AR PL UMing TW MBE", PMingLiU, MingLiU, serif; 17 | background: #f1f3f4; 18 | padding: 8em 5em 8em; 19 | } 20 | 21 | @media screen and (max-width: 42.375em) { 22 | body { 23 | padding: 5em; 24 | } 25 | } 26 | 27 | @media screen and (max-width: 32em) { 28 | body { 29 | padding: 4em 2em; 30 | } 31 | } 32 | 33 | .CodeMirror-code, 34 | .CodeMirror-cursors { 35 | -webkit-filter: invert(1); 36 | filter: invert(1); 37 | } 38 | .CodeMirror-selected { 39 | opacity: .1; 40 | } 41 | 42 | button[reset] { 43 | background: none; 44 | border: 0; 45 | border-radius: 0; 46 | padding: 0; 47 | margin: 0; 48 | cursor: pointer; 49 | line-height: 1; 50 | -webkit-touch-callout: none; 51 | touch-action: none; 52 | } 53 | 54 | button:focus:not(:focus-visible) { 55 | outline: 0; 56 | } 57 | 58 | css-doodle.svelte-wzvjch{width:100%;height:100%;background:#fff;--basic:( 59 | background: #272938; 60 | transition: .2s ease; 61 | )}@media screen and (max-width: 42.375em){css-doodle.svelte-wzvjch{width:9em;height:9em;margin:auto}} 62 | /* BASICS */ 63 | 64 | .CodeMirror { 65 | /* Set height, width, borders, and global font properties here */ 66 | font-family: monospace; 67 | height: 300px; 68 | color: black; 69 | direction: ltr; 70 | } 71 | 72 | /* PADDING */ 73 | 74 | .CodeMirror-lines { 75 | padding: 4px 0; /* Vertical padding around content */ 76 | } 77 | .CodeMirror pre.CodeMirror-line, 78 | .CodeMirror pre.CodeMirror-line-like { 79 | padding: 0 4px; /* Horizontal padding of content */ 80 | } 81 | 82 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 83 | background-color: transparent; /* The little square between H and V scrollbars */ 84 | } 85 | 86 | /* GUTTER */ 87 | 88 | .CodeMirror-gutters { 89 | border-right: 1px solid #ddd; 90 | background-color: #f7f7f7; 91 | white-space: nowrap; 92 | } 93 | .CodeMirror-linenumbers {} 94 | .CodeMirror-linenumber { 95 | padding: 0 3px 0 5px; 96 | min-width: 20px; 97 | text-align: right; 98 | color: #999; 99 | white-space: nowrap; 100 | } 101 | 102 | .CodeMirror-guttermarker { color: black; } 103 | .CodeMirror-guttermarker-subtle { color: #999; } 104 | 105 | /* CURSOR */ 106 | 107 | .CodeMirror-cursor { 108 | border-left: 1px solid black; 109 | border-right: none; 110 | width: 0; 111 | } 112 | /* Shown when moving in bi-directional text */ 113 | .CodeMirror div.CodeMirror-secondarycursor { 114 | border-left: 1px solid silver; 115 | } 116 | .cm-fat-cursor .CodeMirror-cursor { 117 | width: auto; 118 | border: 0 !important; 119 | background: #7e7; 120 | } 121 | .cm-fat-cursor div.CodeMirror-cursors { 122 | z-index: 1; 123 | } 124 | .cm-fat-cursor-mark { 125 | background-color: rgba(20, 255, 20, 0.5); 126 | -webkit-animation: blink 1.06s steps(1) infinite; 127 | -moz-animation: blink 1.06s steps(1) infinite; 128 | animation: blink 1.06s steps(1) infinite; 129 | } 130 | .cm-animate-fat-cursor { 131 | width: auto; 132 | border: 0; 133 | -webkit-animation: blink 1.06s steps(1) infinite; 134 | -moz-animation: blink 1.06s steps(1) infinite; 135 | animation: blink 1.06s steps(1) infinite; 136 | background-color: #7e7; 137 | } 138 | @-moz-keyframes blink { 139 | 0% {} 140 | 50% { background-color: transparent; } 141 | 100% {} 142 | } 143 | @-webkit-keyframes blink { 144 | 0% {} 145 | 50% { background-color: transparent; } 146 | 100% {} 147 | } 148 | @keyframes blink { 149 | 0% {} 150 | 50% { background-color: transparent; } 151 | 100% {} 152 | } 153 | 154 | /* Can style cursor different in overwrite (non-insert) mode */ 155 | .CodeMirror-overwrite .CodeMirror-cursor {} 156 | 157 | .cm-tab { display: inline-block; text-decoration: inherit; } 158 | 159 | .CodeMirror-rulers { 160 | position: absolute; 161 | left: 0; right: 0; top: -50px; bottom: 0; 162 | overflow: hidden; 163 | } 164 | .CodeMirror-ruler { 165 | border-left: 1px solid #ccc; 166 | top: 0; bottom: 0; 167 | position: absolute; 168 | } 169 | 170 | /* DEFAULT THEME */ 171 | 172 | .cm-s-default .cm-header {color: blue;} 173 | .cm-s-default .cm-quote {color: #090;} 174 | .cm-negative {color: #d44;} 175 | .cm-positive {color: #292;} 176 | .cm-header, .cm-strong {font-weight: bold;} 177 | .cm-em {font-style: italic;} 178 | .cm-link {text-decoration: underline;} 179 | .cm-strikethrough {text-decoration: line-through;} 180 | 181 | .cm-s-default .cm-keyword {color: #708;} 182 | .cm-s-default .cm-atom {color: #219;} 183 | .cm-s-default .cm-number {color: #164;} 184 | .cm-s-default .cm-def {color: #00f;} 185 | .cm-s-default .cm-variable, 186 | .cm-s-default .cm-punctuation, 187 | .cm-s-default .cm-property, 188 | .cm-s-default .cm-operator {} 189 | .cm-s-default .cm-variable-2 {color: #05a;} 190 | .cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;} 191 | .cm-s-default .cm-comment {color: #a50;} 192 | .cm-s-default .cm-string {color: #a11;} 193 | .cm-s-default .cm-string-2 {color: #f50;} 194 | .cm-s-default .cm-meta {color: #555;} 195 | .cm-s-default .cm-qualifier {color: #555;} 196 | .cm-s-default .cm-builtin {color: #30a;} 197 | .cm-s-default .cm-bracket {color: #997;} 198 | .cm-s-default .cm-tag {color: #170;} 199 | .cm-s-default .cm-attribute {color: #00c;} 200 | .cm-s-default .cm-hr {color: #999;} 201 | .cm-s-default .cm-link {color: #00c;} 202 | 203 | .cm-s-default .cm-error {color: #f00;} 204 | .cm-invalidchar {color: #f00;} 205 | 206 | .CodeMirror-composing { border-bottom: 2px solid; } 207 | 208 | /* Default styles for common addons */ 209 | 210 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;} 211 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;} 212 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } 213 | .CodeMirror-activeline-background {background: #e8f2ff;} 214 | 215 | /* STOP */ 216 | 217 | /* The rest of this file contains styles related to the mechanics of 218 | the editor. You probably shouldn't touch them. */ 219 | 220 | .CodeMirror { 221 | position: relative; 222 | overflow: hidden; 223 | background: white; 224 | } 225 | 226 | .CodeMirror-scroll { 227 | overflow: scroll !important; /* Things will break if this is overridden */ 228 | /* 50px is the magic margin used to hide the element's real scrollbars */ 229 | /* See overflow: hidden in .CodeMirror */ 230 | margin-bottom: -50px; margin-right: -50px; 231 | padding-bottom: 50px; 232 | height: 100%; 233 | outline: none; /* Prevent dragging from highlighting the element */ 234 | position: relative; 235 | } 236 | .CodeMirror-sizer { 237 | position: relative; 238 | border-right: 50px solid transparent; 239 | } 240 | 241 | /* The fake, visible scrollbars. Used to force redraw during scrolling 242 | before actual scrolling happens, thus preventing shaking and 243 | flickering artifacts. */ 244 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 245 | position: absolute; 246 | z-index: 6; 247 | display: none; 248 | outline: none; 249 | } 250 | .CodeMirror-vscrollbar { 251 | right: 0; top: 0; 252 | overflow-x: hidden; 253 | overflow-y: scroll; 254 | } 255 | .CodeMirror-hscrollbar { 256 | bottom: 0; left: 0; 257 | overflow-y: hidden; 258 | overflow-x: scroll; 259 | } 260 | .CodeMirror-scrollbar-filler { 261 | right: 0; bottom: 0; 262 | } 263 | .CodeMirror-gutter-filler { 264 | left: 0; bottom: 0; 265 | } 266 | 267 | .CodeMirror-gutters { 268 | position: absolute; left: 0; top: 0; 269 | min-height: 100%; 270 | z-index: 3; 271 | } 272 | .CodeMirror-gutter { 273 | white-space: normal; 274 | height: 100%; 275 | display: inline-block; 276 | vertical-align: top; 277 | margin-bottom: -50px; 278 | } 279 | .CodeMirror-gutter-wrapper { 280 | position: absolute; 281 | z-index: 4; 282 | background: none !important; 283 | border: none !important; 284 | } 285 | .CodeMirror-gutter-background { 286 | position: absolute; 287 | top: 0; bottom: 0; 288 | z-index: 4; 289 | } 290 | .CodeMirror-gutter-elt { 291 | position: absolute; 292 | cursor: default; 293 | z-index: 4; 294 | } 295 | .CodeMirror-gutter-wrapper ::selection { background-color: transparent } 296 | .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent } 297 | 298 | .CodeMirror-lines { 299 | cursor: text; 300 | min-height: 1px; /* prevents collapsing before first draw */ 301 | } 302 | .CodeMirror pre.CodeMirror-line, 303 | .CodeMirror pre.CodeMirror-line-like { 304 | /* Reset some styles that the rest of the page might have set */ 305 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; 306 | border-width: 0; 307 | background: transparent; 308 | font-family: inherit; 309 | font-size: inherit; 310 | margin: 0; 311 | white-space: pre; 312 | word-wrap: normal; 313 | line-height: inherit; 314 | color: inherit; 315 | z-index: 2; 316 | position: relative; 317 | overflow: visible; 318 | -webkit-tap-highlight-color: transparent; 319 | -webkit-font-variant-ligatures: contextual; 320 | font-variant-ligatures: contextual; 321 | } 322 | .CodeMirror-wrap pre.CodeMirror-line, 323 | .CodeMirror-wrap pre.CodeMirror-line-like { 324 | word-wrap: break-word; 325 | white-space: pre-wrap; 326 | word-break: normal; 327 | } 328 | 329 | .CodeMirror-linebackground { 330 | position: absolute; 331 | left: 0; right: 0; top: 0; bottom: 0; 332 | z-index: 0; 333 | } 334 | 335 | .CodeMirror-linewidget { 336 | position: relative; 337 | z-index: 2; 338 | padding: 0.1px; /* Force widget margins to stay inside of the container */ 339 | } 340 | 341 | .CodeMirror-widget {} 342 | 343 | .CodeMirror-rtl pre { direction: rtl; } 344 | 345 | .CodeMirror-code { 346 | outline: none; 347 | } 348 | 349 | /* Force content-box sizing for the elements where we expect it */ 350 | .CodeMirror-scroll, 351 | .CodeMirror-sizer, 352 | .CodeMirror-gutter, 353 | .CodeMirror-gutters, 354 | .CodeMirror-linenumber { 355 | -moz-box-sizing: content-box; 356 | box-sizing: content-box; 357 | } 358 | 359 | .CodeMirror-measure { 360 | position: absolute; 361 | width: 100%; 362 | height: 0; 363 | overflow: hidden; 364 | visibility: hidden; 365 | } 366 | 367 | .CodeMirror-cursor { 368 | position: absolute; 369 | pointer-events: none; 370 | } 371 | .CodeMirror-measure pre { position: static; } 372 | 373 | div.CodeMirror-cursors { 374 | visibility: hidden; 375 | position: relative; 376 | z-index: 3; 377 | } 378 | div.CodeMirror-dragcursors { 379 | visibility: visible; 380 | } 381 | 382 | .CodeMirror-focused div.CodeMirror-cursors { 383 | visibility: visible; 384 | } 385 | 386 | .CodeMirror-selected { background: #d9d9d9; } 387 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } 388 | .CodeMirror-crosshair { cursor: crosshair; } 389 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } 390 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } 391 | 392 | .cm-searching { 393 | background-color: #ffa; 394 | background-color: rgba(255, 255, 0, .4); 395 | } 396 | 397 | /* Used to force a border model for a node */ 398 | .cm-force-border { padding-right: .1px; } 399 | 400 | @media print { 401 | /* Hide the cursor when printing */ 402 | .CodeMirror div.CodeMirror-cursors { 403 | visibility: hidden; 404 | } 405 | } 406 | 407 | /* See issue #2901 */ 408 | .cm-tab-wrap-hack:after { content: ''; } 409 | 410 | /* Help users use markselection to safely style text background */ 411 | span.CodeMirror-selectedtext { background: none; } 412 | 413 | /* Based on Sublime Text's Monokai theme */ 414 | 415 | .cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } 416 | .cm-s-monokai div.CodeMirror-selected { background: #49483E; } 417 | .cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } 418 | .cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } 419 | .cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } 420 | .cm-s-monokai .CodeMirror-guttermarker { color: white; } 421 | .cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 422 | .cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } 423 | .cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 424 | 425 | .cm-s-monokai span.cm-comment { color: #75715e; } 426 | .cm-s-monokai span.cm-atom { color: #ae81ff; } 427 | .cm-s-monokai span.cm-number { color: #ae81ff; } 428 | 429 | .cm-s-monokai span.cm-comment.cm-attribute { color: #97b757; } 430 | .cm-s-monokai span.cm-comment.cm-def { color: #bc9262; } 431 | .cm-s-monokai span.cm-comment.cm-tag { color: #bc6283; } 432 | .cm-s-monokai span.cm-comment.cm-type { color: #5998a6; } 433 | 434 | .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; } 435 | .cm-s-monokai span.cm-keyword { color: #f92672; } 436 | .cm-s-monokai span.cm-builtin { color: #66d9ef; } 437 | .cm-s-monokai span.cm-string { color: #e6db74; } 438 | 439 | .cm-s-monokai span.cm-variable { color: #f8f8f2; } 440 | .cm-s-monokai span.cm-variable-2 { color: #9effff; } 441 | .cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; } 442 | .cm-s-monokai span.cm-def { color: #fd971f; } 443 | .cm-s-monokai span.cm-bracket { color: #f8f8f2; } 444 | .cm-s-monokai span.cm-tag { color: #f92672; } 445 | .cm-s-monokai span.cm-header { color: #ae81ff; } 446 | .cm-s-monokai span.cm-link { color: #ae81ff; } 447 | .cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } 448 | 449 | .cm-s-monokai .CodeMirror-activeline-background { background: #373831; } 450 | .cm-s-monokai .CodeMirror-matchingbracket { 451 | text-decoration: underline; 452 | color: white !important; 453 | } 454 | 455 | .toggler.svelte-mcta0o.svelte-mcta0o{position:absolute;right:0;top:0;color:rgba(0, 0, 0, .5);padding:6px 6px;border-radius:0 5px;display:flex;align-items:center;cursor:pointer;transition:.2s ease;user-select:none;background:rgba(39, 41, 56, .06)}.toggler.svelte-mcta0o.svelte-mcta0o:hover{background:rgba(255, 235, 59, .8);color:var(--color-main)}.active.svelte-mcta0o.svelte-mcta0o{background:rgba(255, 235, 59, .8);color:var(--color-main)}.toggler.svelte-mcta0o svg.svelte-mcta0o{display:inline-block;width:1em;height:1em;margin-left:5px}.toggler.svelte-mcta0o span.svelte-mcta0o{text-transform:uppercase} 456 | .container.svelte-xek6jn{width:100%;height:100%;position:relative}.flat.svelte-xek6jn{box-shadow:none}.CodeMirror{padding:1em 1.5em 1em 2em;line-height:1.6;font-size:1em;font-family:'PT Mono', monospace, serif;height:auto}.CodeMirror-scroll{min-height:160px}.cm-s-monokai span.cm-tag{color:#a6e22e}.cm-s-monokai.CodeMirror{background:radial-gradient(circle at 50% 50%, #fff 80%, #f0f2f3)}.toggler.svelte-xek6jn{position:absolute;top:0;right:0;z-index:2}@media screen and (max-width: 42.375em){.cm-s-monokai.CodeMirror{background:#fff}.CodeMirror{padding:1.5em 1.5em 1.5em 2em}}@media screen and (max-width: 26.25em){.CodeMirror{font-size:1em}} 457 | main.svelte-6t1wp9.svelte-6t1wp9{max-width:40em;margin:auto}h1.svelte-6t1wp9.svelte-6t1wp9{font-size:3.2em;color:#4B4E68;margin-bottom:0}header.svelte-6t1wp9.svelte-6t1wp9{margin-bottom:5em}header.svelte-6t1wp9 p.svelte-6t1wp9{margin-top:.5em;font-size:1.4em;color:rgba(75, 78, 104, 0.6196078431372549) 458 | }.list.svelte-6t1wp9.svelte-6t1wp9{list-style:none;margin:0;padding:0}.list.svelte-6t1wp9 li.svelte-6t1wp9{display:flex;margin-bottom:2em}.source.svelte-6t1wp9.svelte-6t1wp9{flex:1;overflow:auto;height:100%;border-radius:5px;box-shadow:20px 5px 20px -15px rgba(0, 0, 0, .03)}.preview.svelte-6t1wp9.svelte-6t1wp9{padding:2em;width:12em;height:12em;align-self:flex-start;background:#fff}a.svelte-6t1wp9.svelte-6t1wp9{color:#4B4E68}a.svelte-6t1wp9.svelte-6t1wp9:hover{background:#4B4E68;color:#fff 459 | }@media screen and (max-width: 42.375em){header.svelte-6t1wp9.svelte-6t1wp9{font-size:.8em}header.svelte-6t1wp9 p.svelte-6t1wp9{margin-top:1em}.preview.svelte-6t1wp9.svelte-6t1wp9{width:100%;border-bottom:1px dashed #eee;padding:2em 0;height:209px;border-radius:5px 5px 0 0 ;background:radial-gradient(circle at 50% 64%, #fff 80%, #f1f2f3)}.source.svelte-6t1wp9.svelte-6t1wp9{box-shadow:0 5px 10px rgba(0, 0, 0, .05);border-radius:0 0 5px 5px}.list.svelte-6t1wp9 li.svelte-6t1wp9{flex-direction:column}} 460 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@css-doodle/shapes", 3 | "version": "1.0.0", 4 | "description": "Discover CSS polygon shapes with css-doodle", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "dev": "parcel src/index.html", 8 | "build": "parcel build src/index.html --no-source-maps --public-url .", 9 | "prebuild": "rm -rf dist/*" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/css-doodle/shapes.git" 14 | }, 15 | "author": "", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/css-doodle/shapes/issues" 19 | }, 20 | "homepage": "https://github.com/css-doodle/shapes#readme", 21 | "devDependencies": { 22 | "parcel-bundler": "^1.12.5", 23 | "parcel-plugin-svelte": "^4.0.9", 24 | "svelte": "^3.42.4" 25 | }, 26 | "dependencies": { 27 | "codemirror": "^5.59.1", 28 | "css-doodle": "0.34.7", 29 | "lodash": "^4.17.20" 30 | }, 31 | "browserslist": [ 32 | "last 2 version" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/css-doodle/shapes/7f482339edf58c2457897f0a737fa39b81d7f16c/screenshot.png -------------------------------------------------------------------------------- /src/app.svelte: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 | 14 |
15 | 16 |
17 | 23 |
24 | 25 | 28 | 29 |
30 | 31 | 173 | 174 | 222 | -------------------------------------------------------------------------------- /src/basic.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | *:after, *:before { 5 | box-sizing: inherit; 6 | } 7 | 8 | html, body, #app { 9 | margin: 0; 10 | height: 100%; 11 | } 12 | 13 | body { 14 | --color-bg: #060a11; 15 | --color-title: #fff; 16 | --color-emphasis: #fff; 17 | --color-main: #ffc107; 18 | --color-rgb: 255, 255, 255; 19 | --color-border-focus: #57596B; 20 | 21 | --color-text: rgba(var(--color-rgb), .7); 22 | --color-link-active: rgba(var(--color-rgb), .2); 23 | --color-shape-bg: rgba(var(--color-rgb), .07); 24 | --color-shape: rgba(var(--color-rgb), .85); 25 | --color-button-border: rgba(var(--color-rgb), .2); 26 | --color-button-bg: transparent; 27 | --color-editor-bg: rgba(var(--color-rgb), .07); 28 | --color-graph-border: rgba(var(--color-rgb), .1); 29 | --graph-bg: transparent; 30 | 31 | --color-toggle-bg: rgba(var(--color-rgb), .1); 32 | --color-toggle-bg-active: rgba(var(--color-rgb), .15); 33 | --editor-shadow: none; 34 | } 35 | 36 | @media (prefers-color-scheme: light) { 37 | body { 38 | --color-bg: #f1f3f4; 39 | --color-title: #000; 40 | --color-emphasis: #000; 41 | --color-main: #ff5722; 42 | --color-rgb: 0, 0, 0; 43 | --color-border-focus: rgba(255, 255, 255, 0); 44 | --color-button-bg: #fff; 45 | 46 | --color-link-active: rgba(255, 87, 34, .08); 47 | --color-toggle-bg-active: rgba(255, 87, 34, .08); 48 | --color-toggle-bg: rgba(var(--color-rgb), .1); 49 | --color-shape-bg: #ffffff; 50 | --color-shape: rgba(var(--color-rgb), .8); 51 | --color-editor-bg: #ffffff; 52 | --color-graph-border: rgba(var(--color-rgb), .03); 53 | --editor-shadow: 0 5px 10px rgba(0, 0, 0, .05); 54 | --graph-bg: radial-gradient(#fff 80%, #f1f2f3); 55 | } 56 | .CodeMirror-code, 57 | .CodeMirror-cursors { 58 | filter: invert(1); 59 | } 60 | .CodeMirror-selected { 61 | opacity: .1; 62 | } 63 | } 64 | 65 | 66 | body[theme="dark"] { 67 | --color-bg: #060a11; 68 | --color-title: #fff; 69 | --color-emphasis: #fff; 70 | --color-main: #ffc107; 71 | --color-rgb: 255, 255, 255; 72 | --color-border-focus: #57596B; 73 | 74 | --color-text: rgba(var(--color-rgb), .7); 75 | --color-link-active: rgba(var(--color-rgb), .2); 76 | --color-shape-bg: rgba(var(--color-rgb), .07); 77 | --color-shape: rgba(var(--color-rgb), .85); 78 | --color-button-border: rgba(var(--color-rgb), .2); 79 | --color-button-bg: transparent; 80 | --color-editor-bg: rgba(var(--color-rgb), .07); 81 | --color-graph-border: rgba(var(--color-rgb), .08); 82 | --graph-bg: transparent; 83 | 84 | --color-toggle-bg: rgba(var(--color-rgb), .1); 85 | --color-toggle-bg-active: rgba(var(--color-rgb), .15); 86 | --editor-shadow: none; 87 | } 88 | 89 | body[theme="dark"] .CodeMirror-code, 90 | body[theme="dark"] .CodeMirror-cursors { 91 | filter: none; 92 | } 93 | body[theme="dark"] .CodeMirror-selected { 94 | opacity: 1; 95 | } 96 | 97 | body[theme="light"] { 98 | --color-bg: #f1f3f4; 99 | --color-title: #000; 100 | --color-emphasis: #000; 101 | --color-main: #ff5722; 102 | --color-rgb: 0, 0, 0; 103 | --color-border-focus: rgba(255, 255, 255, 0); 104 | --color-button-bg: #fff; 105 | 106 | --color-link-active: rgba(255, 87, 34, .08); 107 | --color-toggle-bg-active: rgba(255, 87, 34, .08); 108 | --color-toggle-bg: rgba(var(--color-rgb), .04); 109 | --color-shape-bg: #ffffff; 110 | --color-shape: rgba(var(--color-rgb), .8); 111 | --color-editor-bg: #ffffff; 112 | --color-graph-border: transparent; 113 | --editor-shadow: 0 5px 10px rgba(0, 0, 0, .05); 114 | --graph-bg: radial-gradient(#fff 80%, #f1f2f3); 115 | } 116 | 117 | body[theme="light"] .CodeMirror-code, 118 | body[theme="light"] .CodeMirror-cursors { 119 | filter: invert(1); 120 | } 121 | body[theme="light"] .CodeMirror-selected { 122 | opacity: .1; 123 | } 124 | 125 | body { 126 | background: var(--color-bg); 127 | color: var(--color-text); 128 | -webkit-font-smoothing: antialiased; 129 | } 130 | 131 | body, button { 132 | font-family: system-ui; 133 | } 134 | 135 | .ready { 136 | transition: .2s ease; 137 | } 138 | 139 | a { 140 | transition: background .2s ease; 141 | } 142 | a:link, a:visited { 143 | color: var(--color-main); 144 | } 145 | a:hover, a:active { 146 | background: var(--color-link-active); 147 | } 148 | 149 | h1, h2 { 150 | color: var(--color-title); 151 | } 152 | 153 | button[reset] { 154 | background: none; 155 | border: 0; 156 | border-radius: 0; 157 | padding: 0; 158 | margin: 0; 159 | cursor: pointer; 160 | line-height: 1; 161 | -webkit-touch-callout: none; 162 | touch-action: none; 163 | } 164 | 165 | button:focus:not(:focus-visible) { 166 | outline: 0; 167 | } 168 | -------------------------------------------------------------------------------- /src/components/about.svelte: -------------------------------------------------------------------------------- 1 | 2 |
3 |

About

4 |

5 | This tool is for discovering new CSS polygon shapes generated with 6 | css-doodle @shape function 7 | and mathematical expressions. 8 | Read more about its usage: https://yuanchuan.dev/polygon-shapes. 9 |

10 | 11 |

Commands

12 |
    13 |
  • 14 | fill 15 | nonzero | evenodd; 16 |
  • 17 |
  • 18 | frame 19 | number for frame size; 20 |
  • 21 |
  • 22 | points 23 | number between 3 - 3600; 24 |
  • 25 |
  • 26 | rotate 27 | number in degree for rotation; 28 |
  • 29 |
  • 30 | scale 31 | number for scale factor; 32 |
  • 33 |
  • 34 | move 35 | a pair of value for translating x, y coords; 36 |
  • 37 |
  • 38 | turn 39 | angle between start/end point, defaults to be 1; 40 |
  • 41 |
  • 42 | x 43 | x coordinate for cartesian equation; 44 |
  • 45 |
  • 46 | y 47 | y coordinate for cartesian equation; 48 |
  • 49 |
  • 50 | r 51 | polar equation; 52 |
  • 53 |
54 | 55 |

Operations in equations

56 |
    57 |
  • Operations available: + - * / % ^ | &
  • 58 |
  • 59 | All JavaScript Math functions and constants are supported. 60 | Such as 61 | sin, 62 | cos, 63 | tan, 64 | abs, 65 | pow, 66 | PI or π etc. 67 |
  • 68 |
69 | 70 |

Variables

71 |
72 |

73 | Everything declared is considered a variable. 74 |

75 |
76 | 77 | 78 |
79 |
80 | 81 | 92 | 93 | 139 | -------------------------------------------------------------------------------- /src/components/back.svelte: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Back 6 | 7 | 8 | 11 | 12 | 24 | -------------------------------------------------------------------------------- /src/components/collection.svelte: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Select to edit

5 |
6 | {#each shapes as shape, i} 7 | 8 | {/each} 9 |
10 | 11 |
12 |
13 |
14 | 15 | 40 | 41 | 95 | -------------------------------------------------------------------------------- /src/components/color.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | 26 | 71 | -------------------------------------------------------------------------------- /src/components/doodle.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | 30 | 59 | -------------------------------------------------------------------------------- /src/components/editor.svelte: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 |
8 | 9 |