├── src ├── utils │ ├── expresssion.ts │ ├── dark.ts │ ├── stringify.ts │ ├── load.ts │ ├── canvas.ts │ ├── index.ts │ ├── vector.ts │ ├── shake.ts │ └── colors.ts ├── App.vue ├── window.d.ts ├── pages │ ├── 014.vue │ ├── _template.vue │ ├── 014.psvg │ ├── [...miss].vue │ ├── _template_p5.vue │ ├── 009.vue │ ├── plum.psvg │ ├── 000.vue │ ├── index.vue │ ├── 038.vue │ ├── 001.vue │ ├── 007.vue │ ├── 016.vue │ ├── 027.vue │ ├── 036.vue │ ├── 037.vue │ ├── 033.vue │ ├── 026.vue │ ├── 030.vue │ ├── 031.vue │ ├── 034.vue │ ├── 039.vue │ ├── 025.vue │ ├── 017.vue │ ├── 010.vue │ ├── 013.vue │ ├── 029.vue │ ├── 024.vue │ ├── x-shadow.vue │ ├── 015.vue │ ├── 028.vue │ ├── 012.vue │ ├── 002.vue │ ├── 021.vue │ ├── 035.vue │ ├── 011.vue │ ├── x-lifetime-playground.vue │ ├── 008.vue │ ├── 023.vue │ ├── 022.vue │ ├── 019.vue │ ├── 003.vue │ ├── 018.vue │ ├── 020.vue │ ├── 006.vue │ ├── 032.vue │ ├── 004.vue │ └── 005.vue ├── main.ts ├── components │ ├── Toggle.vue │ ├── Turns.vue │ ├── Note.vue │ ├── Paper.vue │ └── PlaygroundX.vue ├── main.postcss └── works.ts ├── .github └── FUNDING.yml ├── .tazerc.json ├── public ├── shots │ ├── 001.png │ ├── 002.png │ ├── 003.png │ ├── 004.png │ ├── 005.png │ ├── 006.png │ ├── 007.png │ ├── 008.png │ ├── 009.png │ ├── 010.png │ ├── 011.png │ ├── 012.png │ ├── 013.png │ ├── 014.png │ ├── 015.png │ ├── 016.png │ ├── 017.png │ ├── 018.png │ ├── 019.png │ ├── 020.png │ ├── 021.png │ ├── 022.png │ ├── 023.png │ ├── 024.png │ ├── 025.png │ ├── 026.png │ ├── 027.png │ ├── 028.png │ ├── 029.png │ ├── 030.png │ ├── 031.png │ ├── 032.png │ ├── 033.png │ ├── 034.png │ ├── 035.png │ ├── 036.png │ ├── 037.png │ └── index.png ├── 020-goldfish.png ├── 019-tree.svg ├── favicon.svg └── 037.svg ├── .gitignore ├── netlify.toml ├── .vscode ├── extensions.json └── settings.json ├── eslint.config.js ├── tsconfig.json ├── uno.config.ts ├── index.html ├── components.d.ts ├── vite.config.ts ├── LICENSE ├── README.md ├── scripts ├── postbuild.ts └── screenshot.ts └── package.json /src/utils/expresssion.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: antfu 2 | -------------------------------------------------------------------------------- /.tazerc.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": [ 3 | "three" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /public/shots/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/001.png -------------------------------------------------------------------------------- /public/shots/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/002.png -------------------------------------------------------------------------------- /public/shots/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/003.png -------------------------------------------------------------------------------- /public/shots/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/004.png -------------------------------------------------------------------------------- /public/shots/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/005.png -------------------------------------------------------------------------------- /public/shots/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/006.png -------------------------------------------------------------------------------- /public/shots/007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/007.png -------------------------------------------------------------------------------- /public/shots/008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/008.png -------------------------------------------------------------------------------- /public/shots/009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/009.png -------------------------------------------------------------------------------- /public/shots/010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/010.png -------------------------------------------------------------------------------- /public/shots/011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/011.png -------------------------------------------------------------------------------- /public/shots/012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/012.png -------------------------------------------------------------------------------- /public/shots/013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/013.png -------------------------------------------------------------------------------- /public/shots/014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/014.png -------------------------------------------------------------------------------- /public/shots/015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/015.png -------------------------------------------------------------------------------- /public/shots/016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/016.png -------------------------------------------------------------------------------- /public/shots/017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/017.png -------------------------------------------------------------------------------- /public/shots/018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/018.png -------------------------------------------------------------------------------- /public/shots/019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/019.png -------------------------------------------------------------------------------- /public/shots/020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/020.png -------------------------------------------------------------------------------- /public/shots/021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/021.png -------------------------------------------------------------------------------- /public/shots/022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/022.png -------------------------------------------------------------------------------- /public/shots/023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/023.png -------------------------------------------------------------------------------- /public/shots/024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/024.png -------------------------------------------------------------------------------- /public/shots/025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/025.png -------------------------------------------------------------------------------- /public/shots/026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/026.png -------------------------------------------------------------------------------- /public/shots/027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/027.png -------------------------------------------------------------------------------- /public/shots/028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/028.png -------------------------------------------------------------------------------- /public/shots/029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/029.png -------------------------------------------------------------------------------- /public/shots/030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/030.png -------------------------------------------------------------------------------- /public/shots/031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/031.png -------------------------------------------------------------------------------- /public/shots/032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/032.png -------------------------------------------------------------------------------- /public/shots/033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/033.png -------------------------------------------------------------------------------- /public/shots/034.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/034.png -------------------------------------------------------------------------------- /public/shots/035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/035.png -------------------------------------------------------------------------------- /public/shots/036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/036.png -------------------------------------------------------------------------------- /public/shots/037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/037.png -------------------------------------------------------------------------------- /public/020-goldfish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/020-goldfish.png -------------------------------------------------------------------------------- /public/shots/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antfu/100/main/public/shots/index.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | *.local 5 | scripts/screenshots 6 | *.tsbuildinfo 7 | -------------------------------------------------------------------------------- /src/utils/dark.ts: -------------------------------------------------------------------------------- 1 | import { useDark } from '@vueuse/core' 2 | 3 | export const isDark = useDark() 4 | 5 | export function toggleDark() { 6 | isDark.value = !isDark.value 7 | } 8 | -------------------------------------------------------------------------------- /src/window.d.ts: -------------------------------------------------------------------------------- 1 | import type Matter from '@types/matter-js' 2 | import type * as THREE from 'three' 3 | 4 | declare interface Window { 5 | Matter: Matter 6 | THREE: THREE 7 | } 8 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "dist" 3 | command = "pnpm run build" 4 | 5 | [build.environment] 6 | NODE_VERSION = "20" 7 | 8 | [[redirects]] 9 | from = "/*" 10 | to = "/index.html" 11 | status = 200 12 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "octref.vetur", 4 | "antfu.i18n-ally", 5 | "antfu.iconify", 6 | "dbaeumer.vscode-eslint", 7 | "bradlc.vscode-tailwindcss" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu({ 4 | formatters: true, 5 | unocss: true, 6 | vue: true, 7 | }) 8 | .removeRules( 9 | 'unused-imports/no-unused-vars', 10 | ) 11 | -------------------------------------------------------------------------------- /src/pages/014.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /public/019-tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/utils/stringify.ts: -------------------------------------------------------------------------------- 1 | export function stringify(obj: any) { 2 | return JSON.stringify(obj) 3 | .replace(/"/g, '\'') 4 | .replace(/:/g, ': ') 5 | .replace(/\{/g, '{ ') 6 | .replace(/\}/g, ' }') 7 | .replace(/,/g, ', ') 8 | .replace(/'(\w+)':/g, '$1:') 9 | .replace(/'(\d+)'/g, '$1') 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/load.ts: -------------------------------------------------------------------------------- 1 | export function load(url: string) { 2 | return new Promise((resolve) => { 3 | if (document.head.querySelector(`script[src="${url}"]`)) 4 | return resolve() 5 | 6 | const script = document.createElement('script') 7 | script.src = url 8 | script.onload = () => resolve() 9 | document.head.appendChild(script) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/_template.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "incremental": true, 4 | "target": "ESNext", 5 | "lib": ["DOM", "ESNext"], 6 | "baseUrl": ".", 7 | "module": "ESNext", 8 | "moduleResolution": "node", 9 | "paths": { 10 | "/~/*": ["src/*"] 11 | }, 12 | "resolveJsonModule": true, 13 | "strict": true, 14 | "esModuleInterop": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["dist", "node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { createApp } from 'vue' 4 | import { createRouter, createWebHistory } from 'vue-router' 5 | import routes from '~pages' 6 | 7 | import App from './App.vue' 8 | import '@unocss/reset/tailwind.css' 9 | 10 | import './main.postcss' 11 | 12 | import 'uno.css' 13 | 14 | const app = createApp(App) 15 | const router = createRouter({ 16 | history: createWebHistory(), 17 | routes, 18 | }) 19 | 20 | app.use(router) 21 | app.mount('#app') 22 | -------------------------------------------------------------------------------- /src/components/Toggle.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import extractorPug from '@unocss/extractor-pug' 2 | import { 3 | defineConfig, 4 | presetUno, 5 | presetWebFonts, 6 | transformerDirectives, 7 | } from 'unocss' 8 | 9 | export default defineConfig({ 10 | presets: [ 11 | presetUno(), 12 | presetWebFonts({ 13 | fonts: { 14 | code: 'DM Mono', 15 | sans: 'DM Sans', 16 | serif: 'DM Serif Display', 17 | }, 18 | }), 19 | ], 20 | transformers: [ 21 | transformerDirectives(), 22 | ], 23 | extractors: [ 24 | extractorPug(), 25 | ], 26 | }) 27 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 100 days 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/pages/014.psvg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/utils/canvas.ts: -------------------------------------------------------------------------------- 1 | export function initCanvas(canvas: HTMLCanvasElement, width = 400, height = 400, _dpi?: number) { 2 | const ctx = canvas.getContext('2d')! 3 | 4 | const dpr = window.devicePixelRatio || 1 5 | // @ts-expect-error vendor prefix 6 | const bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1 7 | 8 | const dpi = _dpi || dpr / bsr 9 | 10 | canvas.style.width = `${width}px` 11 | canvas.style.height = `${height}px` 12 | canvas.width = dpi * width 13 | canvas.height = dpi * height 14 | ctx.scale(dpi, dpi) 15 | 16 | return { ctx, dpi } 17 | } 18 | -------------------------------------------------------------------------------- /src/pages/[...miss].vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | 27 | 38 | -------------------------------------------------------------------------------- /src/components/Turns.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 25 | 26 | 32 | -------------------------------------------------------------------------------- /components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | CarbonChevronLeft: typeof import('~icons/carbon/chevron-left')['default'] 11 | Note: typeof import('./src/components/Note.vue')['default'] 12 | Paper: typeof import('./src/components/Paper.vue')['default'] 13 | PlaygroundX: typeof import('./src/components/PlaygroundX.vue')['default'] 14 | RouterLink: typeof import('vue-router')['RouterLink'] 15 | RouterView: typeof import('vue-router')['RouterView'] 16 | Toggle: typeof import('./src/components/Toggle.vue')['default'] 17 | Turns: typeof import('./src/components/Turns.vue')['default'] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/_template_p5.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 32 | -------------------------------------------------------------------------------- /src/pages/009.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 38 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import Vue from '@vitejs/plugin-vue' 3 | import UnoCSS from 'unocss/vite' 4 | import AutoImport from 'unplugin-auto-import/vite' 5 | import IconsResolver from 'unplugin-icons/resolver' 6 | import Icons from 'unplugin-icons/vite' 7 | import Components from 'unplugin-vue-components/vite' 8 | import Pages from 'vite-plugin-pages' 9 | import PSVG from 'vite-plugin-psvg' 10 | 11 | const config: UserConfig = { 12 | optimizeDeps: { 13 | include: [ 14 | '@vueuse/core', 15 | '@vueuse/shared', 16 | '@vueuse/router', 17 | 'three', 18 | 'lodash-es', 19 | 'p5i', 20 | 'matter-js', 21 | 'matter-attractors', 22 | ], 23 | }, 24 | plugins: [ 25 | Vue(), 26 | Pages(), 27 | Components({ 28 | resolvers: [ 29 | IconsResolver({ 30 | prefix: '', 31 | }), 32 | ], 33 | }), 34 | Icons(), 35 | PSVG(), 36 | UnoCSS(), 37 | AutoImport({ 38 | imports: [ 39 | 'vue', 40 | '@vueuse/core', 41 | ], 42 | }), 43 | ], 44 | } 45 | 46 | export default config 47 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { useRafFn } from '@vueuse/core' 2 | import { ref } from 'vue' 3 | 4 | export * from './canvas' 5 | export * from './colors' 6 | export * from './load' 7 | export * from './shake' 8 | export * from './stringify' 9 | export * from './vector' 10 | 11 | export function noop() {} 12 | 13 | export function shuffle(arr: T[]): T[] { 14 | const array = arr.slice(0) 15 | for (let i = array.length - 1; i > 0; i--) { 16 | const j = Math.floor(Math.random() * (i + 1)); 17 | [array[i], array[j]] = [array[j], array[i]] 18 | } 19 | return array 20 | } 21 | 22 | export function range(to: number) { 23 | return Array.from({ length: to }).fill(0).map((_, i) => i) 24 | } 25 | 26 | export function useWindowPosition() { 27 | const screenTop = ref(window.screenTop) 28 | const screenLeft = ref(window.screenLeft) 29 | 30 | const timeout = useRafFn(() => { 31 | screenTop.value = window.screenTop 32 | screenLeft.value = window.screenLeft 33 | }) 34 | 35 | return { screenLeft, screenTop, timeout } 36 | } 37 | 38 | export function random(max = 1, min = 0) { 39 | return Math.random() * (max - min) + min 40 | } 41 | -------------------------------------------------------------------------------- /src/pages/plum.psvg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Anthony Fu // free feel to change it to your name. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/pages/000.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 38 | 39 | 57 | -------------------------------------------------------------------------------- /src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 100 2 | 3 | My 100 day project of exploring design, compform, and new things. 4 | 5 | [100.antfu.me](http://100.antfu.me/)  |  [updates on Twitter](https://twitter.com/antfu7/status/1325977074813739009) 6 | 7 |
8 | 9 |

10 | Day 13, plum 11 |

12 | 13 | ## Join us! 14 | 15 | [@octref](https://github.com/octref)(100.matsu.io) and me started our 100-day challenges as we wanted to learn creative coding while having fun. 16 | 17 | We would love to share the journey with you and have you learning and doing sketches together. **Join us in [Codecember](https://codecember.netlify.app/)**, 18 | we'll give you a prompt every day that includes an artwork, its source code and a blurb, throughout December, 2020. 19 | 20 |

21 | 22 | Day 13, plum 23 | 24 |

25 | 26 | ## Sponsors 27 | 28 | This project is part of my Sponsor Program 29 | 30 |

31 | 32 | 33 | 34 |

35 | 36 | ## License 37 | 38 | MIT 39 | -------------------------------------------------------------------------------- /src/pages/038.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 70 | -------------------------------------------------------------------------------- /src/pages/001.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /src/main.postcss: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | #app { 4 | margin: 0; 5 | padding: 0; 6 | @apply font-mono font-light; 7 | } 8 | 9 | html.dark { 10 | filter: invert(1) hue-rotate(180deg); 11 | } 12 | 13 | body { 14 | background: white; 15 | } 16 | 17 | .paper { 18 | @apply fixed top-0 left-0 right-0 bottom-0 grid; 19 | place-items: center; 20 | user-select: none; 21 | justify-content: center; 22 | } 23 | 24 | .link { 25 | @apply text-true-gray-400 hover:text-true-gray-700 transition select-none; 26 | } 27 | 28 | del { 29 | @apply opacity-50; 30 | } 31 | 32 | .centered { 33 | position: fixed; 34 | top: 50%; 35 | left: 50%; 36 | transform: translate(-50%, -50%); 37 | } 38 | 39 | .index-page { 40 | max-height: 100%; 41 | padding: 60px 40px 30px 40px; 42 | overflow: auto; 43 | 44 | @apply w-full md:w-auto; 45 | } 46 | 47 | .box { 48 | width: 400px; 49 | height: 400px; 50 | } 51 | 52 | .large.box { 53 | width: 800px; 54 | height: 800px; 55 | } 56 | 57 | .box:not(.borderless) { 58 | border: 1px solid black; 59 | } 60 | 61 | .box-heading { 62 | position: fixed; 63 | left: calc(50% - 200px); 64 | width: 400px; 65 | bottom: calc(50% + 200px); 66 | } 67 | 68 | .box-description { 69 | position: fixed; 70 | left: calc(50% - 200px); 71 | width: 400px; 72 | top: calc(50% + 200px); 73 | } 74 | 75 | a[target='_blank']:not(.link) { 76 | @apply underline opacity-75 hover:opacity-100 transition-opacity; 77 | } 78 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "i18n-ally.localesPaths": "locales", 3 | "i18n-ally.keystyle": "nested", 4 | "i18n-ally.sortKeys": true, 5 | 6 | // Enable the ESlint flat config support 7 | "eslint.experimental.useFlatConfig": true, 8 | 9 | // Disable the default formatter, use eslint instead 10 | "prettier.enable": false, 11 | "editor.formatOnSave": false, 12 | 13 | // Auto fix 14 | "editor.codeActionsOnSave": { 15 | "source.fixAll.eslint": "explicit", 16 | "source.organizeImports": "never" 17 | }, 18 | 19 | // Silent the stylistic rules in you IDE, but still auto fix them 20 | "eslint.rules.customizations": [ 21 | { "rule": "style/*", "severity": "off" }, 22 | { "rule": "format/*", "severity": "off" }, 23 | { "rule": "*-indent", "severity": "off" }, 24 | { "rule": "*-spacing", "severity": "off" }, 25 | { "rule": "*-spaces", "severity": "off" }, 26 | { "rule": "*-order", "severity": "off" }, 27 | { "rule": "*-dangle", "severity": "off" }, 28 | { "rule": "*-newline", "severity": "off" }, 29 | { "rule": "*quotes", "severity": "off" }, 30 | { "rule": "*semi", "severity": "off" } 31 | ], 32 | 33 | // Enable eslint for all supported languages 34 | "eslint.validate": [ 35 | "javascript", 36 | "javascriptreact", 37 | "typescript", 38 | "typescriptreact", 39 | "vue", 40 | "html", 41 | "markdown", 42 | "json", 43 | "jsonc", 44 | "yaml", 45 | "toml", 46 | "astro" 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /scripts/postbuild.ts: -------------------------------------------------------------------------------- 1 | import cheerio from 'cheerio' 2 | import fs from 'fs-extra' 3 | import { works } from '../src/works' 4 | 5 | const DOMAIN = 'https://100.antfu.me' 6 | 7 | export async function postBuild() { 8 | // console.log('post build!') 9 | 10 | const indexHTML = await fs.readFile('dist/index.html', 'utf-8') 11 | 12 | for (const work of works) { 13 | const $ = cheerio.load(indexHTML) 14 | 15 | const head = $('head') 16 | const title = `${work.no}. ${work.name}` 17 | $('title').text(title) 18 | 19 | head.append($(``)) 20 | 21 | if (fs.existsSync(`public/shots/${work.no}.png`)) { 22 | head.append($(``)) 23 | head.append($('')) 24 | } 25 | head.append($('')) 26 | 27 | await fs.writeFile(`dist/${work.no}.html`, $.html(), 'utf-8') 28 | } 29 | 30 | const $ = cheerio.load(indexHTML) 31 | const head = $('head') 32 | const title = $('title').text() 33 | 34 | head.append($(``)) 35 | head.append($(``)) 36 | head.append($('')) 37 | head.append($('')) 38 | 39 | await fs.writeFile('dist/index.html', $.html(), 'utf-8') 40 | } 41 | 42 | postBuild() 43 | -------------------------------------------------------------------------------- /src/components/Note.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 24 | 25 | 57 | -------------------------------------------------------------------------------- /src/utils/vector.ts: -------------------------------------------------------------------------------- 1 | export type Vector = [number, number] 2 | 3 | export const r180 = Math.PI 4 | export const r90 = Math.PI / 2 5 | export const r60 = Math.PI / 3 6 | export const r30 = Math.PI / 6 7 | export const r15 = Math.PI / 12 8 | export const r120 = Math.PI / 3 * 2 9 | export const r360 = Math.PI * 2 10 | 11 | export const SQRT_3 = Math.sqrt(3) 12 | export const SQRT_2 = Math.sqrt(2) 13 | 14 | export function exclude(arr: T[], v: T) { 15 | return arr.filter(i => i !== v) 16 | } 17 | 18 | export function square(a: number) { 19 | return a ** 2 20 | } 21 | 22 | export function addVec([x1, y1]: Vector, [x2, y2]: Vector): Vector { 23 | return [x1 + x2, y1 + y2] 24 | } 25 | 26 | export function vec2mat([x, y]: Vector) { 27 | return { x, y } 28 | } 29 | 30 | export function distance([x1, y1]: Vector, [x2, y2]: Vector) { 31 | return Math.sqrt(square(x1 - x2) + square(y1 - y2)) 32 | } 33 | 34 | export function get(arr: T[], index: number) { 35 | return arr[index % arr.length] 36 | } 37 | 38 | export function pick(arr: T[], current?: T): T { 39 | if (current) 40 | return pick(exclude(arr, current)) 41 | 42 | return arr[Math.round(Math.random() * (arr.length - 1))] 43 | } 44 | 45 | export function next(arr: T[], current: T): T { 46 | const index = arr.indexOf(current) 47 | if (index < 0) 48 | return pick(arr) 49 | return get(arr, index + 1) 50 | } 51 | 52 | export function polar2cart(x = 0, y = 0, r = 0, theta = 0) { 53 | const dx = r * Math.cos(theta) 54 | const dy = r * Math.sin(theta) 55 | return [x + dx, y + dy] 56 | } 57 | 58 | export function inbound([x, y]: Vector, width = 400, height = 400) { 59 | return x >= 0 && x < width && y >= 0 && y < height 60 | } 61 | -------------------------------------------------------------------------------- /src/pages/007.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 52 | 53 | 63 | -------------------------------------------------------------------------------- /src/utils/shake.ts: -------------------------------------------------------------------------------- 1 | import { useDeviceMotion } from '@vueuse/core' 2 | import { watch } from 'vue' 3 | 4 | export function useShake(fn: () => void) { 5 | const options = { 6 | threshold: 10, // default velocity threshold for shake to register 7 | timeout: 500, // default interval between events 8 | } 9 | 10 | const { accelerationIncludingGravity } = useDeviceMotion() 11 | 12 | let lastX: number | null = null 13 | let lastY: number | null = null 14 | let lastZ: number | null = null 15 | let lastTime = new Date() 16 | 17 | watch(accelerationIncludingGravity, () => { 18 | const current = accelerationIncludingGravity.value 19 | if (!current) 20 | return 21 | 22 | let currentTime 23 | let timeDifference 24 | let deltaX = 0 25 | let deltaY = 0 26 | let deltaZ = 0 27 | 28 | if (lastX === null || lastY === null || lastZ === null) { 29 | lastX = current.x 30 | lastY = current.y 31 | lastZ = current.z 32 | return 33 | } 34 | 35 | deltaX = Math.abs(lastX - current.x!) 36 | deltaY = Math.abs(lastY - current.y!) 37 | deltaZ = Math.abs(lastZ - current.z!) 38 | 39 | if (((deltaX > options.threshold) && (deltaY > options.threshold)) || ((deltaX > options.threshold) && (deltaZ > options.threshold)) || ((deltaY > options.threshold) && (deltaZ > options.threshold))) { 40 | // calculate time in milliseconds since last shake registered 41 | currentTime = new Date() 42 | timeDifference = currentTime.getTime() - lastTime.getTime() 43 | 44 | if (timeDifference > options.timeout) { 45 | fn() 46 | lastTime = new Date() 47 | } 48 | } 49 | 50 | lastX = current.x 51 | lastY = current.y 52 | lastZ = current.z 53 | }) 54 | } 55 | -------------------------------------------------------------------------------- /src/pages/016.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "100d", 3 | "type": "module", 4 | "private": true, 5 | "packageManager": "pnpm@9.15.1", 6 | "scripts": { 7 | "dev": "vite --port 3333 --open", 8 | "build": "cross-env NODE_ENV=production vite build && esno scripts/postbuild.ts", 9 | "shot": "esno scripts/screenshot.ts", 10 | "lint": "eslint .", 11 | "typecheck": "vue-tsc --noEmit" 12 | }, 13 | "dependencies": { 14 | "@iconify/iconify": "^3.1.1", 15 | "@unocss/extractor-pug": "^0.65.3", 16 | "@vueuse/core": "^12.2.0", 17 | "@vueuse/router": "^12.2.0", 18 | "@vueuse/shared": "^12.2.0", 19 | "dayjs": "^1.11.13", 20 | "lodash-es": "^4.17.21", 21 | "matter-attractors": "^0.1.6", 22 | "matter-js": "^0.19.0", 23 | "moveable": "^0.28.0", 24 | "opentype.js": "^1.3.4", 25 | "p5i": "^0.6.0", 26 | "poly-decomp": "^0.3.0", 27 | "simplex-noise": "^4.0.3", 28 | "three": "0.124.0", 29 | "vue": "^3.5.13", 30 | "vue-router": "^4.5.0" 31 | }, 32 | "devDependencies": { 33 | "@antfu/eslint-config": "^3.12.1", 34 | "@iconify/json": "^2.2.288", 35 | "@types/cheerio": "^0.22.35", 36 | "@types/fs-extra": "^11.0.4", 37 | "@types/lodash-es": "^4.17.12", 38 | "@types/matter-js": "^0.19.8", 39 | "@unocss/eslint-plugin": "^0.65.3", 40 | "@unocss/reset": "^0.65.3", 41 | "@vitejs/plugin-vue": "^5.2.1", 42 | "cheerio": "^1.0.0", 43 | "cross-env": "^7.0.3", 44 | "eslint": "^9.17.0", 45 | "eslint-plugin-format": "^0.1.3", 46 | "esno": "^4.8.0", 47 | "fs-extra": "^11.2.0", 48 | "playwright": "^1.49.1", 49 | "pug": "^3.0.3", 50 | "stylus": "^0.64.0", 51 | "typescript": "^5.7.2", 52 | "unocss": "^0.65.3", 53 | "unplugin-auto-import": "^0.19.0", 54 | "unplugin-icons": "^0.22.0", 55 | "unplugin-vue-components": "^0.28.0", 56 | "vite": "^6.0.5", 57 | "vite-plugin-pages": "^0.32.4", 58 | "vite-plugin-psvg": "^0.3.0", 59 | "vue-tsc": "^2.2.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/pages/027.vue: -------------------------------------------------------------------------------- 1 | 89 | 90 | 99 | -------------------------------------------------------------------------------- /src/pages/036.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 52 | 53 | 59 | 60 | 75 | -------------------------------------------------------------------------------- /src/pages/037.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 52 | 53 | 59 | 60 | 75 | -------------------------------------------------------------------------------- /src/utils/colors.ts: -------------------------------------------------------------------------------- 1 | import { clamp } from '@vueuse/core' 2 | 3 | export type ColorVector = [number, number, number] 4 | 5 | export function hexToRgb(hex: string): ColorVector { 6 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)! 7 | return [ 8 | Number.parseInt(result[1], 16), 9 | Number.parseInt(result[2], 16), 10 | Number.parseInt(result[3], 16), 11 | ] 12 | } 13 | 14 | export function toHex(c: number) { 15 | return c.toString(16).padStart(2, '0') 16 | } 17 | 18 | export function rgbToHex(r = 0, g = 0, b = 0) { 19 | return `#${toHex(r)}${toHex(g)}${toHex(b)}` 20 | } 21 | 22 | /** 23 | * @param vectors 24 | * @param num 0~1 25 | */ 26 | export function colorInterpration(vectors: ColorVector[], n: number) { 27 | if (n >= 1) 28 | return vectors[vectors.length - 1] 29 | 30 | const normalized = clamp(n, 0, 1) * (vectors.length - 1) 31 | const integer = Math.trunc(normalized) 32 | const frac = normalized - integer 33 | const nfrac = 1 - frac 34 | 35 | const [a1, a2, a3] = vectors[integer] 36 | const [b1, b2, b3] = vectors[integer + 1] 37 | 38 | return [ 39 | a1 * nfrac + b1 * frac, 40 | a2 * nfrac + b2 * frac, 41 | a3 * nfrac + b3 * frac, 42 | ] 43 | } 44 | 45 | export function hslToRgb(h: number, s: number, l: number): [number, number, number] { 46 | let r, g, b 47 | 48 | if (s === 0) { 49 | r = g = b = l // achromatic 50 | } 51 | else { 52 | const hue2rgb = function hue2rgb(p: number, q: number, t: number) { 53 | if (t < 0) 54 | t += 1 55 | if (t > 1) 56 | t -= 1 57 | if (t < 1 / 6) 58 | return p + (q - p) * 6 * t 59 | if (t < 1 / 2) 60 | return q 61 | if (t < 2 / 3) 62 | return p + (q - p) * (2 / 3 - t) * 6 63 | return p 64 | } 65 | 66 | const q = l < 0.5 ? l * (1 + s) : l + s - l * s 67 | const p = 2 * l - q 68 | r = hue2rgb(p, q, h + 1 / 3) 69 | g = hue2rgb(p, q, h) 70 | b = hue2rgb(p, q, h - 1 / 3) 71 | } 72 | 73 | return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)] 74 | } 75 | -------------------------------------------------------------------------------- /src/pages/033.vue: -------------------------------------------------------------------------------- 1 | 69 | 70 | 77 | -------------------------------------------------------------------------------- /src/components/Paper.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 61 | 62 | 95 | -------------------------------------------------------------------------------- /src/pages/026.vue: -------------------------------------------------------------------------------- 1 | 88 | 89 | 96 | -------------------------------------------------------------------------------- /src/pages/030.vue: -------------------------------------------------------------------------------- 1 | 102 | 103 | 112 | -------------------------------------------------------------------------------- /src/pages/031.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 118 | -------------------------------------------------------------------------------- /src/pages/034.vue: -------------------------------------------------------------------------------- 1 | 106 | 107 | 114 | -------------------------------------------------------------------------------- /src/pages/039.vue: -------------------------------------------------------------------------------- 1 | 105 | 106 | 111 | -------------------------------------------------------------------------------- /src/pages/025.vue: -------------------------------------------------------------------------------- 1 | 95 | 96 | 109 | -------------------------------------------------------------------------------- /src/pages/017.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 114 | -------------------------------------------------------------------------------- /scripts/screenshot.ts: -------------------------------------------------------------------------------- 1 | import { chromium } from 'playwright' 2 | 3 | async function run() { 4 | const browser = await chromium.launch({ headless: false }) 5 | const context = await browser.newContext({ 6 | viewport: { 7 | width: 960, 8 | height: 500, 9 | }, 10 | deviceScaleFactor: 2, 11 | }) 12 | 13 | async function take(no: string, retry = 3, delay = 1000, take = 1, query = '', delayBetweenShot = 0, prefix = '') { 14 | for (let i = 0; i < retry; i++) { 15 | const page = await context.newPage() 16 | await page.goto(`http://localhost:3333/${no}?shot=true${query}`) 17 | await page.waitForTimeout(delay) 18 | for (let j = 0; j < take; j++) { 19 | await page.screenshot({ path: `scripts/screenshots/${prefix}${no}-${i}-${j}.png` }) 20 | if (delayBetweenShot) 21 | await page.waitForTimeout(delayBetweenShot) 22 | } 23 | 24 | page.close() 25 | } 26 | } 27 | 28 | async function open(no: string, query = '') { 29 | const page = await context.newPage() 30 | await page.goto(`http://localhost:3333/${no}?shot=true${query}`) 31 | await page.waitForEvent('close') 32 | return page 33 | } 34 | 35 | // await take('', 1) 36 | // await take('001', 3, 800, 4) 37 | // await take('002', 8, 500) 38 | // await take('003', 1, 1500, 5) 39 | // await take('004', 1, 500) 40 | // await take('005', 5, 1000, 20, '&q=th%20-%20sin(r)%20*%20cos(t)') 41 | // await take('006', 4, 3000, 5, '&shake=true') 42 | // await take('007', 1, 500) 43 | // await take('008', 1, 500, 8) 44 | // await take('009', 10, 1500) 45 | // await take('010', 1, 500) 46 | // await take('011', 10, 500) 47 | // await take('012', 10, 500, 4) 48 | // await take('013', 20, 3000, 3) 49 | // await take('014', 1, 10000, 5) 50 | // await take('015', 2, 7000, 10, '', 1000) 51 | // await take('016', 1, 500, 10, '', 500) 52 | // await take('017', 1, 3000, 5) 53 | // await take('018', 1, 2000, 20, '', 900) 54 | // await take('019', 1, 1000, 1) 55 | // await take('020', 30, 1500, 1) 56 | // await take('021', 20, 1000, 1) 57 | // await take('022', 2, 2000, 1) 58 | // await Promise.all([ 59 | // take('023', 3, 10000, 1, '', 2000, 'c'), 60 | // take('023', 3, 10000, 1, '', 2000, 'd'), 61 | // take('023', 3, 10000, 1, '', 2000, 'e'), 62 | // ]) 63 | // await take('024', 5, 3000, 3, '', 500) 64 | // await take('025', 5, 10000, 3, '', 1000) 65 | // await take('026', 1, 5000, 3, '', 1000) 66 | // await take('027', 1, 1000, 50, '', 1000) 67 | // await take('028', 4, 1000) 68 | // await open('028') 69 | // await take('029', 20, 1000) 70 | // await take('030', 10, 2000) 71 | // await open('030') 72 | // await take('031', 5, 1000) 73 | // await take('032', 5, 1000, 5) 74 | // await open('032') 75 | // await take('033', 1, 1000, 10, '', 1000) 76 | // await take('034', 5, 1000) 77 | // await take('035', 20, 8000) 78 | // await take('036', 1, 1000) 79 | await take('037', 1, 1000) 80 | 81 | await browser.close() 82 | } 83 | 84 | run() 85 | -------------------------------------------------------------------------------- /src/pages/010.vue: -------------------------------------------------------------------------------- 1 | 105 | 106 | 115 | 116 | 119 | -------------------------------------------------------------------------------- /src/works.ts: -------------------------------------------------------------------------------- 1 | export const info = [ 2 | { 3 | name: 'Mass', 4 | date: '2020/11/06', 5 | draft: false, 6 | }, 7 | { 8 | name: 'Hex', 9 | date: '2020/11/07', 10 | }, 11 | { 12 | name: 'Three', 13 | date: '2020/11/08', 14 | }, 15 | { 16 | name: 'Scope', 17 | date: '2020/11/09', 18 | }, 19 | { 20 | name: 'Polar', 21 | date: '2020/11/10', 22 | }, 23 | { 24 | name: 'M & M', 25 | date: '2020/11/11', 26 | }, 27 | { 28 | name: 'Ship', 29 | date: '2020/11/12', 30 | }, 31 | { 32 | name: 'Negative', 33 | date: '2020/11/13', 34 | }, 35 | { 36 | name: 'Unreproducible', 37 | date: '2020/11/14', 38 | }, 39 | { 40 | name: '方圓', 41 | date: '2020/11/15', 42 | }, 43 | { 44 | name: 'Box', 45 | date: '2020/11/16', 46 | }, 47 | { 48 | name: 'Displace', 49 | date: '2020/11/17', 50 | }, 51 | { 52 | name: 'Plum', 53 | date: '2020/11/18', 54 | }, 55 | { 56 | name: 'Orbit', 57 | date: '2020/11/19', 58 | }, 59 | { 60 | name: 'Rust', 61 | date: '2020/11/20', 62 | }, 63 | { 64 | name: 'Connect', 65 | date: '2020/11/21', 66 | }, 67 | { 68 | name: 'Gravity', 69 | date: '2020/11/22', 70 | }, 71 | { 72 | name: 'Field 1', 73 | date: '2020/11/23', 74 | }, 75 | { 76 | name: 'Fractal 1', 77 | date: '2020/11/24', 78 | }, 79 | { 80 | name: 'Clone', 81 | date: '2020/11/25', 82 | }, 83 | { 84 | name: 'Cross', 85 | date: '2020/11/26', 86 | }, 87 | { 88 | name: 'ㄇㄈㄩコロ', 89 | date: '2020/11/27', 90 | }, 91 | { 92 | name: 'Knitting', 93 | date: '2020/11/28', 94 | }, 95 | { 96 | name: 'Cast', 97 | date: '2020/11/30', 98 | }, 99 | { 100 | name: 'Kaleidoscope', 101 | date: '2020/12/01', 102 | }, 103 | { 104 | name: 'Lines', 105 | date: '2020/12/02', 106 | }, 107 | { 108 | name: 'Flat', 109 | date: '2020/12/03', 110 | }, 111 | { 112 | name: 'Joy', 113 | date: '2020/12/04', 114 | }, 115 | { 116 | name: 'Attractor', 117 | date: '2020/12/05', 118 | }, 119 | { 120 | name: 'River', 121 | date: '2020/12/06', 122 | }, 123 | { 124 | name: 'Arc', 125 | date: '2020/12/07', 126 | }, 127 | { 128 | name: 'z = tixy', 129 | date: '2020/12/08', 130 | }, 131 | { 132 | name: 'Glass', 133 | date: '2020/12/15', 134 | }, 135 | { 136 | name: 'Moiré', 137 | date: '2020/12/15', 138 | }, 139 | { 140 | name: 'Window', 141 | date: '2020/12/15', 142 | }, 143 | { 144 | name: 'Arch 1', 145 | date: '2021/01/30', 146 | }, 147 | { 148 | name: 'Arch 2', 149 | date: '2021/01/30', 150 | }, 151 | { 152 | name: 'Boxes', 153 | date: '2020/12/06', 154 | }, 155 | { 156 | name: 'Dots', 157 | date: '2020/12/06', 158 | }, 159 | ] 160 | 161 | export const works = info.map((info, idx) => { 162 | return { 163 | ...info, 164 | no: `${idx + 1}`.padStart(3, '0'), 165 | } 166 | }) 167 | -------------------------------------------------------------------------------- /src/pages/013.vue: -------------------------------------------------------------------------------- 1 | 91 | 92 | 112 | -------------------------------------------------------------------------------- /src/pages/029.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 113 | -------------------------------------------------------------------------------- /src/pages/024.vue: -------------------------------------------------------------------------------- 1 | 128 | 129 | 134 | -------------------------------------------------------------------------------- /src/pages/x-shadow.vue: -------------------------------------------------------------------------------- 1 | 131 | 132 | 136 | 137 | 140 | -------------------------------------------------------------------------------- /src/pages/015.vue: -------------------------------------------------------------------------------- 1 | 161 | 162 | 167 | -------------------------------------------------------------------------------- /src/pages/028.vue: -------------------------------------------------------------------------------- 1 | 122 | 123 | 138 | -------------------------------------------------------------------------------- /src/pages/012.vue: -------------------------------------------------------------------------------- 1 | 137 | 138 | 150 | -------------------------------------------------------------------------------- /src/pages/002.vue: -------------------------------------------------------------------------------- 1 | 135 | 136 | 149 | 150 | 153 | -------------------------------------------------------------------------------- /src/pages/021.vue: -------------------------------------------------------------------------------- 1 | 172 | 173 | 178 | -------------------------------------------------------------------------------- /src/pages/035.vue: -------------------------------------------------------------------------------- 1 | 186 | 187 | 194 | -------------------------------------------------------------------------------- /src/pages/011.vue: -------------------------------------------------------------------------------- 1 | 159 | 160 | 164 | 165 | 168 | -------------------------------------------------------------------------------- /src/pages/x-lifetime-playground.vue: -------------------------------------------------------------------------------- 1 | 168 | 169 | 179 | -------------------------------------------------------------------------------- /src/pages/008.vue: -------------------------------------------------------------------------------- 1 | 170 | 171 | 185 | 186 | 189 | -------------------------------------------------------------------------------- /src/pages/023.vue: -------------------------------------------------------------------------------- 1 | 175 | 176 | 181 | -------------------------------------------------------------------------------- /src/pages/022.vue: -------------------------------------------------------------------------------- 1 | 184 | 185 | 190 | 191 | 194 | -------------------------------------------------------------------------------- /src/components/PlaygroundX.vue: -------------------------------------------------------------------------------- 1 | 194 | 195 | 221 | 222 | 224 | -------------------------------------------------------------------------------- /src/pages/019.vue: -------------------------------------------------------------------------------- 1 | 163 | 164 | 171 | 172 | 191 | -------------------------------------------------------------------------------- /src/pages/003.vue: -------------------------------------------------------------------------------- 1 | 172 | 173 | 182 | 183 | 186 | -------------------------------------------------------------------------------- /src/pages/018.vue: -------------------------------------------------------------------------------- 1 | 176 | 177 | 202 | -------------------------------------------------------------------------------- /src/pages/020.vue: -------------------------------------------------------------------------------- 1 | 190 | 191 | 203 | 204 | 207 | -------------------------------------------------------------------------------- /src/pages/006.vue: -------------------------------------------------------------------------------- 1 | 212 | 213 | 222 | 223 | 226 | -------------------------------------------------------------------------------- /src/pages/032.vue: -------------------------------------------------------------------------------- 1 | 176 | 177 | 213 | 214 | 221 | -------------------------------------------------------------------------------- /src/pages/004.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 73 | -------------------------------------------------------------------------------- /public/037.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/005.vue: -------------------------------------------------------------------------------- 1 | 232 | 233 | 272 | 273 | 282 | --------------------------------------------------------------------------------