├── .gitignore ├── README.md ├── astro ├── .gitignore ├── .prettierrc ├── .vscode │ ├── extensions.json │ └── launch.json ├── README.md ├── astro.config.mjs ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── public │ ├── favicon.svg │ └── fonts │ │ ├── Sohne-Buch-webh.woff │ │ └── Sohne-Buch-webh.woff2 ├── src │ ├── components │ │ ├── Canvas.astro │ │ ├── Fonts.astro │ │ ├── Meta.astro │ │ ├── Section.astro │ │ ├── content.js │ │ └── svg │ │ │ └── Svg.astro │ ├── env.d.ts │ ├── js │ │ └── app.js │ ├── layouts │ │ └── PageLayout.astro │ ├── pages │ │ ├── 404.astro │ │ └── index.astro │ └── style │ │ └── main.css ├── tailwind.config.cjs └── tsconfig.json ├── changelog.md ├── gists ├── cookies.md ├── css.md ├── glsl.md ├── pbr.glsl.md ├── promiseWrap.md ├── threejs.md └── viewport.md ├── package.json ├── pnpm-lock.yaml ├── sanity ├── .eslintrc ├── .gitignore ├── .prettierrc ├── README.md ├── _ │ ├── astro │ │ ├── Image.astro │ │ └── Text.astro │ ├── deref.js │ ├── index.js │ └── sanity-util.js ├── components │ ├── LinkTypeSelect.jsx │ ├── LockedArray.tsx │ ├── index.js │ └── lockedArray.module.sass ├── desk │ └── structure.ts ├── package.json ├── plop │ └── sanitySlice.hbs ├── plopfile.js ├── pnpm-lock.yaml ├── sanity.cli.ts ├── sanity.config.ts ├── schemas │ ├── blocks │ │ ├── blockContent.js │ │ ├── emphasizedHeading.js │ │ ├── externalLink.js │ │ ├── form │ │ │ ├── input.js │ │ │ └── textarea.js │ │ ├── imageAlt.js │ │ ├── imageCaption.js │ │ ├── index.js │ │ ├── internalLink.js │ │ └── normalText.js │ ├── index.ts │ ├── pages │ │ ├── _pageDefaults.js │ │ ├── createPage.ts │ │ ├── error.ts │ │ ├── home.ts │ │ ├── index.ts │ │ ├── legal.ts │ │ └── project.ts │ ├── settings │ │ ├── cookies.ts │ │ ├── footer.ts │ │ ├── form.ts │ │ ├── header.ts │ │ ├── index.ts │ │ ├── lists.ts │ │ └── seo.ts │ ├── slices │ │ ├── _ │ │ │ ├── hero.ts │ │ │ └── media.ts │ │ └── index.ts │ └── types │ │ └── index.ts ├── static │ └── .gitkeep ├── theme │ └── Logo.tsx ├── tsconfig.json └── utils │ ├── client.js │ ├── create.ts │ └── preview.ts ├── todo.md ├── tooling └── watch-asset │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── index.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── public │ └── 001.webp │ └── tsconfig.json ├── turbo ├── .eslintrc.js ├── .gitignore ├── .vscode │ └── settings.json ├── README.md ├── gitignore ├── package.json ├── packages │ ├── eslint-config │ │ ├── README.md │ │ ├── library.js │ │ ├── next.js │ │ ├── package.json │ │ └── react-internal.js │ ├── typescript-config │ │ ├── base.json │ │ ├── nextjs.json │ │ ├── package.json │ │ └── react-library.json │ └── ui │ │ ├── .eslintrc.js │ │ ├── package.json │ │ ├── src │ │ ├── button.tsx │ │ ├── card.tsx │ │ └── code.tsx │ │ ├── tsconfig.json │ │ ├── tsconfig.lint.json │ │ └── turbo │ │ └── generators │ │ ├── config.ts │ │ └── templates │ │ └── component.hbs ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tsconfig.json └── turbo.json ├── utils ├── .gitignore ├── .parcelrc ├── agents.js ├── easings.js ├── esbuild.config.js └── math.js ├── vite ├── .gitignore ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ └── index.js │ ├── gsap.js │ ├── hey.js │ ├── modules │ │ ├── animation │ │ │ ├── alpha.js │ │ │ └── text.js │ │ ├── ctrl.js │ │ ├── dom.js │ │ ├── pages.js │ │ ├── scroll.js │ │ └── viewport.js │ ├── style │ │ ├── anim.css │ │ └── main.css │ └── util │ │ ├── clientRect.js │ │ ├── easings.js │ │ ├── gui.js │ │ ├── index.js │ │ ├── math.js │ │ ├── observe.js │ │ ├── track.js │ │ └── tween.js ├── tsconfig.json.bak └── vite.config.js ├── webflow ├── full │ ├── .gitignore │ ├── README.md │ ├── bin │ │ ├── build.js │ │ └── live-reload.js │ ├── package.json │ └── src │ │ └── index.ts └── tiny │ ├── README.md │ ├── dist │ ├── app.js │ ├── app.js.map │ └── styles │ │ ├── main.css │ │ ├── main.css.map │ │ ├── out.css │ │ └── out.css.map │ ├── esbuild.config.js │ ├── package.json │ ├── pnpm-lock.yaml │ └── src │ ├── app.js │ └── styles │ ├── lenis.css │ ├── main.css │ ├── out.css │ └── variables.css └── webgl ├── chunk ├── imageuv.glsl ├── perlin3d.glsl ├── rand.glsl └── rotate3d.glsl ├── ogl ├── .gitignore ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ ├── index.js │ │ ├── uvH.jpg │ │ └── uvV.jpg │ ├── gl │ │ ├── _dquad.js │ │ ├── _group.js │ │ ├── _instance.js │ │ ├── _model.js │ │ ├── _quad.js │ │ ├── _scene.js │ │ ├── _screen.js │ │ ├── camera.js │ │ ├── gl.js │ │ ├── mat │ │ │ ├── _insta │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── _model │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── _quad │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ └── _screen │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ ├── post │ │ │ ├── mat │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── post.js │ │ │ └── quad.js │ │ └── util │ │ │ ├── domitem.js │ │ │ ├── loader.js │ │ │ ├── model-loader.js │ │ │ └── texture-loader.js │ ├── modules │ │ ├── dom.js │ │ ├── gui.js │ │ ├── lenis.js │ │ ├── pages.js │ │ └── viewport.js │ ├── style │ │ └── main.css │ └── util │ │ ├── math.js │ │ ├── observe.js │ │ └── track.js └── vite.config.js ├── three-new ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ ├── index.js │ │ ├── uvH.jpg │ │ └── uvV.jpg │ ├── gl │ │ ├── gl.js │ │ ├── glsl │ │ │ ├── _ │ │ │ │ └── basic │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ ├── constants.glsl │ │ │ ├── imageuv.glsl │ │ │ ├── perlin3d.glsl │ │ │ ├── rand.glsl │ │ │ └── rotate3d.glsl │ │ ├── instance │ │ │ ├── fragment.frag │ │ │ ├── index.js │ │ │ ├── utils.js │ │ │ └── vertex.vert │ │ ├── post │ │ │ ├── base │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ └── index.js │ │ ├── quad │ │ │ ├── fragment.frag │ │ │ ├── index.js │ │ │ └── vertex.vert │ │ ├── ray.js │ │ ├── scenes │ │ │ └── scene.js │ │ └── utils │ │ │ ├── cube-loader.js │ │ │ ├── draco-loader.js │ │ │ ├── index.js │ │ │ ├── loader.js │ │ │ ├── model-loader.js │ │ │ └── texture-loader.js │ ├── gsap.js │ ├── gui.js │ └── utils │ │ └── math.js ├── style.css └── vite.config.js ├── three-v2 ├── .gitignore ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ ├── index.js │ │ ├── uvH.jpg │ │ └── uvV.jpg │ ├── gl │ │ ├── _instance.js │ │ ├── _quad.js │ │ ├── gl.js │ │ ├── mat │ │ │ ├── basic │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── chunk │ │ │ │ ├── imageuv.glsl │ │ │ │ ├── perlin3d.glsl │ │ │ │ ├── rand.glsl │ │ │ │ └── rotate3d.glsl │ │ │ ├── instance-raw │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── post │ │ │ │ └── base │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ └── raw │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ ├── post.js │ │ ├── scene.js │ │ └── util │ │ │ ├── cube-loader.js │ │ │ ├── draco-loader.js │ │ │ ├── loader.js │ │ │ ├── model-loader.js │ │ │ └── texture-loader.js │ ├── modules │ │ ├── dom.js │ │ ├── gui.js │ │ ├── lenis.js │ │ ├── pages.js │ │ └── viewport.js │ ├── style │ │ └── main.css │ └── util │ │ └── math.js └── vite.config.js ├── three ├── .gitignore ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ ├── index.js │ │ ├── uvH.jpg │ │ └── uvV.jpg │ ├── gl │ │ ├── _instance.js │ │ ├── _quad.js │ │ ├── gl.js │ │ ├── mat │ │ │ ├── basic │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── chunk │ │ │ │ ├── imageuv.glsl │ │ │ │ ├── perlin3d.glsl │ │ │ │ ├── rand.glsl │ │ │ │ └── rotate3d.glsl │ │ │ ├── instance-raw │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── post │ │ │ │ └── base │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ └── raw │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ ├── post.js │ │ ├── scene.js │ │ └── util │ │ │ ├── cube-loader.js │ │ │ ├── draco-loader.js │ │ │ ├── loader.js │ │ │ ├── model-loader.js │ │ │ └── texture-loader.js │ ├── modules │ │ ├── dom.js │ │ ├── gui.js │ │ ├── lenis.js │ │ ├── pages.js │ │ └── viewport.js │ ├── style │ │ └── main.css │ └── util │ │ └── math.js └── vite.config.js ├── twgl ├── index.html ├── package.json ├── package.json.bak ├── pnpm-lock.yaml ├── src │ ├── app.js │ ├── assets │ │ └── index.js │ ├── gl │ │ ├── _ │ │ │ ├── _fs-quad.js │ │ │ ├── _instance.js │ │ │ └── _model.js │ │ ├── _camera.js │ │ ├── _quad.js │ │ ├── gl.js │ │ ├── mat │ │ │ ├── _ │ │ │ │ ├── fsq │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ │ ├── instanced │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ │ └── model │ │ │ │ │ ├── fragment.frag │ │ │ │ │ ├── index.js │ │ │ │ │ └── vertex.vert │ │ │ ├── chunk │ │ │ │ ├── imageuv.glsl │ │ │ │ ├── perlin3d.glsl │ │ │ │ ├── rand.glsl │ │ │ │ └── rotate3d.glsl │ │ │ └── quad │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ ├── post │ │ │ ├── mat │ │ │ │ ├── fragment.frag │ │ │ │ ├── index.js │ │ │ │ └── vertex.vert │ │ │ ├── post.js │ │ │ └── quad.js │ │ ├── scene.js │ │ └── util │ │ │ ├── gltf-loader.js │ │ │ └── spinner.js │ ├── gui.js │ ├── styles │ │ ├── main.css │ │ └── project.css │ └── utils │ │ ├── math.js │ │ ├── media.js │ │ └── texture-loader.js └── vite.config.js ├── util ├── slider.js └── spinner.js └── vanilla ├── esbuild.config.js ├── index.html ├── package-lock.json ├── package.json ├── src ├── app.js ├── assets │ ├── 3d │ │ ├── par.glb │ │ └── par1.glb │ ├── imgs │ │ ├── uvH.jpg │ │ └── uvV.jpg │ ├── index.js │ └── notes.md ├── flightsheet.md ├── modules │ ├── gl.js │ ├── gl │ │ ├── mat │ │ │ ├── cam │ │ │ │ ├── fragment.frag │ │ │ │ ├── m.js │ │ │ │ └── vertex.vert │ │ │ ├── fsq │ │ │ │ ├── fragment.frag │ │ │ │ ├── m.js │ │ │ │ └── vertex.vert │ │ │ ├── instanced │ │ │ │ ├── fragment.frag │ │ │ │ ├── m.js │ │ │ │ └── vertex.vert │ │ │ └── model │ │ │ │ ├── fragment.frag │ │ │ │ ├── m.js │ │ │ │ └── vertex.vert │ │ ├── mod │ │ │ ├── fs-quad.js │ │ │ ├── instance.js │ │ │ ├── model.js │ │ │ └── plane.js │ │ └── utils │ │ │ ├── camera.js │ │ │ ├── gltf-loader.js │ │ │ └── spinner.js │ └── utils │ │ ├── math.js │ │ └── media.js └── styles │ ├── main.css │ └── project.css └── todo.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .npmrc 4 | .DS_Store -------------------------------------------------------------------------------- /astro/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | .output/ 4 | 5 | # dependencies 6 | node_modules/ 7 | 8 | # logs 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | pnpm-debug.log* 13 | 14 | 15 | # environment variables 16 | .env 17 | .env.production 18 | 19 | # macOS-specific files 20 | .DS_Store 21 | -------------------------------------------------------------------------------- /astro/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "tabWidth": 2, 4 | "singleQuote": false, 5 | "jsxSingleQuote": false, 6 | "bracketSpacing": true, 7 | "endOfLine": "lf", 8 | "trailingComma": "es5", 9 | "arrowParens": "avoid", 10 | "plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"] 11 | } 12 | -------------------------------------------------------------------------------- /astro/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /astro/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /astro/README.md: -------------------------------------------------------------------------------- 1 | # Astro BP 2 | 3 | Astro <3 boilerplate for creative thigy 4 | 5 | #### Updates 6 | 7 | - [ ] To Add 8 | 9 | 10 | ### Use w/ Sanity 11 | 12 | scripts 13 | ```json 14 | "cms": "cd cms && pnpm dev", 15 | "all": "concurrently \"pnpm cms\" \"pnpm dev\"", 16 | "sd": "cd cms && pnpm sanity deploy" 17 | ``` 18 | 19 | devdependencies 20 | ```json 21 | "astro-portabletext": "^0.9.1", 22 | "astro-sanity": "^1.1.7", 23 | "concurrently": "^8.2.0", 24 | "@sanity/client": "^6.1.7", 25 | ``` -------------------------------------------------------------------------------- /astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "astro/config"; 2 | import tailwind from "@astrojs/tailwind"; 3 | // import glsl from "vite-plugin-glsl"; 4 | 5 | const plugins = [ 6 | // glsl({ 7 | // include: [ 8 | // // Glob pattern, or array of glob patterns to import 9 | // "**/*.glsl", 10 | // // "**/*.wgsl", 11 | // "**/*.vert", 12 | // "**/*.frag", 13 | // // "**/*.vs", 14 | // // "**/*.fs", 15 | // ], 16 | // exclude: undefined, // Glob pattern, or array of glob patterns to ignore 17 | // warnDuplicatedImports: true, // Warn if the same chunk was imported multiple times 18 | // defaultExtension: "glsl", // Shader suffix when no extension is specified 19 | // compress: false, // Compress output shader code 20 | // watch: false, // Recompile shader on change 21 | // root: "/", // Directory for root imports 22 | // }), 23 | ]; 24 | 25 | export default defineConfig({ 26 | integrations: [tailwind()], 27 | vite: { 28 | // plugins, 29 | assetsInclude: ["**/*.webp", "**/*.glb"], 30 | }, 31 | }); 32 | 33 | // https://astro.build/config 34 | -------------------------------------------------------------------------------- /astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@example/basics", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "devDependencies": { 13 | "@astrojs/tailwind": "3.1.2", 14 | "astro": "2.4.3", 15 | "prettier": "^3.0.0", 16 | "prettier-plugin-astro": "^0.11.0", 17 | "prettier-plugin-tailwindcss": "^0.4.1" 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /astro/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /astro/public/fonts/Sohne-Buch-webh.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/astro/public/fonts/Sohne-Buch-webh.woff -------------------------------------------------------------------------------- /astro/public/fonts/Sohne-Buch-webh.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/astro/public/fonts/Sohne-Buch-webh.woff2 -------------------------------------------------------------------------------- /astro/src/components/Canvas.astro: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 5 |
6 | 9 | -------------------------------------------------------------------------------- /astro/src/components/Fonts.astro: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /astro/src/components/Meta.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { title, imageUrl, description, keyworks } = Astro.props; 3 | const def = { 4 | description: "... Description", 5 | keywords: "... Keywords", 6 | imageUrl: "/util/...", 7 | }; 8 | --- 9 | 10 | 11 | {title} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /astro/src/components/Section.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { cn } = Astro.props; 3 | const classes = cn ? "py-gy" + " " + cn : "py-gy"; 4 | --- 5 | 6 |
7 | 8 |
9 | -------------------------------------------------------------------------------- /astro/src/components/content.js: -------------------------------------------------------------------------------- 1 | /* --- Data */ 2 | export const content = { 3 | links: [], 4 | }; 5 | 6 | /* --- Dynamic Pages */ 7 | export async function getPages() { 8 | const pages = import.meta.glob("../pages/work/*.md"); 9 | const pageArray = []; 10 | 11 | for (const path in pages) { 12 | pageArray.push(await pages[path]()); 13 | } 14 | 15 | // pageArray.sort((a, b ) => Date.parse(b.frontmatter.date) - Date.parse(a.frontmatter.date)) 16 | 17 | return pageArray; 18 | } 19 | -------------------------------------------------------------------------------- /astro/src/components/svg/Svg.astro: -------------------------------------------------------------------------------- 1 | --- 2 | let { size } = Astro.props.props; 3 | if (size === undefined) size = "w-[5rem]"; 4 | 5 | const style = ` 6 | aspect-square 7 | ${size} 8 | `; 9 | --- 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /astro/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /astro/src/js/app.js: -------------------------------------------------------------------------------- 1 | console.log("App script"); 2 | -------------------------------------------------------------------------------- /astro/src/layouts/PageLayout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import "../style/main.css"; 3 | 4 | const { title } = Astro.props; 5 | 6 | import Canvas from "../components/Canvas.astro"; 7 | import Meta from "src/components/Meta.astro"; 8 | import Fonts from "src/components/Fonts.astro"; 9 | --- 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /astro/src/pages/404.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/PageLayout.astro"; 3 | import Section from "../components/Section.astro"; 4 | --- 5 | 6 | 7 |
8 |
404
9 |
10 |
11 | -------------------------------------------------------------------------------- /astro/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/PageLayout.astro"; 3 | import Section from "../components/Section.astro"; 4 | --- 5 | 6 | 7 |
8 |
index
9 |
10 |
11 | -------------------------------------------------------------------------------- /astro/src/style/main.css: -------------------------------------------------------------------------------- 1 | /* ------------------------------ Utils */ 2 | 3 | html, 4 | body { 5 | overscroll-behavior: none; 6 | /* touch-action: none; */ 7 | } 8 | 9 | html, 10 | body, 11 | p, 12 | h1, 13 | h2, 14 | h3, 15 | h4 { 16 | user-select: none; /* supported by Chrome and Opera */ 17 | -webkit-user-select: none; /* Safari */ 18 | -khtml-user-select: none; /* Konqueror HTML */ 19 | -moz-user-select: none; /* Firefox */ 20 | -ms-user-select: none; /* Internet Explorer/Edge */ 21 | } 22 | 23 | [data-selectable] { 24 | user-select: text; 25 | -webkit-user-select: text; 26 | -khtml-user-select: text; 27 | -moz-user-select: text; 28 | -ms-user-select: text; 29 | } 30 | 31 | /* ------------------------------ Webgl */ 32 | [data-gl="c"] { 33 | position: fixed; 34 | box-sizing: border-box; 35 | 36 | top: 0px; 37 | left: 0px; 38 | width: 100vw; 39 | height: 100vh; 40 | 41 | z-index: -10; 42 | pointer-events: none; 43 | /* background: blue; */ 44 | } 45 | 46 | canvas { 47 | width: 100%; 48 | height: 100%; 49 | border: 1px solid blue; 50 | } 51 | 52 | /* ------------------------------ Layout */ 53 | 54 | main { 55 | min-height: 100vh; 56 | } 57 | /* ------------------------------ ... */ 58 | -------------------------------------------------------------------------------- /astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/base", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@c/*": ["src/components/*"], 7 | "@js/*": ["src/js/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /gists/cookies.md: -------------------------------------------------------------------------------- 1 | # Cookie Ops 2 | 3 | #### 100vh Viewport Height variable set 4 | 5 | ```js 6 | export function getCookie(cname) { 7 | let name = cname + "="; 8 | let decodedCookie = decodeURIComponent(document.cookie); 9 | let ca = decodedCookie.split(";"); 10 | for (let i = 0; i < ca.length; i++) { 11 | let c = ca[i]; 12 | while (c.charAt(0) == " ") { 13 | c = c.substring(1); 14 | } 15 | if (c.indexOf(name) == 0) { 16 | return c.substring(name.length, c.length); 17 | } 18 | } 19 | return ""; 20 | } 21 | 22 | export function handleCookie(name = "NAME", value = "VALUE") { 23 | // const cname = "COOKIE NAME"; 24 | // const cval = "COOKIE VALUE"; 25 | 26 | const vcookie = getCookie(cname); 27 | 28 | if (vcookie) { 29 | return false; 30 | } else { 31 | const exdays = 1; 32 | 33 | const d = new Date(); 34 | d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); 35 | let expires = "expires=" + d.toUTCString(); 36 | 37 | document.cookie = cname + "=" + cval + ";" + expires; 38 | 39 | return true; 40 | } 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /gists/css.md: -------------------------------------------------------------------------------- 1 | # CSS Snippets 2 | 3 | ## Body/Root/\* 4 | 5 | #### HTML & Body Fill 6 | 7 | ```css 8 | :where(:root) { 9 | display: grid; 10 | min-height: 100%; 11 | } 12 | ``` 13 | -------------------------------------------------------------------------------- /gists/promiseWrap.md: -------------------------------------------------------------------------------- 1 | # Wrap Promise.all w/ callbacks 2 | 3 | ```js 4 | export function allProgress(proms, progress_cb) { 5 | let d = 0; 6 | progress_cb(0); 7 | for (const p of proms) { 8 | p.then(() => { 9 | d++; 10 | progress_cb((d * 100) / proms.length); 11 | }); 12 | } 13 | return Promise.all(proms); 14 | } 15 | 16 | function test(ms) { 17 | return new Promise((resolve) => { 18 | setTimeout(() => { 19 | console.log(`Waited ${ms}`); 20 | resolve("somedata"); 21 | }, ms); 22 | }); 23 | } 24 | 25 | function progressCallback(p) { 26 | console.log(`${p.toFixed(0)} %`); 27 | } 28 | 29 | async function init() { 30 | const [data1, data2, data3, data4] = await allProgress( 31 | [test(1000), test(3000), test(2000), test(3500)], 32 | progressCallback 33 | ); 34 | 35 | console.log(data1, data2, data3, data4); 36 | } 37 | 38 | init(); 39 | ``` 40 | -------------------------------------------------------------------------------- /gists/threejs.md: -------------------------------------------------------------------------------- 1 | # THREEjs 2 | 3 | ## Shaders 4 | 5 | #### Skinned Shader 6 | 7 | ```csharp 8 | // (VERTEX) 9 | 10 | // #include 11 | #include 12 | 13 | void main() { 14 | // #include 15 | #include 16 | 17 | 18 | vec4 tr = modelViewMatrix * vec4(position, 1.0); 19 | // gl_Position = projectionMatrix * tr; 20 | vUv = uv; 21 | 22 | #include 23 | // #include 24 | #include 25 | #include 26 | #include 27 | 28 | } 29 | 30 | // might want to add (up top) 31 | // #include 32 | // #include 33 | // #include 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /gists/viewport.md: -------------------------------------------------------------------------------- 1 | # Viewport Utils 2 | 3 | ## CSS 4 | 5 | #### 100vh Viewport Height variable set 6 | 7 | ```js 8 | document.documentElement.style.setProperty( 9 | "--100vh", 10 | `${window.innerHeight}px` 11 | ); 12 | ``` 13 | 14 | #### Set VH unit (constantly) 15 | 16 | ```js 17 | ["DOMContentLoaded", "resize"].forEach((event) => { 18 | window.addEventListener(event, (_) => { 19 | const vh = window.innerHeight * 0.01; 20 | document.documentElement.style.setProperty("--vh", `${vh}px`); 21 | }); 22 | }); 23 | ``` 24 | 25 | #### Detect Browser window / tab state 26 | 27 | ```js 28 | document.addEventListener("visibilitychange", () => { 29 | if (document.hidden) { 30 | console.log("hidden"); 31 | } else { 32 | console.log("visible"); 33 | } 34 | }); 35 | 36 | window.addEventListener("focus", () => { 37 | console.log("focus"); 38 | }); 39 | 40 | window.addEventListener("blur", () => { 41 | console.log("blur"); 42 | }); 43 | ``` 44 | 45 | ```js 46 | export function viewportUnits() { 47 | document.documentElement.style.setProperty( 48 | "--vw", 49 | document.documentElement.clientWidth * 0.01 + "px" 50 | ); 51 | 52 | document.documentElement.style.setProperty( 53 | "--dvh", 54 | window.innerHeight * 0.01 + "px" 55 | ); 56 | 57 | document.documentElement.style.setProperty( 58 | "--svh", 59 | document.documentElement.clientHeight * 0.01 + "px" 60 | ); 61 | 62 | document.documentElement.style.setProperty("--lvh", "1vh"); 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starters", 3 | "version": "1.0.0", 4 | "description": "mixed scaffolds and boilerplate code", 5 | "main": "index.js", 6 | "author": "vallafederico", 7 | "license": "MIT", 8 | "scripts": { 9 | "vite": "cd vite && pnpm dev" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: {} 10 | -------------------------------------------------------------------------------- /sanity/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@sanity/eslint-config-studio" 3 | } 4 | -------------------------------------------------------------------------------- /sanity/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # Compiled Sanity Studio 9 | /dist 10 | 11 | # Temporary Sanity runtime, generated by the CLI on every dev server start 12 | /.sanity 13 | 14 | # Logs 15 | /logs 16 | *.log 17 | 18 | # Coverage directory used by testing tools 19 | /coverage 20 | 21 | # Misc 22 | .DS_Store 23 | *.pem 24 | 25 | # Typescript 26 | *.tsbuildinfo 27 | 28 | # Dotenv and similar local-only files 29 | *.local 30 | -------------------------------------------------------------------------------- /sanity/.prettierrc: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /sanity/README.md: -------------------------------------------------------------------------------- 1 | # Sanity Clean Content Studio 2 | 3 | ## Secrets 4 | 5 | ```js 6 | export default defineCliConfig({ 7 | api: { 8 | projectId: process.env.SANITY_STUDIO_ID, 9 | dataset: 'production', 10 | }, 11 | }) 12 | ``` 13 | 14 | ### .env 15 | ```md 16 | SANITY_STUDIO_ID="..." 17 | ``` 18 | -------------------------------------------------------------------------------- /sanity/_/astro/Text.astro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/sanity/_/astro/Text.astro -------------------------------------------------------------------------------- /sanity/_/index.js: -------------------------------------------------------------------------------- 1 | import {urlFor} from './sanity-util.js' 2 | import {sanityClient} from 'sanity:client' 3 | // import { resolveLinks } from "./deref.js" 4 | 5 | export {urlFor} 6 | 7 | // export async function getRef(ref) { 8 | // const query = groq`*[_id == '${ref}']` 9 | // const data = await useSanityClient().fetch(query) 10 | // return data 11 | // } 12 | 13 | export async function getType(type) { 14 | const query = `*[_type == "${type}"]` 15 | const data = await sanityClient.fetch(query) 16 | 17 | // .then(async data => { 18 | // await resolveLinks(data) 19 | // return data 20 | // }) 21 | 22 | return data 23 | } 24 | 25 | /** -- -- Astro */ 26 | export async function getPages(name) { 27 | const data = await getType(name) 28 | 29 | return data.map((d) => { 30 | return { 31 | params: {card: d.slug.current}, 32 | props: d, 33 | } 34 | }) 35 | } 36 | 37 | /** 38 | * /[...smth].astro 39 | */ 40 | 41 | export async function getStaticPaths(name) { 42 | const data = await getPages(name) 43 | // data.forEach((item, i) => { 44 | // // console.log(item) 45 | // if (i === 9) { 46 | // item.props.next = data[0].props; 47 | // } else { 48 | // item.props.next = data[i + 1].props; 49 | // } 50 | // }); 51 | 52 | return data 53 | } 54 | 55 | // const { smth } = Astro.params; 56 | // const { ... } = Astro.props; 57 | -------------------------------------------------------------------------------- /sanity/_/sanity-util.js: -------------------------------------------------------------------------------- 1 | import imageUrlBuilder from '@sanity/image-url' 2 | import {sanityClient} from 'sanity:client' 3 | 4 | // imageBuilder 5 | export const imageBuilder = imageUrlBuilder(sanityClient) 6 | 7 | /* ---- Sanity Image Builder ---- 8 | .size(w | 0, (h / aspectRatio) | 0) 9 | .fit('crop') 10 | .auto('format') // -> converts to webp 11 | .quality(77) 12 | .url() 13 | */ 14 | 15 | export function urlFor(source, {url = false, quality = 50, width = 720} = {}) { 16 | const img = imageBuilder.image(source).auto('format').quality(quality).width(width) 17 | 18 | if (url) return img.url() 19 | return img 20 | } 21 | -------------------------------------------------------------------------------- /sanity/components/index.js: -------------------------------------------------------------------------------- 1 | const components = [] 2 | 3 | export default components 4 | -------------------------------------------------------------------------------- /sanity/components/lockedArray.module.sass: -------------------------------------------------------------------------------- 1 | .locked 2 | :global 3 | .sc-kcuKUB 4 | button[aria-haspopup=true] 5 | display: none -------------------------------------------------------------------------------- /sanity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sofia-papadopoulou", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "main": "package.json", 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "dev": "sanity dev", 10 | "start": "sanity start", 11 | "build": "sanity build", 12 | "deploy": "sanity deploy", 13 | "deploy-graphql": "sanity graphql deploy" 14 | }, 15 | "keywords": [ 16 | "sanity" 17 | ], 18 | "dependencies": { 19 | "@sanity/vision": "^3.24.1", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "react-icons": "^5.0.1", 23 | "react-is": "^18.2.0", 24 | "sanity": "^3.24.1", 25 | "sanity-plugin-prefixed-slug": "^2.0.0", 26 | "sanity-plugin-vercel-deploy": "^3.3.4", 27 | "sass": "^1.69.7", 28 | "styled-components": "^6.1.8" 29 | }, 30 | "devDependencies": { 31 | "@sanity/eslint-config-studio": "^3.0.1", 32 | "@types/react": "^18.2.48", 33 | "@types/styled-components": "^5.1.34", 34 | "eslint": "^8.56.0", 35 | "plop": "^4.0.1", 36 | "prettier": "^3.2.2", 37 | "typescript": "^5.3.3" 38 | }, 39 | "prettier": { 40 | "semi": false, 41 | "printWidth": 100, 42 | "bracketSpacing": false, 43 | "singleQuote": true 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sanity/plop/sanitySlice.hbs: -------------------------------------------------------------------------------- 1 | export default { 2 | name: '{{camelCase name}}', 3 | icon: null, 4 | type: 'object', 5 | fields:[], 6 | preview: { 7 | prepare() { 8 | return { 9 | title: '{{titleCase name}}', 10 | icon: null, 11 | } 12 | }, 13 | }, 14 | } -------------------------------------------------------------------------------- /sanity/sanity.cli.ts: -------------------------------------------------------------------------------- 1 | import {defineCliConfig} from 'sanity/cli' 2 | 3 | export default defineCliConfig({ 4 | api: { 5 | projectId: process.env.SANITY_STUDIO_ID, 6 | dataset: 'production', 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /sanity/sanity.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'sanity' 2 | import {deskTool} from 'sanity/desk' 3 | import {visionTool} from '@sanity/vision' 4 | import {structure} from './desk/structure' 5 | import {schemaTypes} from './schemas' 6 | import {vercelDeployTool} from 'sanity-plugin-vercel-deploy' 7 | 8 | export default defineConfig({ 9 | name: 'default', 10 | title: '👀', 11 | projectId: process.env.SANITY_STUDIO_ID, 12 | dataset: 'production', 13 | 14 | plugins: [deskTool({structure}), visionTool(), vercelDeployTool()], 15 | 16 | schema: { 17 | types: schemaTypes, 18 | }, 19 | }) 20 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/blockContent.js: -------------------------------------------------------------------------------- 1 | // Rich Text field with code tags and H1 removed 2 | 3 | export default { 4 | name: 'blockContent', 5 | title: 'Content', 6 | type: 'array', 7 | of: [ 8 | { 9 | type: 'block', 10 | styles: [ 11 | {title: 'Normal', value: 'normal'}, 12 | // {title: 'H1', value: 'h1'}, 13 | {title: 'Heading', value: 'h2'}, 14 | {title: 'Subhead', value: 'h3'}, 15 | {title: 'Microhead', value: 'h4'}, 16 | ], 17 | lists: [ 18 | {title: '', value: 'bullet'}, 19 | {title: '', value: 'number'}, 20 | ], 21 | marks: { 22 | decorators: [ 23 | { 24 | title: 'Italics', 25 | value: 'em', 26 | }, 27 | { 28 | title: 'Bold', 29 | value: 'strong', 30 | }, 31 | ], 32 | }, 33 | }, 34 | ], 35 | } 36 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/emphasizedHeading.js: -------------------------------------------------------------------------------- 1 | // Only supports normal text and emphasis for b 2 | 3 | export default { 4 | name: 'emphasizedHeading', 5 | title: 'Content', 6 | type: 'array', 7 | of: [ 8 | { 9 | type: 'block', 10 | styles: [ 11 | {title: 'Normal', value: 'normal'}, 12 | // {title: 'Heading 2', value: 'h2'}, 13 | // {title: 'Heading 3', value: 'h3'}, 14 | // {title: 'Heading 4', value: 'h4'}, 15 | // {title: 'Heading 5', value: 'h5'}, 16 | // {title: 'Heading 6', value: 'h6'}, 17 | ], 18 | lists: [], 19 | marks: { 20 | decorators: [ 21 | { 22 | title: 'Italics', 23 | value: 'em', 24 | }, 25 | // { 26 | // title: 'Bold', 27 | // value: 'strong', 28 | // }, 29 | ], 30 | }, 31 | }, 32 | ], 33 | } 34 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/externalLink.js: -------------------------------------------------------------------------------- 1 | import {BiLinkExternal} from 'react-icons/bi' 2 | 3 | export default { 4 | name: 'externalLink', 5 | type: 'object', 6 | icon: BiLinkExternal, 7 | preview: { 8 | select: { 9 | title: 'label', 10 | subtitle: 'url', 11 | }, 12 | prepare(selection) { 13 | const {title, subtitle} = selection 14 | return { 15 | title, 16 | subtitle, 17 | } 18 | }, 19 | }, 20 | fields: [ 21 | { 22 | name: 'label', 23 | type: 'string', 24 | }, 25 | { 26 | name: 'url', 27 | type: 'url', 28 | title: 'URL', 29 | validation: (Rule) => Rule.required(), 30 | description: 'Must begin with https://', 31 | }, 32 | ], 33 | } 34 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/form/input.js: -------------------------------------------------------------------------------- 1 | import {BsInputCursorText} from 'react-icons/bs' 2 | 3 | export default { 4 | name: 'input', 5 | title: 'Short Text Field', 6 | icon: BsInputCursorText, 7 | type: 'object', 8 | fieldsets: [ 9 | { 10 | name: 'form', 11 | options: {columns: 2}, 12 | }, 13 | ], 14 | fields: [ 15 | { 16 | name: 'label', 17 | fieldset: 'form', 18 | type: 'string', 19 | title: 'Field Label', 20 | }, 21 | { 22 | name: 'placeholder', 23 | type: 'string', 24 | fieldset: 'form', 25 | title: 'Field Placeholder', 26 | description: 27 | 'Placed inside the field before a user has typed anything, a helpful hint for the format or expected value. Defaults to the field label above.', 28 | }, 29 | { 30 | name: 'validation', 31 | type: 'string', 32 | descripton: 'Optional. What is the user expected to type?', 33 | options: { 34 | list: [ 35 | { 36 | title: 'Email', 37 | value: 'email', 38 | }, 39 | { 40 | title: 'Location', 41 | value: 'location', 42 | }, 43 | { 44 | title: 'phone', 45 | value: 'Phone Number', 46 | }, 47 | ], 48 | }, 49 | }, 50 | ], 51 | } 52 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/form/textarea.js: -------------------------------------------------------------------------------- 1 | import {BsTextLeft} from 'react-icons/bs' 2 | 3 | export default { 4 | name: 'textarea', 5 | icon: BsTextLeft, 6 | title: 'Long Text Field', 7 | type: 'object', 8 | fieldsets: [ 9 | { 10 | name: 'form', 11 | options: {columns: 2}, 12 | }, 13 | ], 14 | fields: [ 15 | { 16 | name: 'label', 17 | fieldset: 'form', 18 | type: 'string', 19 | title: 'Field Label', 20 | }, 21 | { 22 | name: 'placeholder', 23 | type: 'string', 24 | fieldset: 'form', 25 | title: 'Field Placeholder', 26 | description: 27 | 'Placed inside the field before a user has typed anything, a helpful hint for the format or expected value. Defaults to the field label above.', 28 | }, 29 | ], 30 | } 31 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/imageAlt.js: -------------------------------------------------------------------------------- 1 | import {MdImage} from 'react-icons/md' 2 | 3 | export default { 4 | name: 'imageAlt', 5 | title: 'Image', 6 | icon: MdImage, 7 | type: 'object', 8 | fields: [ 9 | { 10 | name: 'image', 11 | type: 'image', 12 | options: { 13 | metadata: ['lqip'], 14 | hotspot: true, 15 | }, 16 | }, 17 | { 18 | name: 'alt', 19 | title: 'Alternative Text', 20 | type: 'string', 21 | description: 'Users with visual impairments will read this description instead of the image.', 22 | validation: (Rule) => Rule.required().error('Alternative text is required'), 23 | }, 24 | ], 25 | } 26 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/imageCaption.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'object', 3 | name: 'imageCaption', 4 | title: 'Image with Caption', 5 | fields: [ 6 | { 7 | name: 'image', 8 | type: 'imageAlt', 9 | }, 10 | { 11 | name: 'caption', 12 | type: 'string', 13 | description: 'Captions are only visible inside galleries', 14 | }, 15 | ], 16 | preview: { 17 | select: { 18 | alt: 'image.alt', 19 | caption: 'caption', 20 | media: 'image.image', 21 | }, 22 | prepare(selection) { 23 | const {media, alt, caption} = selection 24 | return { 25 | media: media, 26 | title: caption ? caption : 'No caption provided', 27 | } 28 | }, 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/index.js: -------------------------------------------------------------------------------- 1 | import normalText from './normalText' 2 | import blockContent from './blockContent' 3 | import imageAlt from './imageAlt' 4 | // import mediaSelect from './mediaSelect' 5 | import input from './form/input' 6 | import textArea from './form/textArea' 7 | 8 | import emphasizedHeading from './emphasizedHeading' 9 | import imageCaption from './imageCaption' 10 | import internalLink from './internalLink' 11 | 12 | const blocks = [ 13 | imageAlt, 14 | emphasizedHeading, 15 | internalLink, 16 | blockContent, 17 | imageCaption, 18 | // mediaSelect, 19 | normalText, 20 | input, 21 | textArea, 22 | ] 23 | 24 | export default blocks 25 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/internalLink.js: -------------------------------------------------------------------------------- 1 | import {BiLink} from 'react-icons/bi' 2 | import pages from '../pages' 3 | 4 | const allPages = [] 5 | 6 | pages.forEach((page) => { 7 | if (page && page.name) { 8 | allPages.push({type: page.name}) 9 | } 10 | }) 11 | 12 | export default { 13 | name: 'internalLink', 14 | type: 'object', 15 | icon: BiLink, 16 | fields: [ 17 | { 18 | name: 'label', 19 | type: 'string', 20 | validation: (Rule) => Rule.required(), 21 | }, 22 | { 23 | name: 'link', 24 | validation: (Rule) => Rule.required(), 25 | type: 'reference', 26 | options: { 27 | disableNew: true, 28 | }, 29 | to: [...allPages], 30 | }, 31 | ], 32 | preivew: { 33 | select: { 34 | link: 'link', 35 | title: 'label', 36 | }, 37 | prepare(selection) { 38 | const {link, title} = selection 39 | return { 40 | subtitle: link.slug.current, 41 | title, 42 | } 43 | }, 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /sanity/schemas/blocks/normalText.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'normalText', 3 | title: 'Text Block', 4 | type: 'array', 5 | of: [ 6 | { 7 | type: 'block', 8 | styles: [ 9 | {title: 'Normal', value: 'normal'}, 10 | // {title: 'H1', value: 'h1'}, 11 | // {title: 'H2', value: 'h2'}, 12 | ], 13 | }, 14 | ], 15 | } 16 | -------------------------------------------------------------------------------- /sanity/schemas/index.ts: -------------------------------------------------------------------------------- 1 | import pages from './pages' 2 | import slices from './slices' 3 | import settings from './settings' 4 | import blocks from './blocks' 5 | 6 | export const schemaTypes = [...blocks, ...slices, ...pages, ...settings] 7 | -------------------------------------------------------------------------------- /sanity/schemas/pages/error.ts: -------------------------------------------------------------------------------- 1 | import {MdError} from 'react-icons/md' 2 | import createPage from './createPage' 3 | 4 | const options = { 5 | slug: false, 6 | seo: false, 7 | slices: false, 8 | icon: MdError, 9 | body: false, 10 | fields: [ 11 | { 12 | name: 'text', 13 | type: 'string', 14 | group: 'content', 15 | }, 16 | ], 17 | } 18 | 19 | export default createPage('Error Page (404)', 'error', options) 20 | -------------------------------------------------------------------------------- /sanity/schemas/pages/home.ts: -------------------------------------------------------------------------------- 1 | import {MdHome} from 'react-icons/md' 2 | import createPage from './createPage' 3 | 4 | const options = { 5 | slices: 'homeSlices', 6 | icon: MdHome, 7 | slug: false, 8 | prefix: false, 9 | } 10 | 11 | export default createPage('Home', 'home', options) 12 | -------------------------------------------------------------------------------- /sanity/schemas/pages/index.ts: -------------------------------------------------------------------------------- 1 | import error from './error' 2 | import home from './home' 3 | import legal from './legal' 4 | import project from './project' 5 | 6 | const pages = [home, error, legal, project] 7 | 8 | export default pages 9 | -------------------------------------------------------------------------------- /sanity/schemas/pages/legal.ts: -------------------------------------------------------------------------------- 1 | import {MdGavel} from 'react-icons/md' 2 | import createPage from './createPage' 3 | 4 | const options = { 5 | // prefix: 'legal', 6 | seo: false, 7 | slug: true, 8 | fields: [ 9 | { 10 | name: 'blurb', 11 | type: 'text', 12 | rows: 3, 13 | group: 'content', 14 | description: 'Short paragraph at the top of this page, underneath the title.', 15 | }, 16 | ], 17 | icon: MdGavel, 18 | slices: false, 19 | body: true, 20 | } 21 | 22 | export default createPage('Legal Page', 'legal', options) 23 | -------------------------------------------------------------------------------- /sanity/schemas/pages/project.ts: -------------------------------------------------------------------------------- 1 | import {createPreview} from '../../utils/preview' 2 | import createPage from './createPage' 3 | import {MdPages, MdPerson} from 'react-icons/md' 4 | 5 | const options = { 6 | slices: 'pageSlices', 7 | prefix: false, 8 | slug: true, 9 | seo: true, 10 | groups: [{title: 'Project Brief', name: 'brief'}], 11 | icon: MdPages, 12 | fields: [ 13 | // { 14 | // name: 'mainImage', 15 | // type: 'imageAlt', 16 | // group: 'content', 17 | // }, 18 | ], 19 | body: false, 20 | } 21 | 22 | export default createPage('Project', 'project', options) 23 | -------------------------------------------------------------------------------- /sanity/schemas/settings/cookies.ts: -------------------------------------------------------------------------------- 1 | import {MdCookie} from 'react-icons/md' 2 | 3 | export default { 4 | name: 'settings.cookies', 5 | title: 'Cookie & Privacy Settings', 6 | icon: MdCookie, 7 | type: 'document', 8 | fields: [ 9 | { 10 | name: 'blurb', 11 | validation: (Rule) => Rule.required(), 12 | type: 'text', 13 | rows: 2, 14 | description: 15 | 'Small description of what cookies are used for on the site. Appears in the popup when a user loads the page.', 16 | }, 17 | { 18 | name: 'description', 19 | validation: (Rule) => Rule.required(), 20 | type: 'text', 21 | rows: 2, 22 | title: 'Marketing Cookies Description', 23 | description: 24 | "GDPR-Compliant description of how cookies are used when the site gathers them. Visible when a user opens 'Cookie Preferences'", 25 | }, 26 | ], 27 | } 28 | -------------------------------------------------------------------------------- /sanity/schemas/settings/footer.ts: -------------------------------------------------------------------------------- 1 | import {createPreview} from '../../utils/preview' 2 | import {IoShareSocial} from 'react-icons/io5' 3 | 4 | export default { 5 | name: 'settings.footer', 6 | title: 'Footer', 7 | type: 'object', 8 | fields: [ 9 | { 10 | name: 'socialLinks', 11 | title: 'Social Media Links', 12 | type: 'array', 13 | of: [ 14 | { 15 | type: 'object', 16 | icon: IoShareSocial, 17 | preview: createPreview('networkName', 'url'), 18 | fields: [ 19 | {name: 'networkName', type: 'string'}, 20 | {name: 'url', type: 'url', title: 'URL'}, 21 | ], 22 | }, 23 | ], 24 | }, 25 | { 26 | name: 'legalLinks', 27 | title: 'Legal Page Links', 28 | type: 'array', 29 | of: [{type: 'reference', to: [{type: 'legal'}]}], 30 | }, 31 | { 32 | name: 'cta', 33 | title: 'CTA button label', 34 | type: 'string', 35 | }, 36 | { 37 | name: 'email', 38 | type: 'string', 39 | }, 40 | ], 41 | preview: { 42 | prepare() { 43 | return { 44 | title: 'Footer', 45 | } 46 | }, 47 | }, 48 | } 49 | -------------------------------------------------------------------------------- /sanity/schemas/settings/header.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'settings.header', 3 | title: 'Header', 4 | type: 'object', 5 | fields: [ 6 | { 7 | name: 'links', 8 | title: 'Navigation Links', 9 | type: 'array', 10 | of: [ 11 | { 12 | type: 'internalLink', 13 | name: 'link', 14 | }, 15 | ], 16 | }, 17 | { 18 | name: 'cta', 19 | title: 'Call to Action Label', 20 | description: 'Label for a call to action button in the navigation.', 21 | type: 'string', 22 | }, 23 | ], 24 | preview: { 25 | prepare() { 26 | return { 27 | title: 'Header', 28 | } 29 | }, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /sanity/schemas/settings/index.ts: -------------------------------------------------------------------------------- 1 | import header from './header' 2 | import footer from './footer' 3 | import seo from './seo' 4 | import form from './form' 5 | import cookies from './cookies' 6 | 7 | const settings = [header, footer, seo, form, cookies] 8 | 9 | export default settings 10 | -------------------------------------------------------------------------------- /sanity/schemas/slices/_/hero.ts: -------------------------------------------------------------------------------- 1 | import {TbLayoutBottombar} from 'react-icons/tb' 2 | 3 | export default { 4 | name: 'hero', 5 | type: 'object', 6 | icon: TbLayoutBottombar, 7 | fields: [ 8 | { 9 | name: 'swappyWords', 10 | type: 'array', 11 | of: [{type: 'string'}], 12 | }, 13 | ], 14 | preview: { 15 | prepare() { 16 | return { 17 | title: 'Hero', 18 | icon: null, 19 | } 20 | }, 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /sanity/schemas/slices/_/media.ts: -------------------------------------------------------------------------------- 1 | import {MdPermMedia} from 'react-icons/md' 2 | 3 | export default { 4 | name: 'media', 5 | icon: MdPermMedia, 6 | type: 'object', 7 | fields: [ 8 | { 9 | name: 'media', 10 | validation: (Rule) => Rule.max(3), 11 | type: 'array', 12 | of: [ 13 | { 14 | type: 'object', 15 | fields: [ 16 | { 17 | name: 'image', 18 | type: 'imageAlt', 19 | // hidden: ({parent, value}) => parent.mediaType === 'video', 20 | options: { 21 | collapsed: false, 22 | }, 23 | }, 24 | { 25 | name: 'video', 26 | title: 'Video (optional)', 27 | type: 'url', 28 | options: { 29 | collapsed: false, 30 | }, 31 | // hidden: ({parent, value}) => parent.mediaType === 'image', 32 | }, 33 | ], 34 | }, 35 | ], 36 | }, 37 | ], 38 | preview: { 39 | prepare() { 40 | return { 41 | title: 'Media', 42 | icon: MdPermMedia, 43 | } 44 | }, 45 | }, 46 | } 47 | -------------------------------------------------------------------------------- /sanity/schemas/slices/index.ts: -------------------------------------------------------------------------------- 1 | // import hero from './hero' 2 | 3 | const sortAlpha = (a, b) => { 4 | return a.name.localeCompare(b.name) 5 | } 6 | 7 | const globalPageSlices = [ 8 | // hero, 9 | ] 10 | const contentPageSlices = [ 11 | // hero, 12 | ] 13 | const homeSlices = [ 14 | // hero, 15 | ] 16 | 17 | // Create page slices type that acts as a base for all types of slices to be dropped into 18 | const pageSlices = { 19 | name: 'pageSlices', 20 | title: 'Page slices', 21 | description: 'Each section of the page can be edited here', 22 | type: 'array', 23 | of: [...contentPageSlices.sort((a, b) => sortAlpha(a, b)).map((slice) => ({type: slice.name}))], 24 | } 25 | 26 | const homePageSlices = { 27 | name: 'homeSlices', 28 | title: 'Page Slices', 29 | description: 'Each section of the page can be edited here', 30 | type: 'array', 31 | of: [...homeSlices.sort((a, b) => sortAlpha(a, b)).map((slice) => ({type: slice.name}))], 32 | } 33 | 34 | // Create an array from all of the slice types so that sanity can iterate on them 35 | const allSlices = Array.from(new Set([...globalPageSlices])) 36 | 37 | export default [pageSlices, ...allSlices, homePageSlices] 38 | -------------------------------------------------------------------------------- /sanity/schemas/types/index.ts: -------------------------------------------------------------------------------- 1 | import {IconType} from 'react-icons' 2 | import {ObjectField} from 'sanity' 3 | 4 | export interface PageAttributes { 5 | title: string 6 | name: string 7 | options: { 8 | slug?: string 9 | icon: IconType 10 | slices?: false | 'homeSlices' | 'pageSlices' // Adds slice array to add sections in visually-based pages 11 | } 12 | prefix?: string // Add prefix to slug, i.e "/blog/..." 13 | seo?: boolean // Add SEO attributes to page 14 | 15 | body?: boolean // Adds a rich text field for text-based pages 16 | fields?: Array // Add extra fields on top of defaults 17 | } 18 | -------------------------------------------------------------------------------- /sanity/static/.gitkeep: -------------------------------------------------------------------------------- 1 | Files placed here will be served by the Sanity server under the `/static`-prefix 2 | -------------------------------------------------------------------------------- /sanity/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /sanity/utils/client.js: -------------------------------------------------------------------------------- 1 | import client from '@sanity/client' 2 | 3 | export default client({ 4 | projectId: 'r19ry25y', 5 | dataset: 'production', 6 | apiVersion: 'v2023-04-20', 7 | }) 8 | -------------------------------------------------------------------------------- /sanity/utils/create.ts: -------------------------------------------------------------------------------- 1 | // import f 2 | 3 | export const createField = (name: string, type?: string, title?: string, extra?: any) => { 4 | return { 5 | name, 6 | type, 7 | title, 8 | ...extra, 9 | } 10 | } 11 | 12 | export const createTaxo = (name: string, title: string, fields: Array, ...extra: any) => { 13 | return { 14 | name, 15 | title, 16 | type: 'document', 17 | fields: [...fields], 18 | ...extra, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sanity/utils/preview.ts: -------------------------------------------------------------------------------- 1 | export const createPreview = ( 2 | titleFieldName: string, 3 | subtitleFieldName?: string, 4 | mediaFieldName?: string 5 | ) => { 6 | // These can be undefined so this is fine 7 | const selectors = { 8 | title: titleFieldName, 9 | subtitle: subtitleFieldName, 10 | } 11 | 12 | // Media cant be undefined, so only add it to object if its defined 13 | if (mediaFieldName) { 14 | selectors.media = mediaFieldName 15 | } 16 | 17 | const preview = { 18 | select: selectors, 19 | prepare(previewParts: object) { 20 | return { 21 | ...previewParts, 22 | } 23 | }, 24 | } 25 | return preview 26 | } 27 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # Todo (eventually) 2 | 3 | - [ ] make npx for various config 4 | - [ ] move everythign to named imports 5 | 6 | ## Todo - WIP 7 | 8 | - [ ] ALL: switch to named imports and kill all defaults 9 | - [ ] webgl → to named imports 10 | - [ ] vite → to named imports 11 | -------------------------------------------------------------------------------- /tooling/watch-asset/README.md: -------------------------------------------------------------------------------- 1 | # watch-asset 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run index.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.0.0. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /tooling/watch-asset/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/tooling/watch-asset/bun.lockb -------------------------------------------------------------------------------- /tooling/watch-asset/index.ts: -------------------------------------------------------------------------------- 1 | import { watch } from "fs/promises"; 2 | import { unlink, writeFile } from "node:fs/promises"; 3 | import sharp from "sharp"; 4 | 5 | const PATH = import.meta.dir + "/public"; 6 | 7 | sharp.cache(false); 8 | 9 | const watcher = watch(PATH, { recursive: true }); 10 | for await (const event of watcher) { 11 | const { filename } = event; 12 | 13 | /* Images */ 14 | if ( 15 | filename?.includes(".jpg") || 16 | filename?.includes(".jpeg") || 17 | filename?.includes(".png") 18 | ) { 19 | let buffer = await imageToWebp(PATH + "/" + filename); 20 | await writeFile(PATH + "/" + filename.replace(".jpg", ".webp"), buffer); 21 | } 22 | } 23 | 24 | async function imageToWebp(img: string) { 25 | const buffer = await sharp(img).webp({ nearLossless: true }).toBuffer(); 26 | return buffer; 27 | } 28 | -------------------------------------------------------------------------------- /tooling/watch-asset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "watch-asset", 3 | "module": "index.ts", 4 | "type": "module", 5 | "scripts": { 6 | "build": "tsc", 7 | "dev": "bun --watch index.ts" 8 | }, 9 | "devDependencies": { 10 | "bun-types": "latest" 11 | }, 12 | "peerDependencies": { 13 | "typescript": "^5.0.0" 14 | }, 15 | "dependencies": { 16 | "sharp": "^0.33.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tooling/watch-asset/public/001.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/tooling/watch-asset/public/001.webp -------------------------------------------------------------------------------- /tooling/watch-asset/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "esnext", 5 | "target": "esnext", 6 | "moduleResolution": "bundler", 7 | "moduleDetection": "force", 8 | "allowImportingTsExtensions": true, 9 | "noEmit": true, 10 | "composite": true, 11 | "strict": true, 12 | "downlevelIteration": true, 13 | "skipLibCheck": true, 14 | "jsx": "preserve", 15 | "allowSyntheticDefaultImports": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "allowJs": true, 18 | "types": [ 19 | "bun-types" // add Bun global 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /turbo/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This configuration only applies to the package manager root. 2 | /** @type {import("eslint").Linter.Config} */ 3 | module.exports = { 4 | ignorePatterns: ["apps/**", "packages/**"], 5 | extends: ["@repo/eslint-config/library.js"], 6 | parser: "@typescript-eslint/parser", 7 | parserOptions: { 8 | project: true, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /turbo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # Local env files 9 | .env 10 | .env.local 11 | .env.development.local 12 | .env.test.local 13 | .env.production.local 14 | 15 | # Testing 16 | coverage 17 | 18 | # Turbo 19 | .turbo 20 | 21 | # Vercel 22 | .vercel 23 | 24 | # Build Outputs 25 | .next/ 26 | out/ 27 | build 28 | dist 29 | 30 | 31 | # Debug 32 | npm-debug.log* 33 | yarn-debug.log* 34 | yarn-error.log* 35 | 36 | # Misc 37 | .DS_Store 38 | *.pem 39 | -------------------------------------------------------------------------------- /turbo/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.workingDirectories": [ 3 | { 4 | "mode": "auto" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /turbo/README.md: -------------------------------------------------------------------------------- 1 | # Turborepo Starter 2 | -------------------------------------------------------------------------------- /turbo/gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /turbo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "turbo", 3 | "private": true, 4 | "scripts": { 5 | "build": "turbo build", 6 | "dev": "turbo dev", 7 | "lint": "turbo lint", 8 | "format": "prettier --write \"**/*.{ts,tsx,md}\"" 9 | }, 10 | "devDependencies": { 11 | "@repo/eslint-config": "workspace:*", 12 | "@repo/typescript-config": "workspace:*", 13 | "prettier": "^3.2.5", 14 | "turbo": "latest" 15 | }, 16 | "packageManager": "pnpm@8.9.0", 17 | "engines": { 18 | "node": ">=18" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /turbo/packages/eslint-config/README.md: -------------------------------------------------------------------------------- 1 | # `@turbo/eslint-config` 2 | 3 | Collection of internal eslint configurations. 4 | -------------------------------------------------------------------------------- /turbo/packages/eslint-config/library.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require("node:path"); 2 | 3 | const project = resolve(process.cwd(), "tsconfig.json"); 4 | 5 | /** @type {import("eslint").Linter.Config} */ 6 | module.exports = { 7 | extends: ["eslint:recommended", "prettier", "eslint-config-turbo"], 8 | plugins: ["only-warn"], 9 | globals: { 10 | React: true, 11 | JSX: true, 12 | }, 13 | env: { 14 | node: true, 15 | }, 16 | settings: { 17 | "import/resolver": { 18 | typescript: { 19 | project, 20 | }, 21 | }, 22 | }, 23 | ignorePatterns: [ 24 | // Ignore dotfiles 25 | ".*.js", 26 | "node_modules/", 27 | "dist/", 28 | ], 29 | overrides: [ 30 | { 31 | files: ["*.js?(x)", "*.ts?(x)"], 32 | }, 33 | ], 34 | }; 35 | -------------------------------------------------------------------------------- /turbo/packages/eslint-config/next.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require("node:path"); 2 | 3 | const project = resolve(process.cwd(), "tsconfig.json"); 4 | 5 | /** @type {import("eslint").Linter.Config} */ 6 | module.exports = { 7 | extends: [ 8 | "eslint:recommended", 9 | "prettier", 10 | require.resolve("@vercel/style-guide/eslint/next"), 11 | "eslint-config-turbo", 12 | ], 13 | globals: { 14 | React: true, 15 | JSX: true, 16 | }, 17 | env: { 18 | node: true, 19 | browser: true, 20 | }, 21 | plugins: ["only-warn"], 22 | settings: { 23 | "import/resolver": { 24 | typescript: { 25 | project, 26 | }, 27 | }, 28 | }, 29 | ignorePatterns: [ 30 | // Ignore dotfiles 31 | ".*.js", 32 | "node_modules/", 33 | ], 34 | overrides: [{ files: ["*.js?(x)", "*.ts?(x)"] }], 35 | }; 36 | -------------------------------------------------------------------------------- /turbo/packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/eslint-config", 3 | "version": "0.0.0", 4 | "private": true, 5 | "files": [ 6 | "library.js", 7 | "next.js", 8 | "react-internal.js" 9 | ], 10 | "devDependencies": { 11 | "@vercel/style-guide": "^5.2.0", 12 | "eslint-config-turbo": "^1.12.4", 13 | "eslint-config-prettier": "^9.1.0", 14 | "eslint-plugin-only-warn": "^1.1.0", 15 | "@typescript-eslint/parser": "^7.1.0", 16 | "@typescript-eslint/eslint-plugin": "^7.1.0", 17 | "typescript": "^5.3.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /turbo/packages/eslint-config/react-internal.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require("node:path"); 2 | 3 | const project = resolve(process.cwd(), "tsconfig.json"); 4 | 5 | /* 6 | * This is a custom ESLint configuration for use with 7 | * internal (bundled by their consumer) libraries 8 | * that utilize React. 9 | * 10 | * This config extends the Vercel Engineering Style Guide. 11 | * For more information, see https://github.com/vercel/style-guide 12 | * 13 | */ 14 | 15 | /** @type {import("eslint").Linter.Config} */ 16 | module.exports = { 17 | extends: ["eslint:recommended", "prettier", "eslint-config-turbo"], 18 | plugins: ["only-warn"], 19 | globals: { 20 | React: true, 21 | JSX: true, 22 | }, 23 | env: { 24 | browser: true, 25 | }, 26 | settings: { 27 | "import/resolver": { 28 | typescript: { 29 | project, 30 | }, 31 | }, 32 | }, 33 | ignorePatterns: [ 34 | // Ignore dotfiles 35 | ".*.js", 36 | "node_modules/", 37 | "dist/", 38 | ], 39 | overrides: [ 40 | // Force ESLint to detect .tsx files 41 | { files: ["*.js?(x)", "*.ts?(x)"] }, 42 | ], 43 | }; 44 | -------------------------------------------------------------------------------- /turbo/packages/typescript-config/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "declaration": true, 6 | "declarationMap": true, 7 | "esModuleInterop": true, 8 | "incremental": false, 9 | "isolatedModules": true, 10 | "lib": ["es2022", "DOM", "DOM.Iterable"], 11 | "module": "NodeNext", 12 | "moduleDetection": "force", 13 | "moduleResolution": "NodeNext", 14 | "noUncheckedIndexedAccess": true, 15 | "resolveJsonModule": true, 16 | "skipLibCheck": true, 17 | "strict": true, 18 | "target": "ES2022" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /turbo/packages/typescript-config/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "plugins": [{ "name": "next" }], 7 | "module": "ESNext", 8 | "moduleResolution": "Bundler", 9 | "allowJs": true, 10 | "jsx": "preserve", 11 | "noEmit": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /turbo/packages/typescript-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/typescript-config", 3 | "version": "0.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "publishConfig": { 7 | "access": "public" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /turbo/packages/typescript-config/react-library.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "React Library", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /turbo/packages/ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import("eslint").Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | extends: ["@repo/eslint-config/react-internal.js"], 5 | parser: "@typescript-eslint/parser", 6 | parserOptions: { 7 | project: "./tsconfig.lint.json", 8 | tsconfigRootDir: __dirname, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /turbo/packages/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/ui", 3 | "version": "0.0.0", 4 | "private": true, 5 | "exports": { 6 | "./button": "./src/button.tsx", 7 | "./card": "./src/card.tsx", 8 | "./code": "./src/code.tsx" 9 | }, 10 | "scripts": { 11 | "lint": "eslint . --max-warnings 0", 12 | "generate:component": "turbo gen react-component" 13 | }, 14 | "devDependencies": { 15 | "@repo/eslint-config": "workspace:*", 16 | "@repo/typescript-config": "workspace:*", 17 | "@turbo/gen": "^1.12.4", 18 | "@types/node": "^20.11.24", 19 | "@types/eslint": "^8.56.5", 20 | "@types/react": "^18.2.61", 21 | "@types/react-dom": "^18.2.19", 22 | "eslint": "^8.57.0", 23 | "react": "^18.2.0", 24 | "typescript": "^5.3.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /turbo/packages/ui/src/button.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { ReactNode } from "react"; 4 | 5 | interface ButtonProps { 6 | children: ReactNode; 7 | className?: string; 8 | appName: string; 9 | } 10 | 11 | export const Button = ({ children, className, appName }: ButtonProps) => { 12 | return ( 13 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /turbo/packages/ui/src/card.tsx: -------------------------------------------------------------------------------- 1 | export function Card({ 2 | className, 3 | title, 4 | children, 5 | href, 6 | }: { 7 | className?: string; 8 | title: string; 9 | children: React.ReactNode; 10 | href: string; 11 | }): JSX.Element { 12 | return ( 13 | 19 |

20 | {title} -> 21 |

22 |

{children}

23 |
24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /turbo/packages/ui/src/code.tsx: -------------------------------------------------------------------------------- 1 | export function Code({ 2 | children, 3 | className, 4 | }: { 5 | children: React.ReactNode; 6 | className?: string; 7 | }): JSX.Element { 8 | return {children}; 9 | } 10 | -------------------------------------------------------------------------------- /turbo/packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/react-library.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /turbo/packages/ui/tsconfig.lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/react-library.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src", "turbo"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /turbo/packages/ui/turbo/generators/config.ts: -------------------------------------------------------------------------------- 1 | import type { PlopTypes } from "@turbo/gen"; 2 | 3 | // Learn more about Turborepo Generators at https://turbo.build/repo/docs/core-concepts/monorepos/code-generation 4 | 5 | export default function generator(plop: PlopTypes.NodePlopAPI): void { 6 | // A simple generator to add a new React component to the internal UI library 7 | plop.setGenerator("react-component", { 8 | description: "Adds a new react component", 9 | prompts: [ 10 | { 11 | type: "input", 12 | name: "name", 13 | message: "What is the name of the component?", 14 | }, 15 | ], 16 | actions: [ 17 | { 18 | type: "add", 19 | path: "src/{{kebabCase name}}.tsx", 20 | templateFile: "templates/component.hbs", 21 | }, 22 | { 23 | type: "append", 24 | path: "package.json", 25 | pattern: /"exports": {(?)/g, 26 | template: '"./{{kebabCase name}}": "./src/{{kebabCase name}}.tsx",', 27 | }, 28 | ], 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /turbo/packages/ui/turbo/generators/templates/component.hbs: -------------------------------------------------------------------------------- 1 | export const {{ pascalCase name }} = ({ children }: { children: React.ReactNode }) => { 2 | return ( 3 |
4 |

{{ pascalCase name }} Component

5 | {children} 6 |
7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /turbo/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "apps/*" 3 | - "packages/*" 4 | -------------------------------------------------------------------------------- /turbo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/base.json" 3 | } 4 | -------------------------------------------------------------------------------- /turbo/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "globalDependencies": ["**/.env.*local"], 4 | "pipeline": { 5 | "build": { 6 | "dependsOn": ["^build"], 7 | "outputs": [".next/**", "!.next/cache/**"] 8 | }, 9 | "lint": { 10 | "dependsOn": ["^lint"] 11 | }, 12 | "dev": { 13 | "cache": false, 14 | "persistent": true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .npmrc 4 | .DS_Store -------------------------------------------------------------------------------- /utils/.parcelrc: -------------------------------------------------------------------------------- 1 | { "extends": "@parcel/config-default", "transformers": { "*.glb": ["@parcel/transformer-raw"] } } 2 | 3 | -------------------------------------------------------------------------------- /utils/easings.js: -------------------------------------------------------------------------------- 1 | // https://easings.net/ 2 | 3 | const PI = Math.PI; 4 | 5 | export function easeOutSine(x) { 6 | return Math.sin((x * Math.PI) / 2); 7 | } 8 | 9 | export function easeInOutSine(x) { 10 | return -(Math.cos(PI * x) - 1) / 2; 11 | } 12 | 13 | export function easeOutExpo(x) { 14 | return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); 15 | } 16 | 17 | export function easeInOutExpo(x) { 18 | return x === 0 19 | ? 0 20 | : x === 1 21 | ? 1 22 | : x < 0.5 23 | ? Math.pow(2, 20 * x - 10) / 2 24 | : (2 - Math.pow(2, -20 * x + 10)) / 2; 25 | } 26 | -------------------------------------------------------------------------------- /utils/math.js: -------------------------------------------------------------------------------- 1 | /** ------------ Numbers **/ 2 | 3 | // lerp 4 | export function lerp(v0, v1, t) { 5 | return v0 * (1 - t) + v1 * t; 6 | } 7 | 8 | // map 9 | export function map(value, low1, high1, low2, high2) { 10 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 11 | } 12 | 13 | // clamp 14 | export function clamp(min, max, num) { 15 | return Math.min(Math.max(num, min), max); 16 | } 17 | 18 | // modulo 19 | function mod(n, m) { 20 | return ((n % m) + m) % m; 21 | } 22 | 23 | /** ------------ Angles **/ 24 | export function radToDeg(r) { 25 | return (r * 180) / Math.PI; 26 | } 27 | 28 | export function degToRad(d) { 29 | return (d * Math.PI) / 180; 30 | } 31 | 32 | /** ------------ Bitwise **/ 33 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 34 | -------------------------------------------------------------------------------- /vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | .npmrc 26 | -------------------------------------------------------------------------------- /vite/README.md: -------------------------------------------------------------------------------- 1 | # Vite Boilerplate 2 | 3 | #### TODO 4 | 5 | ##### Animations 6 | 7 | - [x] text class 8 | - [ ] track class (?) 9 | 10 | ##### Gl 11 | 12 | - [ ] preloader class (should be in gl?) 13 | - [ ] with emitting promises 14 | -------------------------------------------------------------------------------- /vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^5.2.12", 13 | "vite-plugin-glsl": "^1.3.0" 14 | }, 15 | "dependencies": { 16 | "@unseenco/taxi": "1.6.0", 17 | "gsap": "npm:@gsap/shockingly@^3.12.5", 18 | "lenis": "^1.1.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vite/src/app.js: -------------------------------------------------------------------------------- 1 | import "./style/main.css"; 2 | 3 | import { Dom } from "./modules/dom"; 4 | import { Viewport } from "./modules/viewport"; 5 | import { Scroll } from "./modules/scroll"; 6 | import { Pages } from "./modules/pages"; 7 | 8 | class App { 9 | constructor() { 10 | this.body = document.querySelector("body"); 11 | this.viewport = new Viewport(); 12 | 13 | this.time = 0; 14 | 15 | this.init(); 16 | } 17 | 18 | init() { 19 | this.scroll = new Scroll(); 20 | this.pages = new Pages(); 21 | this.dom = new Dom(); 22 | 23 | this.initEvents(); 24 | 25 | /** RAF should come from gsap */ 26 | // gsap.ticker.add((t) => this.render(t)); 27 | this.render(); 28 | } 29 | 30 | initEvents() { 31 | // prettier-ignore 32 | new ResizeObserver((entry) => this.resize(entry[0])).observe(this.body); 33 | } 34 | 35 | resize({ contentRect }) { 36 | this.viewport?.resize(); 37 | this.dom?.resize(); 38 | } 39 | 40 | render(t) { 41 | this.scroll?.render(t); // if gsap * 1000 42 | this.dom?.render(); 43 | // this.gl?.render(this.scroll.y); 44 | 45 | // remove if gsap 46 | window.requestAnimationFrame(this.render.bind(this)); 47 | } 48 | 49 | /* Events */ 50 | } 51 | 52 | window.app = new App(); 53 | -------------------------------------------------------------------------------- /vite/src/assets/index.js: -------------------------------------------------------------------------------- 1 | export const ASSETS = { 2 | // img: null, 3 | }; 4 | -------------------------------------------------------------------------------- /vite/src/gsap.js: -------------------------------------------------------------------------------- 1 | import gsap from "gsap"; 2 | import { ScrollTrigger } from "gsap/ScrollTrigger"; 3 | import { SplitText } from "gsap/SplitText"; 4 | 5 | gsap.registerPlugin(ScrollTrigger); 6 | gsap.registerPlugin(SplitText); 7 | 8 | const def = { 9 | duration: 1, 10 | ease: "expo.out", 11 | }; 12 | 13 | gsap.defaults(def); 14 | 15 | const utils = {}; 16 | 17 | export default gsap; 18 | export { def, utils, ScrollTrigger, SplitText }; 19 | -------------------------------------------------------------------------------- /vite/src/modules/ctrl.js: -------------------------------------------------------------------------------- 1 | export const ANIM = { 2 | t: { 3 | in: { 4 | d: 1.2, 5 | e: "expo.out", 6 | each: 0.1, 7 | }, 8 | out: { 9 | d: 1.2, 10 | e: "expo.out", 11 | each: 0, 12 | }, 13 | }, 14 | page: { 15 | d: 1.2, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /vite/src/modules/viewport.js: -------------------------------------------------------------------------------- 1 | export class Viewport { 2 | constructor() { 3 | this.resize(); 4 | } 5 | 6 | resize() { 7 | // set CSS vh var 8 | document.documentElement.style.setProperty( 9 | "--100vh", 10 | `${window.innerHeight}px` 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /vite/src/style/anim.css: -------------------------------------------------------------------------------- 1 | /* --- Text Animation */ 2 | 3 | [data-a="char"] div, 4 | [data-a="word"] div, 5 | [data-a="line"] div { 6 | /* border: 1px solid blue; */ 7 | overflow: hidden; 8 | box-sizing: border-box; 9 | } 10 | 11 | [data-a="char"] div div, 12 | [data-a="word"] div div, 13 | [data-a="line"] div div { 14 | /* border: 1px solid red; */ 15 | box-sizing: border-box; 16 | } 17 | -------------------------------------------------------------------------------- /vite/src/util/clientRect.js: -------------------------------------------------------------------------------- 1 | export const clientRect = (element) => { 2 | const bounds = element.getBoundingClientRect(); 3 | 4 | let scroll = 0; 5 | scroll = window.app?.scroll?.y || window.pageYOffset; 6 | 7 | return { 8 | // screen 9 | top: bounds.top + scroll, 10 | bottom: bounds.bottom + scroll, 11 | width: bounds.width, 12 | height: bounds.height, 13 | left: bounds.left, 14 | right: bounds.right, 15 | wh: window.innerHeight, 16 | ww: window.innerWidth, 17 | offset: bounds.top + scroll, 18 | // centery: bounds.top + scroll + bounds.height / 2, // check if correct 19 | // centerx: bounds.left + bounds.width / 2, // check if correct 20 | }; 21 | }; 22 | 23 | // to check 24 | export const clientRectGl = (element, ratio = 1) => { 25 | const bounds = clientRect(element); 26 | 27 | for (const [key, value] of Object.entries(bounds)) 28 | bounds[key] = value * ratio; 29 | 30 | return bounds; 31 | }; 32 | -------------------------------------------------------------------------------- /vite/src/util/easings.js: -------------------------------------------------------------------------------- 1 | // https://easings.net/ 2 | 3 | const PI = Math.PI; 4 | 5 | export function easeOutSine(x) { 6 | return Math.sin((x * Math.PI) / 2); 7 | } 8 | 9 | export function easeInOutSine(x) { 10 | return -(Math.cos(PI * x) - 1) / 2; 11 | } 12 | 13 | export function easeOutExpo(x) { 14 | return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); 15 | } 16 | 17 | export function easeInOutExpo(x) { 18 | return x === 0 19 | ? 0 20 | : x === 1 21 | ? 1 22 | : x < 0.5 23 | ? Math.pow(2, 20 * x - 10) / 2 24 | : (2 - Math.pow(2, -20 * x + 10)) / 2; 25 | } 26 | 27 | export function easeOutBack(x) { 28 | const c1 = 1.70158; 29 | const c3 = c1 + 1; 30 | 31 | return 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2); 32 | } 33 | -------------------------------------------------------------------------------- /vite/src/util/gui.js: -------------------------------------------------------------------------------- 1 | import GUI from "lil-gui"; 2 | 3 | window.gui = new GUI(); 4 | 5 | gui.params = { 6 | progress: 0, 7 | }; 8 | 9 | gui.add(gui.params, "progress", 0, 1, 0.01); 10 | -------------------------------------------------------------------------------- /vite/src/util/index.js: -------------------------------------------------------------------------------- 1 | export function handleResize(container, cb) { 2 | new ResizeObserver((entry) => cb(entry[0].contentRect)).observe(container); 3 | } 4 | -------------------------------------------------------------------------------- /vite/src/util/math.js: -------------------------------------------------------------------------------- 1 | // lerp 2 | export function lerp(v0, v1, t) { 3 | return v0 * (1 - t) + v1 * t; 4 | } 5 | 6 | // map 7 | export function map(value, low1, high1, low2, high2) { 8 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 9 | } 10 | 11 | // clamp 12 | export function clamp(min, max, num) { 13 | return Math.min(Math.max(num, min), max); 14 | } 15 | 16 | /** ------------ Angles **/ 17 | export function radToDeg(r) { 18 | return (r * 180) / Math.PI; 19 | } 20 | 21 | export function degToRad(d) { 22 | return (d * Math.PI) / 180; 23 | } 24 | 25 | /** ------------ Bitwise **/ 26 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 27 | -------------------------------------------------------------------------------- /vite/tsconfig.json.bak: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@s/*": ["src/*"], 6 | "@util/*": ["src/util/*"] 7 | }, 8 | "jsx": "preserve", 9 | "jsxImportSource": "solid-js" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /webflow/full/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Dependency directories 7 | node_modules/ 8 | 9 | # TypeScript v1 declaration files 10 | typings/ 11 | 12 | # Optional npm cache directory 13 | .npm 14 | 15 | # Optional eslint cache 16 | .eslintcache 17 | 18 | # Optional REPL history 19 | .node_repl_history 20 | 21 | # Output of 'npm pack' 22 | *.tgz 23 | 24 | # dotenv environment variables file 25 | .env 26 | 27 | # Production files 28 | dist -------------------------------------------------------------------------------- /webflow/full/README.md: -------------------------------------------------------------------------------- 1 | # Webflow Project Starter 2 | -------------------------------------------------------------------------------- /webflow/full/bin/live-reload.js: -------------------------------------------------------------------------------- 1 | new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener('change', () => location.reload()); 2 | -------------------------------------------------------------------------------- /webflow/full/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@finsweet/developer-starter", 3 | "version": "0.0.0", 4 | "description": "Developer starter template for Finsweet projects.", 5 | "homepage": "https://github.com/finsweet/developer-starter#readme", 6 | "license": "ISC", 7 | "keywords": [], 8 | "author": { 9 | "name": "Finsweet", 10 | "url": "https://finsweet.com/" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/finsweet/developer-starter.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/finsweet/developer-starter/issues" 18 | }, 19 | "type": "module", 20 | "main": "src/index.ts", 21 | "module": "src/index.ts", 22 | "files": [ 23 | "dist" 24 | ], 25 | "scripts": { 26 | "dev": "cross-env NODE_ENV=development node ./bin/build.js", 27 | "build": "cross-env NODE_ENV=production node ./bin/build.js", 28 | "update": "pnpm update -i -L -r" 29 | }, 30 | "devDependencies": { 31 | "cross-env": "^7.0.3", 32 | "esbuild": "^0.17.14" 33 | }, 34 | "dependencies": { 35 | "@finsweet/ts-utils": "^0.39.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /webflow/full/src/index.ts: -------------------------------------------------------------------------------- 1 | console.log("hello webflow"); 2 | -------------------------------------------------------------------------------- /webflow/tiny/README.md: -------------------------------------------------------------------------------- 1 | # Webflow Dev Boilerplate 2 | 3 | Not sure it's needed should just use VITE 4 | 5 | ```html 6 | 7 | 15 | 16 | 21 | ``` 22 | -------------------------------------------------------------------------------- /webflow/tiny/dist/app.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | // src/app.js 3 | var App = class { 4 | constructor() { 5 | console.log("App live"); 6 | } 7 | }; 8 | window.add = new App(); 9 | })(); 10 | //# sourceMappingURL=app.js.map 11 | -------------------------------------------------------------------------------- /webflow/tiny/dist/app.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": ["../src/app.js"], 4 | "sourcesContent": ["class App {\n constructor() {\n console.log(\"App live\");\n }\n}\n\nwindow.add = new App();\n\n// \n// \n\n// \n"], 5 | "mappings": ";;AAAA,MAAM,MAAN,MAAU;AAAA,IACR,cAAc;AACZ,cAAQ,IAAI,UAAU;AAAA,IACxB;AAAA,EACF;AAEA,SAAO,MAAM,IAAI,IAAI;", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /webflow/tiny/dist/styles/main.css: -------------------------------------------------------------------------------- 1 | /* src/styles/variables.css */ 2 | :root { 3 | --duration: 1.2s; 4 | --easeOut: cubic-bezier(0.77, 0, 0.175, 1); 5 | --easeOutBack: cubic-bezier(0.175, 0, 0.77, 1); 6 | --easeOutQuint: cubic-bezier(0.23, 1, 0.32, 1); 7 | } 8 | 9 | /* src/styles/lenis.css */ 10 | html.lenis, 11 | html.lenis body { 12 | height: auto; 13 | } 14 | .lenis.lenis-smooth { 15 | scroll-behavior: auto !important; 16 | } 17 | .lenis.lenis-smooth [data-lenis-prevent] { 18 | overscroll-behavior: contain; 19 | } 20 | .lenis.lenis-stopped { 21 | overflow: clip; 22 | } 23 | .lenis.lenis-smooth iframe { 24 | pointer-events: none; 25 | } 26 | 27 | /* src/styles/main.css */ 28 | * { 29 | box-sizing: border-box; 30 | -webkit-user-select: none; 31 | -ms-user-select: none; 32 | user-select: none; 33 | } 34 | body { 35 | -webkit-font-smoothing: antialiased; 36 | -moz-osx-font-smoothing: grayscale; 37 | text-rendering: optimizeLegibility; 38 | } 39 | :root { 40 | overscroll-behavior: none; 41 | overflow-x: hidden; 42 | } 43 | @media only screen and (min-width: 767px) { 44 | [data-hide=desktop] { 45 | display: none; 46 | } 47 | } 48 | @media only screen and (max-width: 767px) { 49 | :root { 50 | --text-h1: 3.2rem; 51 | } 52 | [data-hide=mobile] { 53 | display: none; 54 | } 55 | } 56 | /*# sourceMappingURL=main.css.map */ 57 | -------------------------------------------------------------------------------- /webflow/tiny/dist/styles/out.css: -------------------------------------------------------------------------------- 1 | /* src/styles/out.css */ 2 | /*# sourceMappingURL=out.css.map */ 3 | -------------------------------------------------------------------------------- /webflow/tiny/dist/styles/out.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": [], 4 | "sourcesContent": [], 5 | "mappings": "", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /webflow/tiny/esbuild.config.js: -------------------------------------------------------------------------------- 1 | import * as esbuild from "esbuild"; 2 | import { glsl } from "esbuild-plugin-glsl"; 3 | 4 | /* - Setup */ 5 | const env = process.env.NODE_ENV; 6 | const production = env === "production"; 7 | 8 | const CONFIG = { 9 | PORT: 8000, 10 | ENTRY: ["src/app.js", "src/styles/main.css", "src/styles/out.css"], 11 | SERVE_DIR: "dist", 12 | OUT_DIR: "dist", 13 | BUILD_DIR: "build", 14 | }; 15 | 16 | /* -- Plugins */ 17 | const plugins = [ 18 | glsl({ 19 | minify: production, 20 | }), 21 | ]; 22 | 23 | const loader = { 24 | ".png": "dataurl", 25 | ".webp": "dataurl", 26 | ".glb": "dataurl", 27 | }; 28 | 29 | const ctx = await esbuild.context({ 30 | bundle: true, 31 | entryPoints: CONFIG.ENTRY, 32 | outdir: production ? CONFIG.BUILD_DIR : CONFIG.OUT_DIR, 33 | minify: production, 34 | sourcemap: !production, 35 | target: production ? "es2019" : "esnext", 36 | plugins, 37 | loader, 38 | }); 39 | 40 | if (production) { 41 | await ctx.rebuild(); 42 | ctx.dispose(); 43 | } else { 44 | await ctx.watch(); 45 | await ctx 46 | .serve({ 47 | servedir: CONFIG.SERVE_DIR, 48 | port: CONFIG.PORT, 49 | }) 50 | .then(() => console.log("http://localhost:8000/")); 51 | } 52 | -------------------------------------------------------------------------------- /webflow/tiny/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webflow", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "NODE_ENV=dev node esbuild.config.js", 9 | "build": "NODE_ENV=production node esbuild.config.js", 10 | "flow": "NODE_ENV=flow node esbuild.config.js" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "esbuild": "^0.19.4", 17 | "esbuild-plugin-glsl": "^1.2.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /webflow/tiny/src/app.js: -------------------------------------------------------------------------------- 1 | class App { 2 | constructor() { 3 | console.log("App live"); 4 | } 5 | } 6 | 7 | window.add = new App(); 8 | 9 | // 10 | // 18 | 19 | // 23 | -------------------------------------------------------------------------------- /webflow/tiny/src/styles/lenis.css: -------------------------------------------------------------------------------- 1 | html.lenis, 2 | html.lenis body { 3 | height: auto; 4 | } 5 | 6 | .lenis.lenis-smooth { 7 | scroll-behavior: auto !important; 8 | } 9 | 10 | .lenis.lenis-smooth [data-lenis-prevent] { 11 | overscroll-behavior: contain; 12 | } 13 | 14 | .lenis.lenis-stopped { 15 | overflow: clip; 16 | } 17 | 18 | .lenis.lenis-smooth iframe { 19 | pointer-events: none; 20 | } 21 | -------------------------------------------------------------------------------- /webflow/tiny/src/styles/main.css: -------------------------------------------------------------------------------- 1 | @import "variables.css"; 2 | @import "lenis.css"; 3 | 4 | * { 5 | box-sizing: border-box; 6 | 7 | -webkit-user-select: none; 8 | -ms-user-select: none; 9 | user-select: none; 10 | } 11 | 12 | body { 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | text-rendering: optimizeLegibility; 16 | } 17 | 18 | :root { 19 | overscroll-behavior: none; 20 | overflow-x: hidden; 21 | } 22 | 23 | @media only screen and (min-width: 767px) { 24 | /* desktop */ 25 | [data-hide="desktop"] { 26 | display: none; 27 | } 28 | } 29 | 30 | @media only screen and (max-width: 767px) { 31 | /* mobile */ 32 | :root { 33 | --text-h1: 3.2rem; 34 | } 35 | 36 | [data-hide="mobile"] { 37 | display: none; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webflow/tiny/src/styles/out.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webflow/tiny/src/styles/out.css -------------------------------------------------------------------------------- /webflow/tiny/src/styles/variables.css: -------------------------------------------------------------------------------- 1 | :root { 2 | /* ** animation */ 3 | --duration: 1.2s; 4 | --easeOut: cubic-bezier(0.77, 0, 0.175, 1); 5 | --easeOutBack: cubic-bezier(0.175, 0, 0.77, 1); 6 | --easeOutQuint: cubic-bezier(0.23, 1, 0.32, 1); 7 | } 8 | -------------------------------------------------------------------------------- /webgl/chunk/imageuv.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Resize image to Cover 3 | uv : uv coord 4 | size : image size 5 | resolution : plane resolution | screen resolution 6 | */ 7 | 8 | vec2 imageuv(vec2 uv, vec2 size, vec2 resolution) { 9 | vec2 ratio = vec2( 10 | min((resolution.x / resolution.y) / (size.x / size.y), 1.0), 11 | min((resolution.y / resolution.x) / (size.y / size.x), 1.0) 12 | ); 13 | 14 | return vec2( 15 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 16 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 17 | ); 18 | } -------------------------------------------------------------------------------- /webgl/chunk/rand.glsl: -------------------------------------------------------------------------------- 1 | float rand(vec2 co){ 2 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 3 | } -------------------------------------------------------------------------------- /webgl/chunk/rotate3d.glsl: -------------------------------------------------------------------------------- 1 | mat4 rotationMatrix(vec3 axis, float angle) { 2 | axis = normalize(axis); 3 | float s = sin(angle); 4 | float c = cos(angle); 5 | float oc = 1.0 - c; 6 | 7 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 8 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 9 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 10 | 0.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | vec3 rotate3d(vec3 v, vec3 axis, float angle) { 14 | mat4 m = rotationMatrix(axis, angle); 15 | return (m * vec4(v, 1.0)).xyz; 16 | } -------------------------------------------------------------------------------- /webgl/ogl/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /webgl/ogl/README.md: -------------------------------------------------------------------------------- 1 | ## Ogl Starter 2 | 3 | ## Todo 4 | 5 | - [ ] refit starter classes in \_ folder 6 | - [ ] add post processing folder + class + shaders 7 | -------------------------------------------------------------------------------- /webgl/ogl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | VVV 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/ogl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^4.4.11", 13 | "vite-plugin-glsl": "^1.1.2" 14 | }, 15 | "dependencies": { 16 | "ogl": "^1.0.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/ogl/src/app.js: -------------------------------------------------------------------------------- 1 | import Dom from "@m/dom"; 2 | import Viewport from "@m/viewport"; 3 | import Gl from "./gl/gl"; 4 | 5 | class App { 6 | time = 0; 7 | constructor() { 8 | this.body = document.querySelector("body"); 9 | this.viewport = new Viewport(); 10 | 11 | this.time = 0; 12 | 13 | setTimeout(() => this.init(), 0); 14 | } 15 | 16 | init() { 17 | this.dom = new Dom(); 18 | 19 | this.gl = new Gl(); 20 | 21 | this.initEvents(); 22 | this.render(); 23 | } 24 | 25 | initEvents() { 26 | // prettier-ignore 27 | new ResizeObserver((entry) => this.resize(entry[0])).observe(this.body); 28 | } 29 | 30 | resize({ contentRect }) { 31 | this.viewport?.resize(); 32 | this.dom?.resize(); 33 | } 34 | 35 | render() { 36 | this.time += 0.1; 37 | 38 | this.gl?.render(this.time); 39 | 40 | window.requestAnimationFrame(this.render.bind(this)); 41 | } 42 | 43 | /* Events */ 44 | } 45 | 46 | window.app = new App(); 47 | -------------------------------------------------------------------------------- /webgl/ogl/src/assets/index.js: -------------------------------------------------------------------------------- 1 | import uvh from "./uvH.jpg"; 2 | import uvv from "./uvV.jpg"; 3 | 4 | export const assets = { 5 | uvh, 6 | uvv, 7 | }; 8 | -------------------------------------------------------------------------------- /webgl/ogl/src/assets/uvH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/ogl/src/assets/uvH.jpg -------------------------------------------------------------------------------- /webgl/ogl/src/assets/uvV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/ogl/src/assets/uvV.jpg -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_dquad.js: -------------------------------------------------------------------------------- 1 | import { Plane, Mesh } from "ogl"; 2 | import Material from "./mat/_quad"; 3 | 4 | import { domSize } from "./util/domitem.js"; 5 | 6 | export default class extends Mesh { 7 | constructor(gl, el = null, vp = {}) { 8 | super(gl); 9 | this.gl = gl; 10 | this.el = el; 11 | this.vp = vp; 12 | 13 | this.geometry = new Plane(this.gl); 14 | this.program = new Material(this.gl); 15 | 16 | // this.place(); 17 | } 18 | 19 | place() { 20 | const { x, y, w, h } = domSize(this.el, this.vp); 21 | this.scale.x = w; 22 | this.scale.y = h; 23 | this.position.x = x; 24 | this.position.y = y; 25 | } 26 | 27 | resize(vp) { 28 | this.vp = vp; 29 | this.place(); 30 | } 31 | 32 | render(t) {} 33 | } 34 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_group.js: -------------------------------------------------------------------------------- 1 | import { Transform } from "ogl"; 2 | 3 | export default class extends Transform { 4 | constructor(gl) { 5 | super(); 6 | this.gl = gl; 7 | this.isOn = false; 8 | } 9 | 10 | render(t) { 11 | if (!this.isOn) return; 12 | } 13 | 14 | resize() {} 15 | } 16 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_model.js: -------------------------------------------------------------------------------- 1 | import { Mesh, Box } from "ogl"; 2 | import Material from "./mat/_model"; 3 | 4 | export default class extends Mesh { 5 | constructor(gl, geometry = new Box(gl)) { 6 | super(gl, { 7 | geometry: geometry, 8 | program: new Material(gl), 9 | }); 10 | 11 | this.gl = gl; 12 | } 13 | 14 | resize() {} 15 | 16 | render(t) { 17 | this.program.time = t; 18 | // this.position.x = Math.sin(t) * 0.2; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_quad.js: -------------------------------------------------------------------------------- 1 | import { Plane, Mesh } from "ogl"; 2 | import Material from "./mat/_quad"; 3 | 4 | export class Quad extends Mesh { 5 | constructor(gl, diff = null) { 6 | super(gl, { 7 | geometry: new Plane(gl), 8 | program: new Material(gl), 9 | }); 10 | 11 | this.gl = gl; 12 | } 13 | 14 | resize() {} 15 | 16 | render(t) { 17 | this.program.time = t; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_scene.js: -------------------------------------------------------------------------------- 1 | import { Transform } from "ogl"; 2 | 3 | import { Quad } from "./_quad.js"; 4 | 5 | import { loadAssets } from "./util/loader.js"; 6 | // import { Instance } from "./_instance.js"; 7 | 8 | export class Scene extends Transform { 9 | constructor(gl, data = {}) { 10 | super(); 11 | this.gl = gl; 12 | this.isOn = true; 13 | 14 | this.create(); 15 | } 16 | 17 | async create() { 18 | /* Basic Quad */ 19 | 20 | this.quad = new Quad(this.gl); 21 | this.quad.setParent(this); 22 | 23 | // const ass = await loadAssets(this.gl); 24 | // console.log(ass); 25 | } 26 | 27 | render(t) { 28 | if (!this.isOn) return; 29 | if (this.quad) this.quad.render(t); 30 | // if (this.quads) this.quads.forEach((item) => item.render(t)); 31 | } 32 | 33 | resize(vp) { 34 | this.vp = vp; 35 | if (this.quad) this.quad.resize(vp); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/_screen.js: -------------------------------------------------------------------------------- 1 | import { Triangle, Mesh } from "ogl"; 2 | import Material from "./mat/_screen"; 3 | 4 | export default class extends Mesh { 5 | constructor(gl) { 6 | super(gl); 7 | this.gl = gl; 8 | 9 | this.geometry = new Triangle(this.gl); 10 | this.program = new Material(this.gl); 11 | } 12 | 13 | resize() {} 14 | 15 | render(t) { 16 | this.program.time = t; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/camera.js: -------------------------------------------------------------------------------- 1 | import { Camera } from "ogl"; 2 | 3 | export class Cam extends Camera { 4 | constructor(gl, { fov = 25 }) { 5 | super(); 6 | 7 | this.gl = gl; 8 | this.fov = fov; 9 | } 10 | 11 | get fovInRad() { 12 | return (this.fov * Math.PI) / 180; 13 | } 14 | 15 | getViewSize(ratio) { 16 | const height = Math.abs(this.position.z * Math.tan(this.fovInRad / 2) * 2); 17 | return { w: height * ratio, h: height }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_insta/fragment.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec3 v_normal; 4 | varying vec2 v_uv; 5 | varying vec4 v_color; 6 | // varying vec4 v_id; 7 | 8 | 9 | 10 | void main() { 11 | 12 | gl_FragColor.rgb = vec3(v_uv, 1.); 13 | gl_FragColor.a = 1.0; 14 | } 15 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_insta/index.js: -------------------------------------------------------------------------------- 1 | import { Program } from "ogl"; 2 | import vertex from "./vertex.vert"; 3 | import fragment from "./fragment.frag"; 4 | 5 | export default class extends Program { 6 | constructor(gl, options = {}) { 7 | super(gl, { 8 | vertex: vertex, 9 | fragment: fragment, 10 | transparent: true, 11 | cullFace: null, 12 | // depthTest: false, 13 | // depthWrite: false, 14 | }); 15 | 16 | this.uniforms = { 17 | u_time: { value: 0 }, 18 | }; 19 | } 20 | 21 | set time(t) { 22 | this.uniforms.u_time.value = t; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_insta/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926538 2 | #define MTAU 6.28318530718 3 | 4 | attribute vec3 position; 5 | attribute vec3 normal; 6 | attribute vec2 uv; 7 | attribute vec3 a_posmod; 8 | attribute float a_random; 9 | attribute vec4 a_id; 10 | 11 | uniform mat4 modelViewMatrix; 12 | uniform mat4 projectionMatrix; 13 | uniform mat3 normalMatrix; 14 | 15 | uniform float u_time; 16 | 17 | varying vec3 v_normal; 18 | varying vec2 v_uv; 19 | // varying vec4 v_id; 20 | 21 | void main() { 22 | vec3 pos = position; 23 | pos += a_posmod; 24 | 25 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 26 | 27 | v_normal = normalize(normalMatrix * normal); 28 | v_uv = uv; 29 | // v_id = a_id; 30 | } 31 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_model/fragment.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec3 v_normal; 4 | varying vec2 v_uv; 5 | varying vec4 v_color; 6 | 7 | 8 | void main() { 9 | 10 | gl_FragColor.rgb = vec3(v_uv, 1.); 11 | gl_FragColor.a = 1.0; 12 | } 13 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_model/index.js: -------------------------------------------------------------------------------- 1 | import { Program } from "ogl"; 2 | import vertex from "./vertex.vert"; 3 | import fragment from "./fragment.frag"; 4 | 5 | export default class extends Program { 6 | constructor(gl, options = {}) { 7 | super(gl, { 8 | vertex: vertex, 9 | fragment: fragment, 10 | transparent: true, 11 | cullFace: null, 12 | }); 13 | 14 | this.uniforms = { 15 | u_time: { value: 0 }, 16 | }; 17 | } 18 | 19 | set time(t) { 20 | this.uniforms.u_time.value = t; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_model/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926538 2 | #define MTAU 6.28318530718 3 | 4 | attribute vec3 position; 5 | attribute vec3 normal; 6 | attribute vec2 uv; 7 | 8 | uniform mat4 modelViewMatrix; 9 | uniform mat4 projectionMatrix; 10 | uniform mat3 normalMatrix; 11 | 12 | uniform float u_time; 13 | 14 | varying vec3 v_normal; 15 | varying vec2 v_uv; 16 | 17 | 18 | void main() { 19 | vec3 pos = position; 20 | 21 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 22 | 23 | v_normal = normalize(normalMatrix * normal); 24 | v_uv = uv; 25 | } 26 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_quad/fragment.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec3 v_normal; 4 | varying vec2 v_uv; 5 | 6 | 7 | 8 | void main() { 9 | 10 | gl_FragColor.rgb = vec3(v_uv, 2.); 11 | gl_FragColor.a = 1.0; 12 | } 13 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_quad/index.js: -------------------------------------------------------------------------------- 1 | import { Program } from "ogl"; 2 | import vertex from "./vertex.vert"; 3 | import fragment from "./fragment.frag"; 4 | 5 | export default class extends Program { 6 | constructor(gl, opt = {}) { 7 | super(gl, { 8 | vertex: vertex, 9 | fragment: fragment, 10 | transparent: true, 11 | cullFace: null, 12 | }); 13 | 14 | this.uniforms = { 15 | u_time: { value: 0 }, 16 | u_diff: { value: opt.diff || null }, 17 | }; 18 | } 19 | 20 | set time(t) { 21 | this.uniforms.u_time.value = t; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_quad/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926538 2 | #define MTAU 6.28318530718 3 | 4 | attribute vec3 position; 5 | attribute vec3 normal; 6 | attribute vec2 uv; 7 | 8 | uniform mat4 modelViewMatrix; 9 | uniform mat4 projectionMatrix; 10 | uniform mat3 normalMatrix; 11 | 12 | uniform float u_time; 13 | 14 | varying vec3 v_normal; 15 | varying vec2 v_uv; 16 | 17 | 18 | void main() { 19 | vec3 pos = position; 20 | 21 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 22 | 23 | v_normal = normalize(normalMatrix * normal); 24 | v_uv = uv; 25 | } 26 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_screen/fragment.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform float u_time; 4 | varying vec2 v_uv; 5 | 6 | void main() { 7 | 8 | gl_FragColor.rgb = vec3(v_uv, 1.); 9 | gl_FragColor.a = 1.0; 10 | } 11 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_screen/index.js: -------------------------------------------------------------------------------- 1 | import { Program } from "ogl"; 2 | import vertex from "./vertex.vert"; 3 | import fragment from "./fragment.frag"; 4 | 5 | export default class extends Program { 6 | constructor(gl, options = {}) { 7 | super(gl, { 8 | vertex: vertex, 9 | fragment: fragment, 10 | transparent: true, 11 | cullFace: null, 12 | }); 13 | 14 | this.uniforms = { 15 | u_time: { value: 0 }, 16 | }; 17 | } 18 | 19 | set time(t) { 20 | this.uniforms.u_time.value = t; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/mat/_screen/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926538 2 | #define MTAU 6.28318530718 3 | 4 | attribute vec2 uv; 5 | attribute vec2 position; 6 | varying vec2 v_uv; 7 | 8 | void main() { 9 | vec2 pos = position; 10 | 11 | gl_Position = vec4(pos, 0, 1); 12 | v_uv = uv; 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/post/mat/fragment.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform float u_time; 4 | uniform sampler2D u_texture; 5 | varying vec2 v_uv; 6 | 7 | void main() { 8 | 9 | vec4 img = texture2D(u_texture, v_uv); 10 | 11 | gl_FragColor.rgb = img.rgb; 12 | gl_FragColor.a = 1.0; 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/post/mat/index.js: -------------------------------------------------------------------------------- 1 | import { Program } from "ogl"; 2 | import vertex from "./vertex.vert"; 3 | import fragment from "./fragment.frag"; 4 | 5 | export default class extends Program { 6 | constructor(gl, options = {}) { 7 | super(gl, { 8 | vertex: vertex, 9 | fragment: fragment, 10 | }); 11 | 12 | // console.log(this.uniforms); 13 | this.transparent = null; 14 | this.cullFace = null; 15 | 16 | this.uniforms = { 17 | u_time: { value: 0 }, 18 | u_texture: { value: null }, 19 | }; 20 | } 21 | 22 | set time(t) { 23 | this.uniforms.u_time.value = t; 24 | } 25 | 26 | set texture(texture) { 27 | this.uniforms.u_texture.value = texture; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/post/mat/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926538 2 | #define MTAU 6.28318530718 3 | 4 | attribute vec2 uv; 5 | attribute vec2 position; 6 | varying vec2 v_uv; 7 | 8 | void main() { 9 | vec2 pos = position; 10 | 11 | gl_Position = vec4(pos, 0, 1); 12 | v_uv = uv; 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/post/post.js: -------------------------------------------------------------------------------- 1 | import { RenderTarget } from "ogl"; 2 | import Quad from "./quad.js"; 3 | 4 | export default class { 5 | constructor(gl) { 6 | this.gl = gl; 7 | this.isActive = true; 8 | 9 | this.rt = new RenderTarget(this.gl, {}); 10 | this.quad = new Quad(this.gl); 11 | this.quad.program.texture = this.rt.texture; 12 | } 13 | 14 | resize(vp) { 15 | this.vp = vp; 16 | 17 | this.rt = new RenderTarget(this.gl, {}); 18 | this.quad.resize(vp); 19 | } 20 | 21 | render(t) { 22 | this.quad.program.texture = this.rt.texture; 23 | this.quad.render(t); 24 | } 25 | } 26 | 27 | /* 28 | renderPost(t) { 29 | // 1. render scene to rt 30 | this.renderer.render({ 31 | scene: this.scene, 32 | camera: this.camera, 33 | target: this.post.rt, 34 | }); 35 | 36 | // 2. move time in post 37 | this.post.render(t); 38 | 39 | // 3. render post to quad 40 | this.renderer.render({ 41 | scene: this.post.quad, 42 | camera: this.camera, 43 | }); 44 | } 45 | */ 46 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/post/quad.js: -------------------------------------------------------------------------------- 1 | import { Triangle, Mesh } from "ogl"; 2 | import Material from "./mat/index.js"; 3 | 4 | export default class extends Mesh { 5 | constructor(gl) { 6 | super(gl); 7 | this.gl = gl; 8 | this.geometry = new Triangle(this.gl); 9 | this.program = new Material(this.gl); 10 | } 11 | 12 | resize(vp) {} 13 | 14 | render(t) { 15 | this.program.time = t; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/util/domitem.js: -------------------------------------------------------------------------------- 1 | export function domSize( 2 | it, 3 | { viewRatio: ratio, w: scw, h: sch, scrollx = 0, scrolly = 0 } 4 | ) { 5 | const { x, y, width: w, height: h } = it.getBoundingClientRect(); 6 | 7 | return { 8 | x: (-scw / 2 + x + w / 2) * ratio, 9 | y: (-sch / 2 + y + h / 2) * ratio, 10 | w: w * ratio, 11 | h: h * ratio, 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/util/loader.js: -------------------------------------------------------------------------------- 1 | import { loadModel } from "./model-loader"; 2 | import { loadTexture } from "./texture-loader"; 3 | import { assets as file } from "../../assets"; 4 | 5 | export async function loadAssets(gl, opt = null) { 6 | // console.time("assets::"); // !1 remove timer from here 7 | const assets = opt || file; 8 | 9 | const promises = []; 10 | const names = []; 11 | 12 | for (const key in assets) { 13 | const asset = assets[key]; 14 | 15 | const extension = asset.split(".").pop(); 16 | 17 | if (extension === "glb" || extension === "gltf") { 18 | promises.push(loadModel(gl, asset)); 19 | } else if ( 20 | extension === "jpg" || 21 | extension === "png" || 22 | extension === "webp" || 23 | extension === "jpeg" 24 | ) { 25 | promises.push(loadTexture(gl, asset)); 26 | } 27 | 28 | names.push(key); 29 | } 30 | 31 | const loaded = await Promise.all(promises); 32 | 33 | const result = names.reduce((acc, key, index) => { 34 | acc[key] = loaded[index]; 35 | return acc; 36 | }, {}); 37 | 38 | // console.timeEnd("assets::"); 39 | 40 | return result; 41 | } 42 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/util/model-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "ogl"; 2 | 3 | export async function loadModel(gl, path) { 4 | return GLTFLoader.load(gl, path); 5 | } 6 | 7 | export async function loadGeometry(gl, path) { 8 | return new Promise((resolve) => { 9 | GLTFLoader.load(gl, path).then((data) => { 10 | resolve(data.meshes[0].primitives[0].geometry); 11 | }); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/gl/util/texture-loader.js: -------------------------------------------------------------------------------- 1 | import { Texture } from "ogl"; 2 | 3 | export async function loadTexture(gl, path) { 4 | return new Promise((resolve) => { 5 | const img = new Image(); 6 | img.src = path; 7 | img.onload = () => { 8 | const texture = new Texture(gl, { image: img }); 9 | resolve(texture); 10 | }; 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /webgl/ogl/src/modules/dom.js: -------------------------------------------------------------------------------- 1 | // import { Observe } from "@u/observe.js"; 2 | 3 | export default class { 4 | constructor() { 5 | // console.log("dom"); 6 | } 7 | 8 | resize() {} 9 | } 10 | -------------------------------------------------------------------------------- /webgl/ogl/src/modules/gui.js: -------------------------------------------------------------------------------- 1 | import LilGui from "lil-gui"; 2 | 3 | export class Gui extends LilGui { 4 | constructor() { 5 | super(); 6 | this.initControllers(); 7 | this.initWindowGui(); 8 | window.gui = this; 9 | 10 | this.close(); 11 | } 12 | 13 | initControllers() { 14 | this.val = { 15 | anim: { 16 | timeline: 0, 17 | }, 18 | }; 19 | } 20 | 21 | initWindowGui() { 22 | for (const key in this.val) { 23 | const fold = this.addFolder(key); 24 | fold.close(); 25 | 26 | for (const key2 in this.val[key]) { 27 | fold.add(this.val[key], key2, 0, 1, 0.001); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webgl/ogl/src/modules/lenis.js: -------------------------------------------------------------------------------- 1 | // import Lenis from "@studio-freight/lenis"; 2 | 3 | export default class { 4 | constructor() {} 5 | 6 | resize() {} 7 | 8 | render(t) {} 9 | } 10 | 11 | /* 12 | 13 | const lenis = new Lenis({ 14 | duration: 1.2, 15 | easing: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)), // https://easings.net 16 | direction: "vertical", 17 | smooth: true, 18 | smoothTouch: false, 19 | touchMultiplier: 2, 20 | }); 21 | 22 | //get scroll value 23 | lenis.on("scroll", ({ scroll, limit, velocity, direction, progress }) => { 24 | console.log({ scroll, limit, velocity, direction, progress }); 25 | }); 26 | 27 | function raf(time) { 28 | lenis.raf(time); 29 | requestAnimationFrame(raf); 30 | } 31 | 32 | requestAnimationFrame(raf); 33 | 34 | 35 | */ 36 | -------------------------------------------------------------------------------- /webgl/ogl/src/modules/pages.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() {} 3 | } 4 | -------------------------------------------------------------------------------- /webgl/ogl/src/modules/viewport.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() { 3 | this.resize(); 4 | } 5 | 6 | resize() { 7 | // set CSS vh var 8 | document.documentElement.style.setProperty( 9 | "--100vh", 10 | `${window.innerHeight}px` 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /webgl/ogl/src/style/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, 5 | Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | } 7 | 8 | [data-gl="c"] { 9 | box-sizing: border-box; 10 | display: block; 11 | width: 100vw; 12 | height: 100vh; 13 | position: fixed; 14 | top: 0; 15 | left: 0; 16 | 17 | z-index: 2; 18 | } 19 | -------------------------------------------------------------------------------- /webgl/ogl/src/util/math.js: -------------------------------------------------------------------------------- 1 | // lerp 2 | export function lerp(v0, v1, t) { 3 | return v0 * (1 - t) + v1 * t; 4 | } 5 | 6 | // map 7 | export function map(value, low1, high1, low2, high2) { 8 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 9 | } 10 | 11 | // clamp 12 | export function clamp(min, max, num) { 13 | return Math.min(Math.max(num, min), max); 14 | } 15 | 16 | /** ------------ Angles **/ 17 | export function radToDeg(r) { 18 | return (r * 180) / Math.PI; 19 | } 20 | 21 | export function degToRad(d) { 22 | return (d * Math.PI) / 180; 23 | } 24 | 25 | /** ------------ Bitwise **/ 26 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 27 | -------------------------------------------------------------------------------- /webgl/ogl/src/util/track.js: -------------------------------------------------------------------------------- 1 | // fix imports 2 | // fix and check code from source 3 | // fins a good name 4 | 5 | // import { getBoundingClientRect } from "@/utils/dom"; 6 | // import { map } from "@/utils/math"; 7 | 8 | // export default class { 9 | // constructor({ element }) { 10 | // this.element = element; 11 | // this.speed = parseFloat(this.element.dataset.animationSpeed); 12 | 13 | // this.onResize(); 14 | // } 15 | 16 | // onResize() { 17 | // this.element.style.transform = ""; 18 | 19 | // this.bounds = getBoundingClientRect(this.element); 20 | // this.height = window.innerHeight; 21 | // } 22 | 23 | // update({ current }) { 24 | // const amount = 100 * this.speed; 25 | // const offset = this.bounds.top + this.bounds.height / 2; 26 | // const parallax = map( 27 | // offset - current, 28 | // -this.height, 29 | // this.height, 30 | // amount, 31 | // -amount 32 | // ); 33 | 34 | // this.element.style.transform = `translate3d(0, ${parallax}px, 0)`; 35 | // } 36 | // } 37 | -------------------------------------------------------------------------------- /webgl/three-new/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | VVV 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/three-new/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^5.4.0", 13 | "vite-plugin-glsl": "^1.3.0" 14 | }, 15 | "dependencies": { 16 | "gsap": "^3.12.5", 17 | "lil-gui": "^0.19.2", 18 | "three": "^0.167.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webgl/three-new/src/app.js: -------------------------------------------------------------------------------- 1 | import { Gl } from "./gl/gl"; 2 | import { Gui } from "./gui"; 3 | import gsap from "@src/gsap"; 4 | import { handleResize } from "./gl/utils"; 5 | 6 | class App { 7 | static time = 0; 8 | static body = document.querySelector("body"); 9 | static gl = Gl; 10 | 11 | static { 12 | this.initEvents(); 13 | gsap.ticker.add(this.render.bind(this)); 14 | } 15 | 16 | static init() {} 17 | 18 | static initEvents() { 19 | handleResize(this.body, this.resize.bind(this)); 20 | } 21 | 22 | static resize({ contentRect }) {} 23 | 24 | static render(t) { 25 | Gl.render(t); 26 | } 27 | 28 | /* Events */ 29 | } 30 | 31 | App.init(); 32 | -------------------------------------------------------------------------------- /webgl/three-new/src/assets/index.js: -------------------------------------------------------------------------------- 1 | export const ASSETS = { 2 | // img: null, 3 | }; 4 | -------------------------------------------------------------------------------- /webgl/three-new/src/assets/uvH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three-new/src/assets/uvH.jpg -------------------------------------------------------------------------------- /webgl/three-new/src/assets/uvV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three-new/src/assets/uvV.jpg -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/_/basic/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float u_time; 2 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 3 | 4 | varying vec2 v_uv; 5 | // varying vec3 vPosition; 6 | 7 | 8 | void main() { 9 | 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/_/basic/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends ShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/_/basic/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | 3 | uniform float u_time; 4 | varying vec2 v_uv; 5 | 6 | 7 | void main() { 8 | vec3 pos = position; 9 | 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 11 | v_uv = uv; 12 | } 13 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/constants.glsl: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | #define MTAU 6.283185307179586476925286766559 -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/imageuv.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Resize image to Cover 3 | uv : uv coord 4 | size : image size 5 | resolution : plane resolution | screen resolution 6 | */ 7 | 8 | vec2 imageuv(vec2 uv, vec2 size, vec2 resolution) { 9 | vec2 ratio = vec2( 10 | min((resolution.x / resolution.y) / (size.x / size.y), 1.0), 11 | min((resolution.y / resolution.x) / (size.y / size.x), 1.0) 12 | ); 13 | 14 | return vec2( 15 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 16 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 17 | ); 18 | } -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/rand.glsl: -------------------------------------------------------------------------------- 1 | float rand(vec2 co){ 2 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 3 | } -------------------------------------------------------------------------------- /webgl/three-new/src/gl/glsl/rotate3d.glsl: -------------------------------------------------------------------------------- 1 | mat4 rotationMatrix(vec3 axis, float angle) { 2 | axis = normalize(axis); 3 | float s = sin(angle); 4 | float c = cos(angle); 5 | float oc = 1.0 - c; 6 | 7 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 8 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 9 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 10 | 0.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | vec3 rotate3d(vec3 v, vec3 axis, float angle) { 14 | mat4 m = rotationMatrix(axis, angle); 15 | return (m * vec4(v, 1.0)).xyz; 16 | } -------------------------------------------------------------------------------- /webgl/three-new/src/gl/instance/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/instance/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | InstancedMesh, 3 | PlaneGeometry, 4 | RawShaderMaterial, 5 | DoubleSide, 6 | } from "three"; 7 | 8 | import { calcAttributes } from "./utils"; 9 | 10 | import vertexShader from "./vertex.vert"; 11 | import fragmentShader from "./fragment.frag"; 12 | 13 | export class Instance extends InstancedMesh { 14 | count = 10; 15 | 16 | constructor() { 17 | super(); 18 | 19 | this.geometry = new PlaneGeometry(1, 1, 1, 1); 20 | this.setAttributes(); 21 | this.material = new Material(); 22 | } 23 | 24 | setAttributes() { 25 | const attributes = calcAttributes(this.count); 26 | for (const key in attributes) { 27 | const { name, data } = attributes[key]; 28 | this.geometry.setAttribute(name, data); 29 | } 30 | } 31 | 32 | render(t) {} 33 | 34 | resize() {} 35 | } 36 | 37 | class Material extends RawShaderMaterial { 38 | constructor(options) { 39 | super({ 40 | vertexShader, 41 | fragmentShader, 42 | side: DoubleSide, 43 | wireframe: true, 44 | transparent: true, 45 | uniforms: { 46 | u_time: { value: options?.u_time || 0 }, 47 | u_t1: { value: options?.u_t1 || null }, 48 | }, 49 | }); 50 | } 51 | 52 | set time(t) { 53 | this.uniforms.u_time.value = t; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/instance/utils.js: -------------------------------------------------------------------------------- 1 | import { InstancedBufferAttribute } from "three"; 2 | 3 | // * utils 4 | export function calcAttributes(num) { 5 | const a_rot = new Float32Array(num * 1); 6 | const a_pos = new Float32Array(num * 3); 7 | 8 | for (let i = 0; i < num; i++) { 9 | a_rot.set([Math.random() - 0.5], i * 1); 10 | a_pos.set( 11 | [Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5], 12 | i * 3 13 | ); 14 | } 15 | 16 | return { 17 | a_rotation: { 18 | name: "a_rotation", 19 | data: new InstancedBufferAttribute(a_rot, 1), 20 | }, 21 | a_position: { 22 | name: "a_position", 23 | data: new InstancedBufferAttribute(a_pos, 3), 24 | }, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/instance/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | attribute vec3 a_position; 7 | uniform mat4 modelViewMatrix; 8 | uniform mat4 projectionMatrix; 9 | 10 | uniform float u_time; 11 | varying vec2 v_uv; 12 | 13 | 14 | void main() { 15 | vec3 pos = position; 16 | pos += a_position; 17 | 18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 19 | v_uv = uv; 20 | } 21 | 22 | 23 | /* 24 | vec4 m_pos = modelViewMatrix * vec4(position, 1.0); 25 | gl_PointSize = 1000. * (1. / -m_pos.z); 26 | gl_Position = projectionMatrix * m_pos; 27 | */ -------------------------------------------------------------------------------- /webgl/three-new/src/gl/post/base/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float opacity; 2 | uniform sampler2D tDiffuse; 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | gl_FragColor.rgb = texture2D( tDiffuse, vUv ).rgb; 7 | gl_FragColor.a = 1.; 8 | } 9 | 10 | 11 | /** post */ 12 | // gl_FragColor.rgb = ACESFilmicToneMapping(diff.rgb); 13 | // gl_FragColor.a = 1.; 14 | // gl_FragColor = linearToOutputTexel(gl_FragColor); -------------------------------------------------------------------------------- /webgl/three-new/src/gl/post/base/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js"; 2 | import fragmentShader from "./fragment.frag"; 3 | import vertexShader from "./vertex.vert"; 4 | 5 | export const CopyShader = { 6 | uniforms: { 7 | tDiffuse: { value: null }, 8 | opacity: { value: 1.0 }, 9 | }, 10 | vertexShader, 11 | fragmentShader, 12 | }; 13 | 14 | export class Shader extends ShaderPass { 15 | constructor() { 16 | super(CopyShader); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/post/base/vertex.vert: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | void main() { 3 | vUv = uv; 4 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 5 | } -------------------------------------------------------------------------------- /webgl/three-new/src/gl/post/index.js: -------------------------------------------------------------------------------- 1 | // import { Vector2 } from "three"; 2 | import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js"; 3 | import { RenderPass } from "three/addons/postprocessing/RenderPass.js"; 4 | 5 | import { Shader } from "./base"; 6 | import { Gl } from "../gl"; 7 | 8 | export class Post extends EffectComposer { 9 | isOn = true; 10 | 11 | constructor() { 12 | super(Gl.renderer); 13 | this.renderPass = new RenderPass(Gl.scene, Gl.camera); 14 | this.addPass(this.renderPass); 15 | this.createPasses(); 16 | } 17 | 18 | createPasses() { 19 | this.addPass(new Shader()); 20 | } 21 | 22 | renderPasses(t) {} 23 | 24 | // * 25 | renderPost() { 26 | if (this.isOn) { 27 | this.renderPasses(Gl.time); 28 | this.render(); 29 | } else { 30 | Gl.renderer.render(Gl.scene, Gl.camera); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/quad/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/quad/index.js: -------------------------------------------------------------------------------- 1 | import { Mesh, PlaneGeometry } from "three"; 2 | import { RawShaderMaterial, DoubleSide } from "three"; 3 | 4 | import vertexShader from "./vertex.vert"; 5 | import fragmentShader from "./fragment.frag"; 6 | 7 | export class Quad extends Mesh { 8 | geometry = new PlaneGeometry(1, 1, 1, 1); 9 | material = new Material(); 10 | 11 | constructor() { 12 | super(); 13 | } 14 | 15 | render(t) { 16 | // console.log(t); 17 | } 18 | } 19 | 20 | class Material extends RawShaderMaterial { 21 | constructor(options) { 22 | super({ 23 | vertexShader, 24 | fragmentShader, 25 | uniforms: { 26 | u_time: { value: options?.u_time || 0 }, 27 | u_t1: { value: options?.u_t1 || null }, 28 | }, 29 | side: DoubleSide, 30 | wireframe: false, 31 | transparent: true, 32 | }); 33 | } 34 | 35 | set time(t) { 36 | this.uniforms.u_time.value = t; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/quad/vertex.vert: -------------------------------------------------------------------------------- 1 | #include '../glsl/constants.glsl' 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | uniform mat4 modelViewMatrix; 7 | uniform mat4 projectionMatrix; 8 | 9 | uniform float u_time; 10 | varying vec2 v_uv; 11 | 12 | 13 | void main() { 14 | vec3 pos = position; 15 | 16 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 17 | v_uv = uv; 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/ray.js: -------------------------------------------------------------------------------- 1 | import { Raycaster, Vector2 } from "three"; 2 | import { Gl } from "@gl/gl"; 3 | 4 | export class Ray { 5 | casting = false; 6 | raycaster = new Raycaster(); 7 | pointer = new Vector2(); 8 | 9 | constructor(target, { casting } = {}) { 10 | this.target = target; 11 | this.casting = casting; 12 | 13 | console.log(Gl.camera, this); 14 | } 15 | 16 | set isCasting(value) { 17 | this.casting = value; 18 | } 19 | 20 | cast(reset = false) { 21 | if (!this.casting) return; 22 | this.pointer.x = Gl.mouse.ex; 23 | this.pointer.y = Gl.mouse.ey; 24 | 25 | this.raycaster.setFromCamera(this.pointer, Gl.camera); 26 | 27 | const intersects = this.raycaster.intersectObjects(this.target, false); 28 | // console.log(intersects); 29 | 30 | if (intersects.length > 0) { 31 | // console.log(intersects[0].point); 32 | 33 | if (reset) { 34 | this.casting = false; 35 | } 36 | 37 | return intersects[0].point; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/scenes/scene.js: -------------------------------------------------------------------------------- 1 | import { Scene } from "three"; 2 | import { Quad } from "../quad"; 3 | // import { Gl } from "./gl"; 4 | 5 | export default class extends Scene { 6 | isOn = true; 7 | 8 | constructor(vp) { 9 | super(); 10 | // this.vp = Gl.vp; 11 | 12 | this.create(); 13 | } 14 | 15 | create() { 16 | this.quad = new Quad(); 17 | this.add(this.quad); 18 | } 19 | 20 | render(t) { 21 | this.quad?.render(t); 22 | } 23 | 24 | resize(vp) { 25 | // this.vp = vp; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/cube-loader.js: -------------------------------------------------------------------------------- 1 | import { CubeTextureLoader, Math } from "three"; 2 | const tl = new CubeTextureLoader(); 3 | 4 | /* ORDER IS: px, nx, py, ny, pz, nz 5 | const { px, nx, py, ny, pz, nz } = IMPORTEDPATH; 6 | const cbmarr = [px, nx, py, ny, pz, nz] 7 | */ 8 | 9 | export default function loadCube(arr) { 10 | return new Promise((resolve) => { 11 | tl.load(arr, (data) => { 12 | data.needsUpdate = true; 13 | // console.log(data); 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // fragment using cubemap 20 | 21 | /* 22 | uniform samplerCube u_cube; 23 | 24 | // ... 25 | 26 | // cubemap 27 | vec3 R = reflect(vec3(0, 0, 8), normalize(v_coords.xyz)); 28 | // vec3 smp = sampledBlur(0.5, u_cube, R, 10); 29 | 30 | vec3 cube_map = 1. - textureCube(u_cube, v_coords.xyz).rgb; 31 | vec3 cube_map_r = textureCube(u_cube, R).rgb; 32 | float cube_map_l = (cube_map.r + cube_map.g + cube_map.b) / 3.; 33 | 34 | // col *= 1. - cube_map_l * .5; 35 | col *= 1. - cube_map_r * .1; 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/draco-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; 2 | import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; 3 | 4 | const decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.4.3/"; 5 | 6 | const dracoLoader = new DRACOLoader(); 7 | dracoLoader.setDecoderPath(decoderPath); // use a full url path 8 | dracoLoader.preload(); 9 | 10 | const loader = new GLTFLoader(); 11 | loader.setDRACOLoader(dracoLoader); 12 | 13 | export default (url) => { 14 | return new Promise((resolve, reject) => { 15 | loader.load(url, (gltf) => { 16 | const result = { model: gltf.scene }; 17 | resolve(result); 18 | }); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/index.js: -------------------------------------------------------------------------------- 1 | export function findGroup(obj) { 2 | if (obj.isGroup === true) { 3 | return obj; 4 | } 5 | 6 | for (const key in obj) { 7 | if (typeof obj[key] === "object") { 8 | const result = findGroup(obj[key]); 9 | if (result) { 10 | return result; 11 | } 12 | } 13 | } 14 | 15 | return null; 16 | } 17 | 18 | export function handleResize(container, cb) { 19 | new ResizeObserver((entry) => cb(entry[0].contentRect)).observe(container); 20 | } 21 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/loader.js: -------------------------------------------------------------------------------- 1 | import loadModel from "./model-loader"; 2 | import loadTexture from "./texture-loader"; 3 | import { assets as file } from "../assets"; 4 | 5 | export async function loadAssets(opt = null) { 6 | // console.time("assets::"); // !1 remove timer from here 7 | const assets = opt || file; 8 | 9 | const promises = []; 10 | const names = []; 11 | 12 | for (const key in assets) { 13 | const asset = assets[key]; 14 | 15 | const extension = asset.split(".").pop(); 16 | 17 | if (extension === "glb" || extension === "gltf") { 18 | promises.push(loadModel(asset)); 19 | } else if ( 20 | extension === "jpg" || 21 | extension === "png" || 22 | extension === "webp" || 23 | extension === "jpeg" // !2 we need to add the extension as it's not covered 24 | ) { 25 | promises.push(loadTexture(asset)); 26 | } 27 | 28 | names.push(key); 29 | } 30 | 31 | const loaded = await Promise.all(promises); 32 | 33 | const result = names.reduce((acc, key, index) => { 34 | acc[key] = loaded[index]; 35 | return acc; 36 | }, {}); 37 | 38 | // console.timeEnd("assets::"); 39 | 40 | return result; 41 | } 42 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/model-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; 2 | const loader = new GLTFLoader(); 3 | 4 | export default (url, id) => { 5 | return new Promise((resolve, reject) => { 6 | loader.load(url, (gltf) => { 7 | const result = { model: gltf.scene }; 8 | resolve(result); 9 | }); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /webgl/three-new/src/gl/utils/texture-loader.js: -------------------------------------------------------------------------------- 1 | import { TextureLoader } from "three"; 2 | const tl = new TextureLoader(); 3 | 4 | export default function loadTexture(url) { 5 | return new Promise((resolve) => { 6 | tl.load(url, (data) => { 7 | data.needsUpdate = true; 8 | 9 | // add sizes 10 | data.source.w = data.source.data.width; 11 | data.source.h = data.source.data.height; 12 | data.source.r = data.source.data.width / data.source.data.height; 13 | 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // this.texture = await loadTexture(dbgImg); 20 | -------------------------------------------------------------------------------- /webgl/three-new/src/gsap.js: -------------------------------------------------------------------------------- 1 | import gsap from "gsap"; 2 | 3 | const defaults = { 4 | duration: 1, 5 | ease: "expo.out", 6 | }; 7 | 8 | gsap.defaults(defaults); 9 | 10 | export default gsap; 11 | export { defaults }; 12 | -------------------------------------------------------------------------------- /webgl/three-new/src/utils/math.js: -------------------------------------------------------------------------------- 1 | // lerp 2 | export function lerp(v0, v1, t) { 3 | return v0 * (1 - t) + v1 * t; 4 | } 5 | 6 | // map 7 | export function map(value, low1, high1, low2, high2) { 8 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 9 | } 10 | 11 | // clamp 12 | export function clamp(min, max, num) { 13 | return Math.min(Math.max(num, min), max); 14 | } 15 | 16 | /** ------------ Angles **/ 17 | export function radToDeg(r) { 18 | return (r * 180) / Math.PI; 19 | } 20 | 21 | export function degToRad(d) { 22 | return (d * Math.PI) / 180; 23 | } 24 | 25 | /** ------------ Bitwise **/ 26 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 27 | -------------------------------------------------------------------------------- /webgl/three-new/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, 5 | Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | } 7 | canvas { 8 | display: block; 9 | } 10 | 11 | [data-gl="c"] { 12 | width: 100vw; 13 | height: 100vh; 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | } 18 | -------------------------------------------------------------------------------- /webgl/three-new/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { fileURLToPath, URL } from "url"; 3 | import glsl from "vite-plugin-glsl"; 4 | 5 | const alias = { 6 | "@src": fileURLToPath(new URL("./src", import.meta.url)), 7 | "@utils": fileURLToPath(new URL("./src/utils", import.meta.url)), 8 | "#gl": fileURLToPath(new URL("./src/gl", import.meta.url)), 9 | }; 10 | 11 | // plugins 12 | const plugins = [glsl()]; 13 | 14 | export default defineConfig({ 15 | assetsInclude: ["**/*.gltf"], 16 | plugins, 17 | resolve: { 18 | alias, 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /webgl/three-v2/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /webgl/three-v2/README.md: -------------------------------------------------------------------------------- 1 | ## Threejs Starter 2 | 3 | ## Todo 4 | 5 | - [ ] skin 6 | - [ ] post 7 | -------------------------------------------------------------------------------- /webgl/three-v2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | VVV 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/three-v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^5.2.12", 13 | "vite-plugin-glsl": "^1.3.0" 14 | }, 15 | "dependencies": { 16 | "three": "^0.165.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three-v2/src/app.js: -------------------------------------------------------------------------------- 1 | import Dom from "./modules/dom"; 2 | import Viewport from "./modules/viewport"; 3 | import { Gl } from "./gl/gl"; 4 | 5 | class App { 6 | time = 0; 7 | constructor() { 8 | this.body = document.querySelector("body"); 9 | this.viewport = new Viewport(); 10 | 11 | this.init(); 12 | } 13 | 14 | init() { 15 | this.dom = new Dom(); 16 | 17 | this.gl = new Gl(); 18 | 19 | this.initEvents(); 20 | this.render(); 21 | } 22 | 23 | initEvents() { 24 | // prettier-ignore 25 | new ResizeObserver((entry) => this.resize(entry[0])).observe(this.body); 26 | } 27 | 28 | resize({ contentRect }) { 29 | this.viewport?.resize(); 30 | this.dom?.resize(); 31 | } 32 | 33 | render() { 34 | this.time += 0.1; 35 | 36 | this.gl?.render(this.time); 37 | 38 | window.requestAnimationFrame(this.render.bind(this)); 39 | } 40 | 41 | /* Events */ 42 | } 43 | 44 | window.app = new App(); 45 | -------------------------------------------------------------------------------- /webgl/three-v2/src/assets/index.js: -------------------------------------------------------------------------------- 1 | export const ASSETS = { 2 | // img: null, 3 | }; 4 | -------------------------------------------------------------------------------- /webgl/three-v2/src/assets/uvH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three-v2/src/assets/uvH.jpg -------------------------------------------------------------------------------- /webgl/three-v2/src/assets/uvV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three-v2/src/assets/uvV.jpg -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/_instance.js: -------------------------------------------------------------------------------- 1 | import { InstancedMesh, PlaneGeometry, InstancedBufferAttribute } from "three"; 2 | import Material from "./mat/instance-raw"; 3 | 4 | export class Instance extends InstancedMesh { 5 | constructor(data = {}) { 6 | super(); 7 | 8 | this.count = 10; 9 | this.geometry = new PlaneGeometry(1, 1, 1, 1); 10 | this.setAttributes(); 11 | this.material = new Material(); 12 | } 13 | 14 | setAttributes() { 15 | const attributes = calcAttributes(this.count); 16 | for (const key in attributes) { 17 | const { name, data } = attributes[key]; 18 | this.geometry.setAttribute(name, data); 19 | } 20 | } 21 | 22 | render(t) {} 23 | 24 | resize() {} 25 | } 26 | 27 | function calcAttributes(num) { 28 | const a_rot = new Float32Array(num * 1); 29 | const a_pos = new Float32Array(num * 3); 30 | 31 | for (let i = 0; i < num; i++) { 32 | a_rot.set([Math.random() - 0.5], i * 1); 33 | a_pos.set( 34 | [Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5], 35 | i * 3 36 | ); 37 | } 38 | 39 | return { 40 | a_rotation: { 41 | name: "a_rotation", 42 | data: new InstancedBufferAttribute(a_rot, 1), 43 | }, 44 | a_position: { 45 | name: "a_position", 46 | data: new InstancedBufferAttribute(a_pos, 3), 47 | }, 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/_quad.js: -------------------------------------------------------------------------------- 1 | import { Mesh, PlaneGeometry } from "three"; 2 | import PlaneMaterial from "./mat/raw"; 3 | 4 | export class Quad extends Mesh { 5 | constructor(data = {}) { 6 | super(); 7 | this.data = data; 8 | 9 | this.geometry = new PlaneGeometry(1, 1, 1, 1); 10 | this.material = new PlaneMaterial(); 11 | } 12 | 13 | render(t) { 14 | // console.log(t); 15 | } 16 | } 17 | 18 | function findGroup(obj) { 19 | if (obj.isGroup === true) { 20 | return obj; 21 | } 22 | 23 | for (const key in obj) { 24 | if (typeof obj[key] === "object") { 25 | const result = findGroup(obj[key]); 26 | if (result) { 27 | return result; 28 | } 29 | } 30 | } 31 | 32 | return null; 33 | } 34 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/basic/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float u_time; 2 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 3 | 4 | varying vec2 v_uv; 5 | // varying vec3 vPosition; 6 | 7 | 8 | void main() { 9 | 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/basic/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends ShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/basic/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | 3 | uniform float u_time; 4 | varying vec2 v_uv; 5 | 6 | 7 | void main() { 8 | vec3 pos = position; 9 | 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 11 | v_uv = uv; 12 | } 13 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/chunk/imageuv.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Resize image to Cover 3 | uv : uv coord 4 | size : image size 5 | resolution : plane resolution | screen resolution 6 | */ 7 | 8 | vec2 imageuv(vec2 uv, vec2 size, vec2 resolution) { 9 | vec2 ratio = vec2( 10 | min((resolution.x / resolution.y) / (size.x / size.y), 1.0), 11 | min((resolution.y / resolution.x) / (size.y / size.x), 1.0) 12 | ); 13 | 14 | return vec2( 15 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 16 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 17 | ); 18 | } -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/chunk/rand.glsl: -------------------------------------------------------------------------------- 1 | float rand(vec2 co){ 2 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 3 | } -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/chunk/rotate3d.glsl: -------------------------------------------------------------------------------- 1 | mat4 rotationMatrix(vec3 axis, float angle) { 2 | axis = normalize(axis); 3 | float s = sin(angle); 4 | float c = cos(angle); 5 | float oc = 1.0 - c; 6 | 7 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 8 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 9 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 10 | 0.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | vec3 rotate3d(vec3 v, vec3 axis, float angle) { 14 | mat4 m = rotationMatrix(axis, angle); 15 | return (m * vec4(v, 1.0)).xyz; 16 | } -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/instance-raw/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/instance-raw/index.js: -------------------------------------------------------------------------------- 1 | import { RawShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends RawShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/instance-raw/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | attribute vec3 a_position; 7 | uniform mat4 modelViewMatrix; 8 | uniform mat4 projectionMatrix; 9 | 10 | uniform float u_time; 11 | varying vec2 v_uv; 12 | 13 | 14 | void main() { 15 | vec3 pos = position; 16 | pos += a_position; 17 | 18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 19 | v_uv = uv; 20 | } 21 | 22 | 23 | /* 24 | vec4 m_pos = modelViewMatrix * vec4(position, 1.0); 25 | gl_PointSize = 1000. * (1. / -m_pos.z); 26 | gl_Position = projectionMatrix * m_pos; 27 | */ -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/post/base/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float opacity; 2 | uniform sampler2D tDiffuse; 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | gl_FragColor.rgb = texture2D( tDiffuse, vUv ).rgb; 7 | gl_FragColor.a = 1.; 8 | } 9 | 10 | 11 | /** post */ 12 | // gl_FragColor.rgb = ACESFilmicToneMapping(diff.rgb); 13 | // gl_FragColor.a = 1.; 14 | // gl_FragColor = linearToOutputTexel(gl_FragColor); -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/post/base/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js"; 2 | import fragmentShader from "./fragment.frag"; 3 | import vertexShader from "./vertex.vert"; 4 | 5 | export const CopyShader = { 6 | uniforms: { 7 | tDiffuse: { value: null }, 8 | opacity: { value: 1.0 }, 9 | }, 10 | vertexShader, 11 | fragmentShader, 12 | }; 13 | 14 | export class Shader extends ShaderPass { 15 | constructor() { 16 | super(CopyShader); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/post/base/vertex.vert: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | void main() { 3 | vUv = uv; 4 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 5 | } -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/raw/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/raw/index.js: -------------------------------------------------------------------------------- 1 | import { RawShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends RawShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/mat/raw/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | uniform mat4 modelViewMatrix; 7 | uniform mat4 projectionMatrix; 8 | 9 | uniform float u_time; 10 | varying vec2 v_uv; 11 | 12 | 13 | void main() { 14 | vec3 pos = position; 15 | 16 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 17 | v_uv = uv; 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/post.js: -------------------------------------------------------------------------------- 1 | // import { Vector2 } from "three"; 2 | import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js"; 3 | import { RenderPass } from "three/addons/postprocessing/RenderPass.js"; 4 | 5 | import { Shader } from "./mat/post/base"; 6 | 7 | export class Post extends EffectComposer { 8 | constructor({ renderer, scene, camera }) { 9 | super(renderer); 10 | this.isOn = true; 11 | this.renderer = renderer; 12 | 13 | this.renderPass = new RenderPass(scene, camera); 14 | this.addPass(this.renderPass); 15 | 16 | this.createPasses(); 17 | } 18 | 19 | createPasses() { 20 | this.addPass(new Shader()); 21 | } 22 | 23 | renderPasses(t) {} 24 | } 25 | 26 | /* 27 | if (this.post?.isOn) { 28 | this.post.renderPasses(this.time); 29 | this.post.render(); 30 | } else { 31 | this.renderer.render(this.scene, this.camera); 32 | } 33 | */ 34 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/scene.js: -------------------------------------------------------------------------------- 1 | import { Scene } from "three"; 2 | import { Quad } from "./_quad.js"; 3 | 4 | export default class extends Scene { 5 | constructor(vp, {} = {}) { 6 | super(); 7 | this.vp = vp; 8 | 9 | this.create(); 10 | } 11 | 12 | create() { 13 | this.quad = new Quad(); 14 | this.add(this.quad); 15 | } 16 | 17 | render(t) { 18 | if (this.quad) this.quad.render(t); 19 | } 20 | 21 | resize(vp) { 22 | this.vp = vp; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/util/cube-loader.js: -------------------------------------------------------------------------------- 1 | import { CubeTextureLoader, Math } from "three"; 2 | const tl = new CubeTextureLoader(); 3 | 4 | /* ORDER IS: px, nx, py, ny, pz, nz 5 | const { px, nx, py, ny, pz, nz } = IMPORTEDPATH; 6 | const cbmarr = [px, nx, py, ny, pz, nz] 7 | */ 8 | 9 | export default function loadCube(arr) { 10 | return new Promise((resolve) => { 11 | tl.load(arr, (data) => { 12 | data.needsUpdate = true; 13 | // console.log(data); 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // fragment using cubemap 20 | 21 | /* 22 | uniform samplerCube u_cube; 23 | 24 | // ... 25 | 26 | // cubemap 27 | vec3 R = reflect(vec3(0, 0, 8), normalize(v_coords.xyz)); 28 | // vec3 smp = sampledBlur(0.5, u_cube, R, 10); 29 | 30 | vec3 cube_map = 1. - textureCube(u_cube, v_coords.xyz).rgb; 31 | vec3 cube_map_r = textureCube(u_cube, R).rgb; 32 | float cube_map_l = (cube_map.r + cube_map.g + cube_map.b) / 3.; 33 | 34 | // col *= 1. - cube_map_l * .5; 35 | col *= 1. - cube_map_r * .1; 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/util/draco-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; 2 | import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; 3 | 4 | const decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.4.3/"; 5 | 6 | const dracoLoader = new DRACOLoader(); 7 | dracoLoader.setDecoderPath(decoderPath); // use a full url path 8 | dracoLoader.preload(); 9 | 10 | const loader = new GLTFLoader(); 11 | loader.setDRACOLoader(dracoLoader); 12 | 13 | export default (url) => { 14 | return new Promise((resolve, reject) => { 15 | loader.load(url, (gltf) => { 16 | const result = { model: gltf.scene }; 17 | resolve(result); 18 | }); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/util/loader.js: -------------------------------------------------------------------------------- 1 | import loadModel from "./model-loader"; 2 | import loadTexture from "./texture-loader"; 3 | import { assets as file } from "../assets"; 4 | 5 | export async function loadAssets(opt = null) { 6 | // console.time("assets::"); // !1 remove timer from here 7 | const assets = opt || file; 8 | 9 | const promises = []; 10 | const names = []; 11 | 12 | for (const key in assets) { 13 | const asset = assets[key]; 14 | 15 | const extension = asset.split(".").pop(); 16 | 17 | if (extension === "glb" || extension === "gltf") { 18 | promises.push(loadModel(asset)); 19 | } else if ( 20 | extension === "jpg" || 21 | extension === "png" || 22 | extension === "webp" || 23 | extension === "jpeg" // !2 we need to add the extension as it's not covered 24 | ) { 25 | promises.push(loadTexture(asset)); 26 | } 27 | 28 | names.push(key); 29 | } 30 | 31 | const loaded = await Promise.all(promises); 32 | 33 | const result = names.reduce((acc, key, index) => { 34 | acc[key] = loaded[index]; 35 | return acc; 36 | }, {}); 37 | 38 | // console.timeEnd("assets::"); 39 | 40 | return result; 41 | } 42 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/util/model-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; 2 | const loader = new GLTFLoader(); 3 | 4 | export default (url, id) => { 5 | return new Promise((resolve, reject) => { 6 | loader.load(url, (gltf) => { 7 | const result = { model: gltf.scene }; 8 | resolve(result); 9 | }); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /webgl/three-v2/src/gl/util/texture-loader.js: -------------------------------------------------------------------------------- 1 | import { TextureLoader } from "three"; 2 | const tl = new TextureLoader(); 3 | 4 | export default function loadTexture(url) { 5 | return new Promise((resolve) => { 6 | tl.load(url, (data) => { 7 | data.needsUpdate = true; 8 | 9 | // add sizes 10 | data.source.w = data.source.data.width; 11 | data.source.h = data.source.data.height; 12 | data.source.r = data.source.data.width / data.source.data.height; 13 | 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // this.texture = await loadTexture(dbgImg); 20 | -------------------------------------------------------------------------------- /webgl/three-v2/src/modules/dom.js: -------------------------------------------------------------------------------- 1 | // import { Observe } from "@u/observe.js"; 2 | 3 | export default class { 4 | constructor() { 5 | // console.log("dom"); 6 | } 7 | 8 | resize() {} 9 | } 10 | -------------------------------------------------------------------------------- /webgl/three-v2/src/modules/gui.js: -------------------------------------------------------------------------------- 1 | import LilGui from "lil-gui"; 2 | 3 | export class Gui extends LilGui { 4 | constructor() { 5 | super(); 6 | this.initControllers(); 7 | this.initWindowGui(); 8 | window.gui = this; 9 | 10 | this.close(); 11 | } 12 | 13 | initControllers() { 14 | this.val = { 15 | anim: { 16 | timeline: 0, 17 | }, 18 | }; 19 | } 20 | 21 | initWindowGui() { 22 | for (const key in this.val) { 23 | const fold = this.addFolder(key); 24 | fold.close(); 25 | 26 | for (const key2 in this.val[key]) { 27 | fold.add(this.val[key], key2, 0, 1, 0.001); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webgl/three-v2/src/modules/lenis.js: -------------------------------------------------------------------------------- 1 | // import Lenis from "@studio-freight/lenis"; 2 | 3 | export default class { 4 | constructor() {} 5 | 6 | resize() {} 7 | 8 | render(t) {} 9 | } 10 | 11 | /* 12 | 13 | const lenis = new Lenis({ 14 | duration: 1.2, 15 | easing: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)), // https://easings.net 16 | direction: "vertical", 17 | smooth: true, 18 | smoothTouch: false, 19 | touchMultiplier: 2, 20 | }); 21 | 22 | //get scroll value 23 | lenis.on("scroll", ({ scroll, limit, velocity, direction, progress }) => { 24 | console.log({ scroll, limit, velocity, direction, progress }); 25 | }); 26 | 27 | function raf(time) { 28 | lenis.raf(time); 29 | requestAnimationFrame(raf); 30 | } 31 | 32 | requestAnimationFrame(raf); 33 | 34 | 35 | */ 36 | -------------------------------------------------------------------------------- /webgl/three-v2/src/modules/pages.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() {} 3 | } 4 | -------------------------------------------------------------------------------- /webgl/three-v2/src/modules/viewport.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() { 3 | this.resize(); 4 | } 5 | 6 | resize() { 7 | // set CSS vh var 8 | document.documentElement.style.setProperty( 9 | "--100vh", 10 | `${window.innerHeight}px` 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three-v2/src/style/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, 5 | Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | } 7 | canvas { 8 | display: block; 9 | } 10 | 11 | [data-gl="c"] { 12 | width: 100vw; 13 | height: 100vh; 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | } 18 | -------------------------------------------------------------------------------- /webgl/three-v2/src/util/math.js: -------------------------------------------------------------------------------- 1 | // lerp 2 | export function lerp(v0, v1, t) { 3 | return v0 * (1 - t) + v1 * t; 4 | } 5 | 6 | // map 7 | export function map(value, low1, high1, low2, high2) { 8 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 9 | } 10 | 11 | // clamp 12 | export function clamp(min, max, num) { 13 | return Math.min(Math.max(num, min), max); 14 | } 15 | 16 | /** ------------ Angles **/ 17 | export function radToDeg(r) { 18 | return (r * 180) / Math.PI; 19 | } 20 | 21 | export function degToRad(d) { 22 | return (d * Math.PI) / 180; 23 | } 24 | 25 | /** ------------ Bitwise **/ 26 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 27 | -------------------------------------------------------------------------------- /webgl/three/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /webgl/three/README.md: -------------------------------------------------------------------------------- 1 | ## Threejs Starter 2 | 3 | ## Todo 4 | 5 | - [ ] skin 6 | - [ ] post 7 | -------------------------------------------------------------------------------- /webgl/three/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | VVV 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/three/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^4.3.5", 13 | "vite-plugin-glsl": "^1.1.2" 14 | }, 15 | "dependencies": { 16 | "three": "^0.152.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three/src/app.js: -------------------------------------------------------------------------------- 1 | import Dom from "./modules/dom"; 2 | import Viewport from "./modules/viewport"; 3 | import { Gl } from "./gl/gl"; 4 | 5 | class App { 6 | time = 0; 7 | constructor() { 8 | this.body = document.querySelector("body"); 9 | this.viewport = new Viewport(); 10 | 11 | this.init(); 12 | } 13 | 14 | init() { 15 | this.dom = new Dom(); 16 | 17 | this.gl = new Gl(); 18 | 19 | this.initEvents(); 20 | this.render(); 21 | } 22 | 23 | initEvents() { 24 | // prettier-ignore 25 | new ResizeObserver((entry) => this.resize(entry[0])).observe(this.body); 26 | } 27 | 28 | resize({ contentRect }) { 29 | this.viewport?.resize(); 30 | this.dom?.resize(); 31 | } 32 | 33 | render() { 34 | this.time += 0.1; 35 | 36 | this.gl?.render(this.time); 37 | 38 | window.requestAnimationFrame(this.render.bind(this)); 39 | } 40 | 41 | /* Events */ 42 | } 43 | 44 | window.app = new App(); 45 | -------------------------------------------------------------------------------- /webgl/three/src/assets/index.js: -------------------------------------------------------------------------------- 1 | export const ASSETS = { 2 | // img: null, 3 | }; 4 | -------------------------------------------------------------------------------- /webgl/three/src/assets/uvH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three/src/assets/uvH.jpg -------------------------------------------------------------------------------- /webgl/three/src/assets/uvV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/three/src/assets/uvV.jpg -------------------------------------------------------------------------------- /webgl/three/src/gl/_instance.js: -------------------------------------------------------------------------------- 1 | import { InstancedMesh, PlaneGeometry, InstancedBufferAttribute } from "three"; 2 | import Material from "./mat/instance-raw"; 3 | 4 | export class Instance extends InstancedMesh { 5 | constructor(data = {}) { 6 | super(); 7 | 8 | this.count = 10; 9 | this.geometry = new PlaneGeometry(1, 1, 1, 1); 10 | this.setAttributes(); 11 | this.material = new Material(); 12 | } 13 | 14 | setAttributes() { 15 | const attributes = calcAttributes(this.count); 16 | for (const key in attributes) { 17 | const { name, data } = attributes[key]; 18 | this.geometry.setAttribute(name, data); 19 | } 20 | } 21 | 22 | render(t) {} 23 | 24 | resize() {} 25 | } 26 | 27 | function calcAttributes(num) { 28 | const a_rot = new Float32Array(num * 1); 29 | const a_pos = new Float32Array(num * 3); 30 | 31 | for (let i = 0; i < num; i++) { 32 | a_rot.set([Math.random() - 0.5], i * 1); 33 | a_pos.set( 34 | [Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5], 35 | i * 3 36 | ); 37 | } 38 | 39 | return { 40 | a_rotation: { 41 | name: "a_rotation", 42 | data: new InstancedBufferAttribute(a_rot, 1), 43 | }, 44 | a_position: { 45 | name: "a_position", 46 | data: new InstancedBufferAttribute(a_pos, 3), 47 | }, 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /webgl/three/src/gl/_quad.js: -------------------------------------------------------------------------------- 1 | import { Mesh, PlaneGeometry } from "three"; 2 | import PlaneMaterial from "./mat/raw"; 3 | 4 | export class Quad extends Mesh { 5 | constructor(data = {}) { 6 | super(); 7 | this.data = data; 8 | 9 | this.geometry = new PlaneGeometry(1, 1, 1, 1); 10 | this.material = new PlaneMaterial(); 11 | } 12 | 13 | render(t) { 14 | // console.log(t); 15 | } 16 | } 17 | 18 | function findGroup(obj) { 19 | if (obj.isGroup === true) { 20 | return obj; 21 | } 22 | 23 | for (const key in obj) { 24 | if (typeof obj[key] === "object") { 25 | const result = findGroup(obj[key]); 26 | if (result) { 27 | return result; 28 | } 29 | } 30 | } 31 | 32 | return null; 33 | } 34 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/basic/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float u_time; 2 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 3 | 4 | varying vec2 v_uv; 5 | // varying vec3 vPosition; 6 | 7 | 8 | void main() { 9 | 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/basic/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends ShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/basic/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | 3 | uniform float u_time; 4 | varying vec2 v_uv; 5 | 6 | 7 | void main() { 8 | vec3 pos = position; 9 | 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 11 | v_uv = uv; 12 | } 13 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/chunk/imageuv.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Resize image to Cover 3 | uv : uv coord 4 | size : image size 5 | resolution : plane resolution | screen resolution 6 | */ 7 | 8 | vec2 imageuv(vec2 uv, vec2 size, vec2 resolution) { 9 | vec2 ratio = vec2( 10 | min((resolution.x / resolution.y) / (size.x / size.y), 1.0), 11 | min((resolution.y / resolution.x) / (size.y / size.x), 1.0) 12 | ); 13 | 14 | return vec2( 15 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 16 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 17 | ); 18 | } -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/chunk/rand.glsl: -------------------------------------------------------------------------------- 1 | float rand(vec2 co){ 2 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 3 | } -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/chunk/rotate3d.glsl: -------------------------------------------------------------------------------- 1 | mat4 rotationMatrix(vec3 axis, float angle) { 2 | axis = normalize(axis); 3 | float s = sin(angle); 4 | float c = cos(angle); 5 | float oc = 1.0 - c; 6 | 7 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 8 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 9 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 10 | 0.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | vec3 rotate3d(vec3 v, vec3 axis, float angle) { 14 | mat4 m = rotationMatrix(axis, angle); 15 | return (m * vec4(v, 1.0)).xyz; 16 | } -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/instance-raw/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/instance-raw/index.js: -------------------------------------------------------------------------------- 1 | import { RawShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends RawShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/instance-raw/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | attribute vec3 a_position; 7 | uniform mat4 modelViewMatrix; 8 | uniform mat4 projectionMatrix; 9 | 10 | uniform float u_time; 11 | varying vec2 v_uv; 12 | 13 | 14 | void main() { 15 | vec3 pos = position; 16 | pos += a_position; 17 | 18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 19 | v_uv = uv; 20 | } 21 | 22 | 23 | /* 24 | vec4 m_pos = modelViewMatrix * vec4(position, 1.0); 25 | gl_PointSize = 1000. * (1. / -m_pos.z); 26 | gl_Position = projectionMatrix * m_pos; 27 | */ -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/post/base/fragment.frag: -------------------------------------------------------------------------------- 1 | uniform float opacity; 2 | uniform sampler2D tDiffuse; 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | gl_FragColor.rgb = texture2D( tDiffuse, vUv ).rgb; 7 | gl_FragColor.a = 1.; 8 | } 9 | 10 | 11 | /** post */ 12 | // gl_FragColor.rgb = ACESFilmicToneMapping(diff.rgb); 13 | // gl_FragColor.a = 1.; 14 | // gl_FragColor = linearToOutputTexel(gl_FragColor); -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/post/base/index.js: -------------------------------------------------------------------------------- 1 | import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js"; 2 | import fragmentShader from "./fragment.frag"; 3 | import vertexShader from "./vertex.vert"; 4 | 5 | export const CopyShader = { 6 | uniforms: { 7 | tDiffuse: { value: null }, 8 | opacity: { value: 1.0 }, 9 | }, 10 | vertexShader, 11 | fragmentShader, 12 | }; 13 | 14 | export class Shader extends ShaderPass { 15 | constructor() { 16 | super(CopyShader); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/post/base/vertex.vert: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | void main() { 3 | vUv = uv; 4 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 5 | } -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/raw/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform float u_time; 4 | // uniform sampler2D u_t1; vec4 img = texture2D(u_t1, v_uv); 5 | 6 | varying vec2 v_uv; 7 | 8 | 9 | void main() { 10 | 11 | gl_FragColor = vec4(v_uv, 0., 1.); 12 | // gl_FragColor = vec4(1., 0., 0., 1.); 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/raw/index.js: -------------------------------------------------------------------------------- 1 | import { RawShaderMaterial, DoubleSide } from "three"; 2 | 3 | import vertexShader from "./vertex.vert"; 4 | import fragmentShader from "./fragment.frag"; 5 | 6 | export default class extends RawShaderMaterial { 7 | constructor(options) { 8 | super({ 9 | vertexShader, 10 | fragmentShader, 11 | }); 12 | 13 | this.uniforms = { 14 | u_time: { value: options?.u_time || 0 }, 15 | u_t1: { value: options?.u_t1 || null }, 16 | }; 17 | 18 | this.side = DoubleSide; 19 | // this.wireframe= true; 20 | // this.transparent= true; 21 | } 22 | 23 | set time(t) { 24 | this.uniforms.u_time.value = t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webgl/three/src/gl/mat/raw/vertex.vert: -------------------------------------------------------------------------------- 1 | #define MPI 3.1415926535897932384626433832795 2 | // precision mediump float; 3 | 4 | attribute vec3 position; 5 | attribute vec2 uv; 6 | uniform mat4 modelViewMatrix; 7 | uniform mat4 projectionMatrix; 8 | 9 | uniform float u_time; 10 | varying vec2 v_uv; 11 | 12 | 13 | void main() { 14 | vec3 pos = position; 15 | 16 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); 17 | v_uv = uv; 18 | } 19 | -------------------------------------------------------------------------------- /webgl/three/src/gl/post.js: -------------------------------------------------------------------------------- 1 | // import { Vector2 } from "three"; 2 | import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js"; 3 | import { RenderPass } from "three/addons/postprocessing/RenderPass.js"; 4 | 5 | import { Shader } from "./mat/post/base"; 6 | 7 | export class Post extends EffectComposer { 8 | constructor({ renderer, scene, camera }) { 9 | super(renderer); 10 | this.isOn = true; 11 | this.renderer = renderer; 12 | 13 | this.renderPass = new RenderPass(scene, camera); 14 | this.addPass(this.renderPass); 15 | 16 | this.createPasses(); 17 | } 18 | 19 | createPasses() { 20 | this.addPass(new Shader()); 21 | } 22 | 23 | renderPasses(t) {} 24 | } 25 | 26 | /* 27 | if (this.post?.isOn) { 28 | this.post.renderPasses(this.time); 29 | this.post.render(); 30 | } else { 31 | this.renderer.render(this.scene, this.camera); 32 | } 33 | */ 34 | -------------------------------------------------------------------------------- /webgl/three/src/gl/scene.js: -------------------------------------------------------------------------------- 1 | import { Scene } from "three"; 2 | import { Quad } from "./_quad.js"; 3 | 4 | export default class extends Scene { 5 | constructor(vp, {} = {}) { 6 | super(); 7 | this.vp = vp; 8 | 9 | this.create(); 10 | } 11 | 12 | create() { 13 | this.quad = new Quad(); 14 | this.add(this.quad); 15 | } 16 | 17 | render(t) { 18 | if (this.quad) this.quad.render(t); 19 | } 20 | 21 | resize(vp) { 22 | this.vp = vp; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webgl/three/src/gl/util/cube-loader.js: -------------------------------------------------------------------------------- 1 | import { CubeTextureLoader, Math } from "three"; 2 | const tl = new CubeTextureLoader(); 3 | 4 | /* ORDER IS: px, nx, py, ny, pz, nz 5 | const { px, nx, py, ny, pz, nz } = IMPORTEDPATH; 6 | const cbmarr = [px, nx, py, ny, pz, nz] 7 | */ 8 | 9 | export default function loadCube(arr) { 10 | return new Promise((resolve) => { 11 | tl.load(arr, (data) => { 12 | data.needsUpdate = true; 13 | // console.log(data); 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // fragment using cubemap 20 | 21 | /* 22 | uniform samplerCube u_cube; 23 | 24 | // ... 25 | 26 | // cubemap 27 | vec3 R = reflect(vec3(0, 0, 8), normalize(v_coords.xyz)); 28 | // vec3 smp = sampledBlur(0.5, u_cube, R, 10); 29 | 30 | vec3 cube_map = 1. - textureCube(u_cube, v_coords.xyz).rgb; 31 | vec3 cube_map_r = textureCube(u_cube, R).rgb; 32 | float cube_map_l = (cube_map.r + cube_map.g + cube_map.b) / 3.; 33 | 34 | // col *= 1. - cube_map_l * .5; 35 | col *= 1. - cube_map_r * .1; 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /webgl/three/src/gl/util/draco-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; 2 | import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; 3 | 4 | const decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.4.3/"; 5 | 6 | const dracoLoader = new DRACOLoader(); 7 | dracoLoader.setDecoderPath(decoderPath); // use a full url path 8 | dracoLoader.preload(); 9 | 10 | const loader = new GLTFLoader(); 11 | loader.setDRACOLoader(dracoLoader); 12 | 13 | export default (url) => { 14 | return new Promise((resolve, reject) => { 15 | loader.load(url, (gltf) => { 16 | const result = { model: gltf.scene }; 17 | resolve(result); 18 | }); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /webgl/three/src/gl/util/loader.js: -------------------------------------------------------------------------------- 1 | import loadModel from "./model-loader"; 2 | import loadTexture from "./texture-loader"; 3 | import { assets as file } from "../assets"; 4 | 5 | export async function loadAssets(opt = null) { 6 | // console.time("assets::"); // !1 remove timer from here 7 | const assets = opt || file; 8 | 9 | const promises = []; 10 | const names = []; 11 | 12 | for (const key in assets) { 13 | const asset = assets[key]; 14 | 15 | const extension = asset.split(".").pop(); 16 | 17 | if (extension === "glb" || extension === "gltf") { 18 | promises.push(loadModel(asset)); 19 | } else if ( 20 | extension === "jpg" || 21 | extension === "png" || 22 | extension === "webp" || 23 | extension === "jpeg" // !2 we need to add the extension as it's not covered 24 | ) { 25 | promises.push(loadTexture(asset)); 26 | } 27 | 28 | names.push(key); 29 | } 30 | 31 | const loaded = await Promise.all(promises); 32 | 33 | const result = names.reduce((acc, key, index) => { 34 | acc[key] = loaded[index]; 35 | return acc; 36 | }, {}); 37 | 38 | // console.timeEnd("assets::"); 39 | 40 | return result; 41 | } 42 | -------------------------------------------------------------------------------- /webgl/three/src/gl/util/model-loader.js: -------------------------------------------------------------------------------- 1 | import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; 2 | const loader = new GLTFLoader(); 3 | 4 | export default (url, id) => { 5 | return new Promise((resolve, reject) => { 6 | loader.load(url, (gltf) => { 7 | const result = { model: gltf.scene }; 8 | resolve(result); 9 | }); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /webgl/three/src/gl/util/texture-loader.js: -------------------------------------------------------------------------------- 1 | import { TextureLoader } from "three"; 2 | const tl = new TextureLoader(); 3 | 4 | export default function loadTexture(url) { 5 | return new Promise((resolve) => { 6 | tl.load(url, (data) => { 7 | data.needsUpdate = true; 8 | 9 | // add sizes 10 | data.source.w = data.source.data.width; 11 | data.source.h = data.source.data.height; 12 | data.source.r = data.source.data.width / data.source.data.height; 13 | 14 | resolve(data); 15 | }); 16 | }); 17 | } 18 | 19 | // this.texture = await loadTexture(dbgImg); 20 | -------------------------------------------------------------------------------- /webgl/three/src/modules/dom.js: -------------------------------------------------------------------------------- 1 | // import { Observe } from "@u/observe.js"; 2 | 3 | export default class { 4 | constructor() { 5 | // console.log("dom"); 6 | } 7 | 8 | resize() {} 9 | } 10 | -------------------------------------------------------------------------------- /webgl/three/src/modules/gui.js: -------------------------------------------------------------------------------- 1 | import LilGui from "lil-gui"; 2 | 3 | export class Gui extends LilGui { 4 | constructor() { 5 | super(); 6 | this.initControllers(); 7 | this.initWindowGui(); 8 | window.gui = this; 9 | 10 | this.close(); 11 | } 12 | 13 | initControllers() { 14 | this.val = { 15 | anim: { 16 | timeline: 0, 17 | }, 18 | }; 19 | } 20 | 21 | initWindowGui() { 22 | for (const key in this.val) { 23 | const fold = this.addFolder(key); 24 | fold.close(); 25 | 26 | for (const key2 in this.val[key]) { 27 | fold.add(this.val[key], key2, 0, 1, 0.001); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webgl/three/src/modules/lenis.js: -------------------------------------------------------------------------------- 1 | // import Lenis from "@studio-freight/lenis"; 2 | 3 | export default class { 4 | constructor() {} 5 | 6 | resize() {} 7 | 8 | render(t) {} 9 | } 10 | 11 | /* 12 | 13 | const lenis = new Lenis({ 14 | duration: 1.2, 15 | easing: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)), // https://easings.net 16 | direction: "vertical", 17 | smooth: true, 18 | smoothTouch: false, 19 | touchMultiplier: 2, 20 | }); 21 | 22 | //get scroll value 23 | lenis.on("scroll", ({ scroll, limit, velocity, direction, progress }) => { 24 | console.log({ scroll, limit, velocity, direction, progress }); 25 | }); 26 | 27 | function raf(time) { 28 | lenis.raf(time); 29 | requestAnimationFrame(raf); 30 | } 31 | 32 | requestAnimationFrame(raf); 33 | 34 | 35 | */ 36 | -------------------------------------------------------------------------------- /webgl/three/src/modules/pages.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() {} 3 | } 4 | -------------------------------------------------------------------------------- /webgl/three/src/modules/viewport.js: -------------------------------------------------------------------------------- 1 | export default class { 2 | constructor() { 3 | this.resize(); 4 | } 5 | 6 | resize() { 7 | // set CSS vh var 8 | document.documentElement.style.setProperty( 9 | "--100vh", 10 | `${window.innerHeight}px` 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /webgl/three/src/style/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, 5 | Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | } 7 | canvas { 8 | display: block; 9 | } 10 | 11 | [data-gl="c"] { 12 | width: 100vw; 13 | height: 100vh; 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | } 18 | -------------------------------------------------------------------------------- /webgl/three/src/util/math.js: -------------------------------------------------------------------------------- 1 | // lerp 2 | export function lerp(v0, v1, t) { 3 | return v0 * (1 - t) + v1 * t; 4 | } 5 | 6 | // map 7 | export function map(value, low1, high1, low2, high2) { 8 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); 9 | } 10 | 11 | // clamp 12 | export function clamp(min, max, num) { 13 | return Math.min(Math.max(num, min), max); 14 | } 15 | 16 | /** ------------ Angles **/ 17 | export function radToDeg(r) { 18 | return (r * 180) / Math.PI; 19 | } 20 | 21 | export function degToRad(d) { 22 | return (d * Math.PI) / 180; 23 | } 24 | 25 | /** ------------ Bitwise **/ 26 | const isPowerOfTwo = (n) => !!n && (n & (n - 1)) == 0; 27 | -------------------------------------------------------------------------------- /webgl/twgl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ??? 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/twgl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twgl-v4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "preview": "vite preview" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "twgl.js": "^5.3.1", 17 | "vite": "^4.3.5", 18 | "vite-plugin-glsl": "^1.1.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webgl/twgl/package.json.bak: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@loaders.gl/core": "3.0.12", 4 | "@loaders.gl/gltf": "3.0.12", 5 | "gsap": "^3.7.0", 6 | "parcel": "latest", 7 | "twgl.js": "^4.19.1" 8 | }, 9 | "devDependencies": { 10 | "glslify-bundle": "^5.1.1", 11 | "glslify-deps": "^1.3.2" 12 | }, 13 | "keywords": [], 14 | "name": "twgl-v4", 15 | "description": "" 16 | } -------------------------------------------------------------------------------- /webgl/twgl/src/app.js: -------------------------------------------------------------------------------- 1 | import Gl from "./gl/gl.js"; 2 | 3 | new Gl("c"); 4 | -------------------------------------------------------------------------------- /webgl/twgl/src/assets/index.js: -------------------------------------------------------------------------------- 1 | export const ASSETS = { 2 | // img: image1, 3 | // m1: model, 4 | }; 5 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/_camera.js: -------------------------------------------------------------------------------- 1 | import { m4 } from "twgl.js"; 2 | export class Camera { 3 | constructor( 4 | gl, 5 | data = { 6 | z: -3, 7 | fov: 0.6, 8 | near: 1, 9 | far: 1024, 10 | } 11 | ) { 12 | data.fov = degToRad(35); 13 | this.camera = data; 14 | // this.get(gl); 15 | 16 | this.camera.mat = m4.translate( 17 | m4.perspective( 18 | this.camera.fov, 19 | gl.canvas.width / gl.canvas.height, 20 | this.camera.near, 21 | this.camera.far 22 | ), 23 | [0, 0, this.camera.z] 24 | ); 25 | 26 | return this.camera; 27 | } 28 | } 29 | 30 | function degToRad(d) { 31 | return (d * Math.PI) / 180; 32 | } 33 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/fsq/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform vec2 u_res; 4 | uniform float u_time; 5 | 6 | void main() { 7 | vec2 uv = gl_FragCoord.xy / u_res; 8 | 9 | gl_FragColor = vec4(uv, 1., 1.); 10 | } 11 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/fsq/index.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/fsq/vertex.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 position; 2 | 3 | void main() { 4 | gl_Position = position; 5 | } 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/instanced/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | varying float v_num0; 10 | 11 | 12 | 13 | void main() { 14 | 15 | 16 | 17 | gl_FragColor = vec4(v_uv, v_num0, 1.); 18 | 19 | //vec4 img = texture2D(u_diff, v_uv); 20 | //gl_FragColor = img; 21 | 22 | } 23 | 24 | // vec2 st = gl_FragCoord.xy/v_res.xy; 25 | 26 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/instanced/index.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/instanced/vertex.vert: -------------------------------------------------------------------------------- 1 | #define PI 3.1415926538 2 | attribute vec4 position; 3 | attribute vec2 texcoord; 4 | attribute vec2 ai_trasl; 5 | 6 | uniform mat4 u_camera; 7 | uniform float u_time; 8 | uniform vec2 u_res; 9 | uniform vec2 u_vs; 10 | 11 | uniform float u_num0; 12 | 13 | varying vec2 v_res; 14 | varying float v_time; 15 | varying vec2 v_uv; 16 | 17 | varying float v_num0; 18 | varying vec3 v_TEST; 19 | 20 | 21 | void main() { 22 | vec4 pos = position; 23 | pos.xy += ai_trasl.xy; 24 | 25 | 26 | gl_Position = u_camera * vec4(pos); 27 | 28 | v_res = u_res; 29 | v_time = u_time; 30 | v_uv = texcoord; 31 | 32 | v_num0 = u_num0; 33 | 34 | /* TEST OBJ */ 35 | v_TEST = vec3(0., 0., 0.); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/model/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | varying float v_num0; 10 | 11 | 12 | 13 | void main() { 14 | 15 | 16 | 17 | gl_FragColor = vec4(v_uv, v_num0, 1.); 18 | 19 | //vec4 img = texture2D(u_diff, v_uv); 20 | //gl_FragColor = img; 21 | 22 | } 23 | 24 | // vec2 st = gl_FragCoord.xy/v_res.xy; 25 | 26 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/_/model/index.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/chunk/imageuv.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Resize image to Cover 3 | uv : uv coord 4 | size : image size 5 | resolution : plane resolution | screen resolution 6 | */ 7 | 8 | vec2 imageuv(vec2 uv, vec2 size, vec2 resolution) { 9 | vec2 ratio = vec2( 10 | min((resolution.x / resolution.y) / (size.x / size.y), 1.0), 11 | min((resolution.y / resolution.x) / (size.y / size.x), 1.0) 12 | ); 13 | 14 | return vec2( 15 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 16 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 17 | ); 18 | } -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/chunk/rand.glsl: -------------------------------------------------------------------------------- 1 | float rand(vec2 co){ 2 | return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); 3 | } -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/chunk/rotate3d.glsl: -------------------------------------------------------------------------------- 1 | mat4 rotationMatrix(vec3 axis, float angle) { 2 | axis = normalize(axis); 3 | float s = sin(angle); 4 | float c = cos(angle); 5 | float oc = 1.0 - c; 6 | 7 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 8 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 9 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 10 | 0.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | vec3 rotate3d(vec3 v, vec3 axis, float angle) { 14 | mat4 m = rotationMatrix(axis, angle); 15 | return (m * vec4(v, 1.0)).xyz; 16 | } -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/quad/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | 10 | void main() { 11 | 12 | 13 | gl_FragColor.rgb = vec3(v_uv, 1.); 14 | gl_FragColor.a = 1.; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/quad/index.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/mat/quad/vertex.vert: -------------------------------------------------------------------------------- 1 | #define PI 3.1415926538 2 | attribute vec4 position; 3 | attribute vec2 texcoord; 4 | 5 | uniform mat4 u_camera; 6 | 7 | uniform float u_time; 8 | uniform vec2 u_res; 9 | uniform vec2 u_vs; 10 | 11 | varying vec2 v_res; 12 | varying float v_time; 13 | varying vec2 v_uv; 14 | 15 | 16 | void main() { 17 | vec4 pos = position; 18 | 19 | 20 | gl_Position = u_camera * vec4(pos); 21 | 22 | v_res = u_res; 23 | v_time = u_time; 24 | v_uv = texcoord; 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/post/mat/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | #define MPI 3.14159265359 3 | 4 | uniform vec2 u_res; 5 | uniform float u_time; 6 | 7 | uniform sampler2D u_diff; 8 | 9 | 10 | void main() { 11 | vec2 uv = gl_FragCoord.xy / u_res; 12 | vec4 diff = texture2D(u_diff, uv); 13 | 14 | gl_FragColor.rgb = diff.rgb; 15 | gl_FragColor.a = 1.; 16 | } 17 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/post/mat/index.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/post/mat/vertex.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 position; 2 | 3 | void main() { 4 | gl_Position = position; 5 | } 6 | -------------------------------------------------------------------------------- /webgl/twgl/src/gl/scene.js: -------------------------------------------------------------------------------- 1 | import { Quad } from "./_quad.js"; 2 | import { Post } from "./post/post.js"; 3 | 4 | export class Scene { 5 | constructor(gl) { 6 | this.gl = gl; 7 | 8 | this.create(); 9 | } 10 | 11 | create() { 12 | this.post = new Post(this.gl); 13 | this.quad = new Quad(this.gl); 14 | } 15 | 16 | resize(gl) { 17 | this.gl = gl; 18 | 19 | this.post?.resize(this.gl); 20 | this.quad?.resize(this.gl); 21 | } 22 | 23 | render(t) { 24 | if (this.post) this.post.setupRender(); 25 | 26 | this.quad?.render(t); 27 | 28 | if (this.post) this.post.render(this.time); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /webgl/twgl/src/gui.js: -------------------------------------------------------------------------------- 1 | import LilGui from "lil-gui"; 2 | 3 | export class Gui extends LilGui { 4 | constructor() { 5 | super(); 6 | this.initControllers(); 7 | this.initWindowGui(); 8 | window.gui = this; 9 | 10 | this.close(); 11 | } 12 | 13 | initControllers() { 14 | this.val = { 15 | anim: { 16 | timeline: 0, 17 | }, 18 | }; 19 | } 20 | 21 | initWindowGui() { 22 | for (const key in this.val) { 23 | const fold = this.addFolder(key); 24 | fold.close(); 25 | 26 | for (const key2 in this.val[key]) { 27 | fold.add(this.val[key], key2, 0, 1, 0.001); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webgl/twgl/src/styles/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, 5 | Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | } 7 | canvas { 8 | display: block; 9 | } 10 | 11 | [data-gl="c"] { 12 | width: 100vw; 13 | height: 100vh; 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | z-index: -1; 18 | } 19 | 20 | /* Project Styles */ 21 | 22 | #content { 23 | /* border: 3px solid red; */ 24 | width: 100vw; 25 | height: 100vh; 26 | position: fixed; 27 | top: 0; 28 | left: 0; 29 | z-index: 1; 30 | } 31 | 32 | .placeh { 33 | border: 2px solid white; 34 | margin: 10vw; 35 | width: 300px; 36 | height: 300px; 37 | } 38 | 39 | /* NOTES *************************************************************** 40 | 41 | 42 | */ 43 | -------------------------------------------------------------------------------- /webgl/twgl/src/styles/project.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/twgl/src/styles/project.css -------------------------------------------------------------------------------- /webgl/twgl/src/utils/math.js: -------------------------------------------------------------------------------- 1 | /* Easings */ 2 | 3 | export function lerp(v0, v1, t) { 4 | return v0 * (1 - t) + v1 * t; 5 | } 6 | 7 | /* Angles */ 8 | export function radToDeg(r) { 9 | return (r * 180) / Math.PI; 10 | } 11 | export function degToRad(d) { 12 | return (d * Math.PI) / 180; 13 | } 14 | -------------------------------------------------------------------------------- /webgl/twgl/src/utils/media.js: -------------------------------------------------------------------------------- 1 | export const getImgData = (img) => { 2 | let w = 1, 3 | h = 1, 4 | ratio = img.naturalWidth / img.naturalHeight; 5 | 6 | if (ratio > 1) { 7 | // image is horizontal 8 | h = img.naturalHeight / img.naturalWidth; 9 | } else if (ratio < 1) { 10 | // image is vertical 11 | w = ratio; 12 | } else { 13 | // image is squared or something went horribly wrong 14 | } 15 | 16 | //return { w, h }; 17 | }; 18 | -------------------------------------------------------------------------------- /webgl/twgl/src/utils/texture-loader.js: -------------------------------------------------------------------------------- 1 | import { createTexture } from "twgl.js"; 2 | 3 | export async function loadTexture(gl, src) { 4 | if (src.constructor !== Array) src = [src]; 5 | return await Promise.all(src.map((s) => promiseLoad(gl, s))); 6 | } 7 | 8 | function promiseLoad(gl, src) { 9 | if (typeof src !== "string") src = src.image; 10 | 11 | return new Promise((resolve) => { 12 | createTexture( 13 | gl, 14 | { 15 | src, 16 | mag: gl.NEAREST, 17 | crossOrigin: "anonymous", 18 | }, 19 | 20 | (err, texture, source) => { 21 | const ratio = [ 22 | Math.min(source.naturalHeight / source.naturalWidth, 1), 23 | Math.min(source.naturalWidth / source.naturalHeight, 1), 24 | ]; 25 | 26 | // console.log(ratio) 27 | 28 | resolve({ texture, ratio }); 29 | } 30 | ); 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /webgl/twgl/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import glsl from "vite-plugin-glsl"; 3 | 4 | export default defineConfig({ 5 | assetsInclude: ["**/*.glb"], 6 | plugins: [ 7 | glsl({ 8 | include: [ 9 | // Glob pattern, or array of glob patterns to import 10 | "**/*.glsl", 11 | // "**/*.wgsl", 12 | "**/*.vert", 13 | "**/*.frag", 14 | // "**/*.vs", 15 | // "**/*.fs", 16 | ], 17 | exclude: undefined, // Glob pattern, or array of glob patterns to ignore 18 | warnDuplicatedImports: true, // Warn if the same chunk was imported multiple times 19 | defaultExtension: "glsl", // Shader suffix when no extension is specified 20 | compress: true, // Compress output shader code 21 | watch: false, // Recompile shader on change 22 | root: "/", // Directory for root imports 23 | }), 24 | ], 25 | // ... 26 | }); 27 | -------------------------------------------------------------------------------- /webgl/util/slider.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/util/slider.js -------------------------------------------------------------------------------- /webgl/vanilla/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ??? 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /webgl/vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vanilla-bp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "NODE_ENV=dev node esbuild.config.js", 9 | "build": "NODE_ENV=production node esbuild.config.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "keywords": [], 14 | "devDependencies": { 15 | "esbuild": "^0.15.9", 16 | "esbuild-plugin-glsl": "^1.1.0" 17 | }, 18 | "dependencies": { 19 | "@loaders.gl/core": "3.0.12", 20 | "@loaders.gl/gltf": "3.0.12", 21 | "gsap": "^3.7.0", 22 | "parcel": "latest", 23 | "twgl.js": "^4.19.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /webgl/vanilla/src/app.js: -------------------------------------------------------------------------------- 1 | import Gl from "./modules/gl.js"; 2 | 3 | window.gl = new Gl("c"); 4 | -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/3d/par.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/vanilla/src/assets/3d/par.glb -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/3d/par1.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/vanilla/src/assets/3d/par1.glb -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/imgs/uvH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/vanilla/src/assets/imgs/uvH.jpg -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/imgs/uvV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/vanilla/src/assets/imgs/uvV.jpg -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/index.js: -------------------------------------------------------------------------------- 1 | // import image1 from "./imgs/img5.jpg"; 2 | // import model from "./3d/par1.glb"; 3 | 4 | // export const LIB = { 5 | // img: image1, 6 | // m1: model 7 | // }; 8 | -------------------------------------------------------------------------------- /webgl/vanilla/src/assets/notes.md: -------------------------------------------------------------------------------- 1 | RATIO 2 | img1: 1.4997070885 3 | img2: 1.4997070885 4 | img3: 0.8 5 | img4: 0.8 6 | img5: sq 7 | -------------------------------------------------------------------------------- /webgl/vanilla/src/flightsheet.md: -------------------------------------------------------------------------------- 1 | #??? 2 | [] ? 3 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/cam/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | varying float v_num0; 10 | 11 | 12 | 13 | void main() { 14 | 15 | 16 | 17 | gl_FragColor = vec4(v_uv, v_num0, 1.); 18 | 19 | //vec4 img = texture2D(u_diff, v_uv); 20 | //gl_FragColor = img; 21 | 22 | } 23 | 24 | // vec2 st = gl_FragCoord.xy/v_res.xy; 25 | 26 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/cam/m.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/cam/vertex.vert: -------------------------------------------------------------------------------- 1 | #define PI 3.1415926538 2 | attribute vec4 position; 3 | attribute vec2 texcoord; 4 | 5 | uniform mat4 u_camera; 6 | uniform float u_time; 7 | uniform vec2 u_res; 8 | uniform vec2 u_vs; 9 | 10 | uniform float u_num0; 11 | 12 | varying vec2 v_res; 13 | varying float v_time; 14 | varying vec2 v_uv; 15 | 16 | varying float v_num0; 17 | varying vec3 v_TEST; 18 | 19 | 20 | void main() { 21 | vec4 pos = position; 22 | //pos.xy *= u_vs; 23 | 24 | 25 | gl_Position = u_camera * vec4(pos); 26 | 27 | v_res = u_res; 28 | v_time = u_time; 29 | v_uv = texcoord; 30 | 31 | v_num0 = u_num0; 32 | 33 | /* TEST OBJ */ 34 | v_TEST = vec3(0., 0., 0.); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/fsq/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform vec2 u_res; 4 | uniform float u_time; 5 | 6 | void main() { 7 | vec2 uv = gl_FragCoord.xy / u_res; 8 | 9 | gl_FragColor = vec4(uv, 1., 1.); 10 | } 11 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/fsq/m.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/fsq/vertex.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 position; 2 | 3 | void main() { 4 | gl_Position = position; 5 | } 6 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/instanced/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | varying float v_num0; 10 | 11 | 12 | 13 | void main() { 14 | 15 | 16 | 17 | gl_FragColor = vec4(v_uv, v_num0, 1.); 18 | 19 | //vec4 img = texture2D(u_diff, v_uv); 20 | //gl_FragColor = img; 21 | 22 | } 23 | 24 | // vec2 st = gl_FragCoord.xy/v_res.xy; 25 | 26 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/instanced/m.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/instanced/vertex.vert: -------------------------------------------------------------------------------- 1 | #define PI 3.1415926538 2 | attribute vec4 position; 3 | attribute vec2 texcoord; 4 | attribute vec2 ai_trasl; 5 | 6 | uniform mat4 u_camera; 7 | uniform float u_time; 8 | uniform vec2 u_res; 9 | uniform vec2 u_vs; 10 | 11 | uniform float u_num0; 12 | 13 | varying vec2 v_res; 14 | varying float v_time; 15 | varying vec2 v_uv; 16 | 17 | varying float v_num0; 18 | varying vec3 v_TEST; 19 | 20 | 21 | void main() { 22 | vec4 pos = position; 23 | pos.xy += ai_trasl.xy; 24 | 25 | 26 | gl_Position = u_camera * vec4(pos); 27 | 28 | v_res = u_res; 29 | v_time = u_time; 30 | v_uv = texcoord; 31 | 32 | v_num0 = u_num0; 33 | 34 | /* TEST OBJ */ 35 | v_TEST = vec3(0., 0., 0.); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/model/fragment.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D u_diff; 4 | 5 | varying vec2 v_res; 6 | varying float v_time; 7 | varying vec2 v_uv; 8 | 9 | varying float v_num0; 10 | 11 | 12 | 13 | void main() { 14 | 15 | 16 | 17 | gl_FragColor = vec4(v_uv, v_num0, 1.); 18 | 19 | //vec4 img = texture2D(u_diff, v_uv); 20 | //gl_FragColor = img; 21 | 22 | } 23 | 24 | // vec2 st = gl_FragCoord.xy/v_res.xy; 25 | 26 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mat/model/m.js: -------------------------------------------------------------------------------- 1 | import vert from "./vertex.vert"; 2 | import frag from "./fragment.frag"; 3 | 4 | const Sh = [vert, frag]; 5 | export default Sh; 6 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/mod/fs-quad.js: -------------------------------------------------------------------------------- 1 | import * as twgl from "twgl.js"; 2 | import shaders from "../mat/fsq/m.js"; 3 | 4 | export default class { 5 | constructor(gl, data = {}) { 6 | this.gl = gl; 7 | this.data = data; 8 | this.shaders = shaders; 9 | this.programInfo = twgl.createProgramInfo(this.gl, this.shaders); 10 | 11 | this.gl.useProgram(this.programInfo.program); 12 | this.setBuffAtt(); 13 | this.setUniforms(); 14 | } 15 | 16 | setBuffAtt() { 17 | const arrays = { 18 | position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0] 19 | }; 20 | this.bufferInfo = twgl.createBufferInfoFromArrays(this.gl, arrays); 21 | } 22 | 23 | setUniforms() { 24 | this.uniforms = { 25 | u_res: [this.gl.canvas.width, this.gl.canvas.height], 26 | u_time: 0 27 | }; 28 | 29 | this.gl.useProgram(this.programInfo.program); 30 | twgl.setUniforms(this.programInfo, this.uniforms); 31 | } 32 | 33 | render(time) { 34 | this.gl.useProgram(this.programInfo.program); 35 | twgl.setBuffersAndAttributes(this.gl, this.programInfo, this.bufferInfo); 36 | twgl.setUniforms(this.programInfo, { 37 | u_time: time 38 | }); 39 | 40 | twgl.drawBufferInfo(this.gl, this.bufferInfo); 41 | // this.gl.LINES 42 | } 43 | 44 | resize(gl) { 45 | this.gl = gl; 46 | 47 | this.gl.useProgram(this.programInfo.program); 48 | twgl.setUniforms(this.programInfo, { 49 | u_res: [this.gl.canvas.width, this.gl.canvas.height] 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/gl/utils/camera.js: -------------------------------------------------------------------------------- 1 | import * as twgl from "twgl.js"; 2 | 3 | export default class { 4 | constructor( 5 | gl, 6 | data = { 7 | z: -3, 8 | fov: 0.6, 9 | near: 1, 10 | far: 1024 11 | } 12 | ) { 13 | data.fov = degToRad(35); 14 | this.camera = data; 15 | // this.get(gl); 16 | } 17 | 18 | get(gl) { 19 | this.camera.mat = twgl.m4.translate( 20 | twgl.m4.perspective( 21 | this.camera.fov, 22 | gl.canvas.width / gl.canvas.height, 23 | this.camera.near, 24 | this.camera.far 25 | ), 26 | [0, 0, this.camera.z] 27 | ); 28 | 29 | return this.camera; 30 | } 31 | } 32 | 33 | function degToRad(d) { 34 | return (d * Math.PI) / 180; 35 | } 36 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/utils/math.js: -------------------------------------------------------------------------------- 1 | 2 | /* Easings */ 3 | 4 | export function lerp(v0, v1, t) { 5 | return v0*(1-t)+v1*t 6 | } 7 | 8 | 9 | /* Angles */ 10 | export function radToDeg(r) { 11 | return r * 180 / Math.PI; 12 | } 13 | export function degToRad(d) { 14 | return d * Math.PI / 180; 15 | } 16 | -------------------------------------------------------------------------------- /webgl/vanilla/src/modules/utils/media.js: -------------------------------------------------------------------------------- 1 | export const getImgData = (img) => { 2 | let w = 1, 3 | h = 1, 4 | ratio = img.naturalWidth / img.naturalHeight; 5 | 6 | if (ratio > 1) { 7 | // image is horizontal 8 | h = img.naturalHeight / img.naturalWidth; 9 | } else if (ratio < 1) { 10 | // image is vertical 11 | w = ratio; 12 | } else { 13 | // image is squared or something went horribly wrong 14 | } 15 | 16 | //return { w, h }; 17 | }; 18 | -------------------------------------------------------------------------------- /webgl/vanilla/src/styles/main.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | margin:0; 4 | padding:0; 5 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 6 | 7 | } 8 | canvas { 9 | display:block; 10 | } 11 | 12 | #c { 13 | width:100vw; 14 | height:100vh; 15 | position:fixed; 16 | top:0; 17 | left:0; 18 | z-index: -1; 19 | } 20 | 21 | /* Project Styles */ 22 | 23 | #content { 24 | /* border: 3px solid red; */ 25 | width:100vw; 26 | height:100vh; 27 | position:fixed; 28 | top:0; 29 | left:0; 30 | z-index: 1; 31 | } 32 | 33 | .placeh{ 34 | border: 2px solid white; 35 | margin: 10vw; 36 | width: 300px; 37 | height: 300px; 38 | 39 | } 40 | 41 | 42 | 43 | 44 | /* NOTES *************************************************************** 45 | 46 | 47 | */ 48 | -------------------------------------------------------------------------------- /webgl/vanilla/src/styles/project.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/webgl/vanilla/src/styles/project.css -------------------------------------------------------------------------------- /webgl/vanilla/todo.md: -------------------------------------------------------------------------------- 1 | ## Todo 2 | 3 | - [ ] restructure code to match threejs / all the rest 4 | --------------------------------------------------------------------------------