├── .gitignore ├── LICENSE ├── README.md └── src ├── 10print ├── .npmignore ├── README.md ├── dist │ └── 10print.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── arcs ├── .npmignore ├── README.md ├── dist │ └── arcs.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── colors ├── .npmignore ├── README.md ├── dist │ └── colors.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── connections ├── .editorconfig ├── .npmignore ├── README.md ├── assets │ └── connections.png ├── dist │ └── connections.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── dots ├── .npmignore ├── README.md ├── dist │ └── dots.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── ellipse ├── .npmignore ├── README.md ├── dist │ └── ellipse.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── generative ├── .npmignore ├── README.md ├── dist │ └── generative.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── grid ├── .npmignore ├── README.md ├── dist │ └── grid.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── lines ├── .npmignore ├── README.md ├── assets │ └── lines.png ├── dist │ └── lines.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── noise ├── .npmignore ├── README.md ├── dist │ └── noise.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── pattern ├── .npmignore ├── README.md ├── dist │ └── pattern.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── pixels ├── .npmignore ├── README.md ├── dist │ └── pixels.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── rect ├── .npmignore ├── README.md ├── dist │ └── rect.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css ├── shapes ├── .npmignore ├── README.md ├── dist │ └── shapes.js ├── package.json ├── server.js ├── src │ └── index.js └── test │ ├── index.html │ ├── js │ ├── controls.js │ └── tweakpane-1.5.6.min.js │ └── styles.css └── waves ├── .npmignore ├── README.md ├── dist └── waves.js ├── package.json ├── server.js ├── src └── index.js └── test ├── index.html ├── js ├── controls.js └── tweakpane-1.5.6.min.js └── styles.css /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | **/test/*.js 5 | 6 | # Local Netlify folder 7 | .netlify -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 CSS Houdini 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Extends CSS with the Houdini powers 2 | 3 | A set of worklets to extends your CSS with the Houdini powers. 4 | -------------------------------------------------------------------------------- /src/10print/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/10print/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/10print/dist/10print.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/10print/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-ten-print", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background 10print", 5 | "source": "src/index.js", 6 | "main": "dist/10print.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/10print.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/10print.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/10print" 53 | } 54 | -------------------------------------------------------------------------------- /src/10print/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/10print/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [].map( 11 | prop => 12 | props 13 | .get(prop) 14 | .toString() 15 | .trim() || undefined 16 | ) 17 | } 18 | 19 | paint(ctx, geometry, props) { 20 | const {width: w, height: h} = geometry 21 | } 22 | } 23 | ) 24 | -------------------------------------------------------------------------------- /src/10print/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/10print/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/10print/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/arcs/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/arcs/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/arcs/dist/arcs.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/arcs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-arcs", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background arcs", 5 | "source": "src/index.js", 6 | "main": "dist/arcs.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/arcs.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/arcs.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/arcs" 53 | } 54 | -------------------------------------------------------------------------------- /src/arcs/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/arcs/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/arcs/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/arcs/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/arcs/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/colors/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/colors/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/colors/dist/colors.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/colors/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-colors", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background colors", 5 | "source": "src/index.js", 6 | "main": "dist/colors.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/colors.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/colors.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/colors" 53 | } 54 | -------------------------------------------------------------------------------- /src/colors/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/colors/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/colors/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/colors/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/colors/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/connections/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | end_of_line = lf 9 | indent_size = 2 10 | charset = utf-8 11 | -------------------------------------------------------------------------------- /src/connections/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/connections/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini Connections 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini Connections](https://rawcdn.githack.com/CSSHoudini/css-houdini/37db32100d05d0231d0adb11b128229a8b737d55/src/connections/assets/connections.png) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('https://rawcdn.githack.com/CSSHoudini/css-houdini/6979b873e80f9120f52bd481fbdf2d4c60db6b19/src/connections/dist/connections.js'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Connections Worklet](https://github.com/CSSHoudini/css-houdini/tree/main/src/connections/dist) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('path/to/connections.js'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **connections** worlet you need define some custom properties with values and add the value `paint(connections)` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | --connections-particleColor: rgb(150,180,200); 51 | --connections-lineColor: rgb(150,180,200); 52 | --connections-particleAmount: 40; 53 | --connections-defaultRadius: 2; 54 | --connections-variantRadius: 1; 55 | --connections-linkRadius: 60; 56 | 57 | background-image: paint(connections); 58 | } 59 | ``` 60 | 61 | | property | description | default value | 62 | | -------- | ----------- | ------------- | 63 | | --connections-particleColor | Dot color | `rgb(74,74,74)` | 64 | | --connections-lineColor | Line conections color | `rgb(76,76,76)` | 65 | | --connections-particleAmount | Dots number to show on the element | `(w * h) / 1000` Calc of width * height divided to 1000 | 66 | | --connections-defaultRadius | Dot radius | 1.5 | 67 | | --connections-variantRadius | Dot radius variant | 3 | 68 | | --connections-linkRadius | Minimum distance between dots to draw the line connection | 80 | 69 | 70 | #### Important informaction 71 | 72 | - The current worklet version needs that the values for `--connections-particleColor` and `--connections-lineColor` are **RGB Color** with format `rgb(150,180,200)`. 73 | - If you define a huge values, you can see hundreds of lines in your element. 74 | 75 | ## License 76 | 77 | MIT License 78 | 79 | Copyright (c) 2020 CSS Houdini 80 | -------------------------------------------------------------------------------- /src/connections/assets/connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSSHoudini/css-houdini/cb47d30c5d2d6d91d120290c22808e56069f2d40/src/connections/assets/connections.png -------------------------------------------------------------------------------- /src/connections/dist/connections.js: -------------------------------------------------------------------------------- 1 | registerPaint("connections",class{static get inputProperties(){return["--connections-particleColor","--connections-lineColor","--connections-particleAmount","--connections-defaultRadius","--connections-variantRadius","--connections-linkRadius"]}hexToRgb(t){let n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return n?[parseInt(n[1],16),parseInt(n[2],16),parseInt(n[3],16)]:null}parseProps(t){return["--connections-particleColor","--connections-lineColor","--connections-particleAmount","--connections-defaultRadius","--connections-variantRadius","--connections-linkRadius"].map(n=>t.get(n).toString().trim()||void 0)}checkDistance(t,n,e,o){return Math.sqrt(Math.pow(e-t,2)+Math.pow(o-n,2))}paint(t,n,e){const{width:o,height:i}=n,[a="rgb(74,74,74)",r="rgb(76,76,76)",c=o*i/1e3,s=1.5,l=3,h=80]=this.parseProps(e);let d=[];const u=/^#([0-9A-F]{3}){1,2}$/i.test(r),[p,g,f]=u?this.hexToRgb(r):r.match(/\d+/g),m=(n,e)=>{let o=+s+Math.random()*+l;return t.beginPath(),t.arc(n,e,o,0,2*Math.PI),t.fillStyle=a,t.fill(),{x:n,y:e}},M=n=>{for(let e=0;e0&&(t.lineWidth=.5,t.strokeStyle=`rgba(${p}, ${g}, ${f}, ${o})`,t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(d[e].x,d[e].y),t.closePath(),t.stroke())}};for(let t=0;t 36 | props 37 | .get(prop) 38 | .toString() 39 | .trim() || undefined 40 | ) 41 | } 42 | 43 | checkDistance(x1, y1, x2, y2) { 44 | return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) 45 | } 46 | 47 | paint(ctx, geometry, props) { 48 | const {width: w, height: h} = geometry 49 | const [ 50 | particleColor = 'rgb(74,74,74)', 51 | lineColor = 'rgb(76,76,76)', 52 | particleAmount = (w * h) / 1000, 53 | defaultRadius = 1.5, 54 | variantRadius = 3, 55 | linkRadius = 80 56 | ] = this.parseProps(props) 57 | 58 | let particles = [] 59 | const isHexColor = /^#([0-9A-F]{3}){1,2}$/i.test(lineColor) 60 | const [r, g, b] = isHexColor 61 | ? this.hexToRgb(lineColor) 62 | : lineColor.match(/\d+/g) 63 | 64 | const particle = (x, y) => { 65 | let radius = +defaultRadius + Math.random() * +variantRadius 66 | ctx.beginPath() 67 | ctx.arc(x, y, radius, 0, Math.PI * 2) 68 | ctx.fillStyle = particleColor 69 | ctx.fill() 70 | return {x, y} 71 | } 72 | 73 | const linkPoints = point => { 74 | for (let i = 0; i < particleAmount; i++) { 75 | let distance = this.checkDistance( 76 | point.x, 77 | point.y, 78 | particles[i].x, 79 | particles[i].y 80 | ) 81 | let opacity = 1 - distance / linkRadius 82 | if (opacity > 0) { 83 | ctx.lineWidth = 0.5 84 | ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${opacity})` 85 | ctx.beginPath() 86 | ctx.moveTo(point.x, point.y) 87 | ctx.lineTo(particles[i].x, particles[i].y) 88 | ctx.closePath() 89 | ctx.stroke() 90 | } 91 | } 92 | } 93 | 94 | for (let i = 0; i < particleAmount; i++) { 95 | let x = Math.round(Math.random() * w) 96 | let y = Math.round(Math.random() * h) 97 | particles.push(particle(x, y)) 98 | } 99 | 100 | for (let i = 0; i < particleAmount; i++) { 101 | linkPoints(particles[i]) 102 | } 103 | } 104 | } 105 | ) 106 | -------------------------------------------------------------------------------- /src/connections/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini Connections 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/connections/test/js/controls.js: -------------------------------------------------------------------------------- 1 | const element = document.querySelector('.connections') 2 | const PARAMS = { 3 | particleColor: {r: 150, g: 180, b: 200}, 4 | lineColor: {r: 150, g: 180, b: 200}, 5 | particleAmount: 80, 6 | defaultRadius: 2, 7 | variantRadius: 3, 8 | linkRadius: 80 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Connections Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'particleColor', {label: 'Particle Color'}).on( 17 | 'change', 18 | value => { 19 | const {r, g, b} = value 20 | const color = `rgb(${r},${g},${b})` 21 | element.style.setProperty('--connections-particleColor', color) 22 | } 23 | ) 24 | f1.addInput(PARAMS, 'lineColor', {label: 'Line Color'}).on('change', value => { 25 | const {r, g, b} = value 26 | const color = `rgb(${r},${g},${b})` 27 | element.style.setProperty('--connections-lineColor', color) 28 | }) 29 | f1.addInput(PARAMS, 'particleAmount', { 30 | label: 'Amount', 31 | step: 5, 32 | min: 10, 33 | max: 400 34 | }).on('change', value => { 35 | element.style.setProperty('--connections-particleAmount', value) 36 | }) 37 | f1.addInput(PARAMS, 'defaultRadius', { 38 | label: 'Radius', 39 | step: 0.5, 40 | min: 1, 41 | max: 5 42 | }).on('change', value => { 43 | element.style.setProperty('--connections-defaultRadius', value) 44 | }) 45 | f1.addInput(PARAMS, 'variantRadius', { 46 | label: 'Variant Radius', 47 | step: 0.5, 48 | min: 1, 49 | max: 4 50 | }).on('change', value => { 51 | element.style.setProperty('--connections-variantRadius', value) 52 | }) 53 | f1.addInput(PARAMS, 'linkRadius', { 54 | label: 'Link Radius', 55 | step: 1, 56 | min: 10, 57 | max: 200 58 | }).on('change', value => { 59 | element.style.setProperty('--connections-linkRadius', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open( 64 | 'https://github.com/CSSHoudini/css-houdini', 65 | 'CSS Houdini Connections' 66 | ) 67 | ) 68 | f2.addButton({title: '@csshoudini'}).on('click', () => 69 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 70 | ) 71 | -------------------------------------------------------------------------------- /src/connections/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | --color-dark: #353535; 4 | --color-medium: #858585; 5 | --color-light: #d3d3d3; 6 | } 7 | 8 | @media (min-width: 600px) { 9 | :root { 10 | --size: 600px; 11 | } 12 | } 13 | 14 | html, 15 | body { 16 | margin: 0; 17 | padding: 0; 18 | height: 100%; 19 | } 20 | 21 | body { 22 | align-items: center; 23 | background-color: white; 24 | display: flex; 25 | flex-direction: column; 26 | font-family: sans-serif; 27 | justify-content: center; 28 | padding-top: 1em; 29 | } 30 | 31 | .css-houdini { 32 | height: var(--size); 33 | padding: 1em; 34 | box-sizing: content-box; 35 | width: var(--size); 36 | } 37 | 38 | .connections { 39 | --connections-particleColor: #96b4c8; 40 | --connections-lineColor: #96b4c8; 41 | --connections-particleAmount: 200; 42 | --connections-defaultRadius: 2; 43 | --connections-variantRadius: 1; 44 | --connections-linkRadius: 60; 45 | 46 | background-image: paint(connections); 47 | } 48 | -------------------------------------------------------------------------------- /src/dots/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/dots/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/dots/dist/dots.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/dots/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-dots", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background dots", 5 | "source": "src/index.js", 6 | "main": "dist/dots.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/dots.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/dots.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/dots" 53 | } 54 | -------------------------------------------------------------------------------- /src/dots/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/dots/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/dots/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/dots/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/dots/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/ellipse/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/ellipse/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/ellipse/dist/ellipse.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/ellipse/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-ellipse", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background ellipse", 5 | "source": "src/index.js", 6 | "main": "dist/ellipse.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/ellipse.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/ellipse.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/ellipse" 53 | } 54 | -------------------------------------------------------------------------------- /src/ellipse/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/ellipse/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/ellipse/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/ellipse/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/ellipse/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/generative/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/generative/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/generative/dist/generative.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/generative/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-generative", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background generative", 5 | "source": "src/index.js", 6 | "main": "dist/generative.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/generative.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/generative.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/generative" 53 | } 54 | -------------------------------------------------------------------------------- /src/generative/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/generative/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/generative/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/generative/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/generative/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/grid/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/grid/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/grid/dist/grid.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/grid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-grid", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background grid", 5 | "source": "src/index.js", 6 | "main": "dist/grid.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/grid.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/grid.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/grid" 53 | } 54 | -------------------------------------------------------------------------------- /src/grid/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/grid/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/grid/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/grid/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/grid/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/lines/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/lines/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini Lines 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini Lines](https://rawcdn.githack.com/CSSHoudini/css-houdini/37db32100d05d0231d0adb11b128229a8b737d55/src/lines/assets/lines.png) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('https://rawcdn.githack.com/CSSHoudini/css-houdini/74a3e2482adf18b41882de48f601a5fc18fd9d5c/src/lines/dist/lines.js'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [lines Worklet](https://github.com/CSSHoudini/css-houdini/tree/main/src/lines/dist) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('path/to/lines.js'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **Lines** worlet you need define some custom properties with values and add the value `paint(lines)` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | --lines-colors: #f94144, #f3722c, #f8961e, #f9844a; 51 | --lines-widths: 10, 2, 3, 8; 52 | --lines-gaps: 20, 4, 3, 7; 53 | --lines-rotate: 0; /* In degrees */ 54 | 55 | background-image: paint(lines); 56 | } 57 | ``` 58 | 59 | | property | description | default value | 60 | | -------- | ----------- | ------------- | 61 | | --lines-colors | **Color lines**, you can define one or more hexadecimal colors comma separated | `#71a7ee, #7940c1` | 62 | | --lines-widths | **Width lines**, you can define one or more line widths comma separated | `6, 2` | 63 | | --lines-gaps | **Gap lines**, you can define one or more gaps comma separated | `8` | 64 | | --lines-rotate | **Rotation lines**, with an interger | `0` | 65 | 66 | ## License 67 | 68 | MIT License 69 | 70 | Copyright (c) 2020 CSS Houdini 71 | -------------------------------------------------------------------------------- /src/lines/assets/lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSSHoudini/css-houdini/cb47d30c5d2d6d91d120290c22808e56069f2d40/src/lines/assets/lines.png -------------------------------------------------------------------------------- /src/lines/dist/lines.js: -------------------------------------------------------------------------------- 1 | registerPaint("lines",class{static get inputProperties(){return["--lines-colors","--lines-widths","--lines-gaps","--lines-rotate"]}parseProps(t){return["--lines-colors","--lines-widths","--lines-gaps","--lines-rotate"].map(e=>t.get(e).toString().trim()||void 0)}paint(t,e,s){const{width:l,height:i}=e,[a="#71a7ee, #7940c1",n="6, 2",r="8",o=0]=this.parseProps(s),p=2*Math.floor(Math.sqrt(Math.pow(l,2)+Math.pow(i,2))),h=a.split(",").map(t=>t),c=h.length;let g=0;const m=n.split(",").map(t=>+t),M=Math.min(...m),w=m.length;let P=0;const d=r.split(",").map(t=>+t),f=d.length;let u=0;0!==o&&(t.rotate(o*Math.PI/180),t.translate(-p,-p));let S=0;for(let e=0;e

=w-1?P=0:P++,u>=f-1?u=0:u++,g>=c-1?g=0:g++,S+=e}}}); 2 | -------------------------------------------------------------------------------- /src/lines/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-lines", 3 | "version": "1.0.4", 4 | "description": "CSS Houdini Background Lines", 5 | "source": "src/index.js", 6 | "main": "dist/lines.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/lines.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/lines.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/lines" 53 | } 54 | -------------------------------------------------------------------------------- /src/lines/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/lines/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | 'lines', 4 | class { 5 | static get inputProperties() { 6 | return [ 7 | '--lines-colors', 8 | '--lines-widths', 9 | '--lines-gaps', 10 | '--lines-rotate' 11 | ] 12 | } 13 | 14 | parseProps(props) { 15 | return [ 16 | '--lines-colors', 17 | '--lines-widths', 18 | '--lines-gaps', 19 | '--lines-rotate' 20 | ].map( 21 | prop => 22 | props 23 | .get(prop) 24 | .toString() 25 | .trim() || undefined 26 | ) 27 | } 28 | 29 | paint(ctx, geometry, props) { 30 | const {width: w, height: h} = geometry 31 | const [ 32 | colors = '#71a7ee, #7940c1', 33 | widths = '6, 2', 34 | gaps = '8', 35 | rotate = 0 36 | ] = this.parseProps(props) 37 | 38 | const sqrtArea = Math.floor(Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2))) 39 | const saveArea = sqrtArea * 2 40 | const colorLines = colors.split(',').map(color => color) 41 | const maxColors = colorLines.length 42 | let indexColor = 0 43 | 44 | const widthLines = widths.split(',').map(width => +width) 45 | const maxWidth = Math.min(...widthLines) 46 | const maxLines = widthLines.length 47 | let indexLine = 0 48 | 49 | const gapLines = gaps.split(',').map(gap => +gap) 50 | const maxGaps = gapLines.length 51 | let indexGap = 0 52 | 53 | if (rotate !== 0) { 54 | ctx.rotate((rotate * Math.PI) / 180) 55 | ctx.translate(-saveArea, -saveArea) 56 | } 57 | 58 | let posY = 0 59 | 60 | for (let i = 0; i < saveArea / maxWidth; i++) { 61 | const lineGap = +widthLines[indexLine] + gapLines[indexGap] 62 | ctx.fillStyle = colorLines[indexColor] 63 | 64 | ctx.fillRect( 65 | -saveArea * 0.5, 66 | posY, 67 | saveArea * 2, 68 | +widthLines[indexLine] 69 | ) 70 | 71 | indexLine >= maxLines - 1 ? (indexLine = 0) : indexLine++ 72 | indexGap >= maxGaps - 1 ? (indexGap = 0) : indexGap++ 73 | indexColor >= maxColors - 1 ? (indexColor = 0) : indexColor++ 74 | 75 | posY += lineGap 76 | } 77 | } 78 | } 79 | ) 80 | -------------------------------------------------------------------------------- /src/lines/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini Lines 7 | 8 | 9 | 10 |

11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/lines/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/lines/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | 35 | .lines { 36 | --lines-colors: #f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1; 37 | --lines-widths: 10, 2, 3, 8; 38 | --lines-gaps: 20, 4, 3, 7; 39 | --lines-rotate: 0; /* In degrees */ 40 | 41 | background-image: paint(lines); 42 | } 43 | -------------------------------------------------------------------------------- /src/noise/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/noise/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/noise/dist/noise.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/noise/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-noise", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background noise", 5 | "source": "src/index.js", 6 | "main": "dist/noise.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/noise.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/noise.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/noise" 53 | } 54 | -------------------------------------------------------------------------------- /src/noise/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/noise/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/noise/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/noise/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/noise/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/pattern/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/pattern/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/pattern/dist/pattern.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/pattern/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-pattern", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background pattern", 5 | "source": "src/index.js", 6 | "main": "dist/pattern.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/pattern.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/pattern.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/pattern" 53 | } 54 | -------------------------------------------------------------------------------- /src/pattern/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/pattern/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/pattern/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/pattern/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/pattern/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/pixels/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/pixels/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/pixels/dist/pixels.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/pixels/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-pixels", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background pixels", 5 | "source": "src/index.js", 6 | "main": "dist/pixels.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/pixels.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/pixels.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/pixels" 53 | } 54 | -------------------------------------------------------------------------------- /src/pixels/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/pixels/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/pixels/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/pixels/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/pixels/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/rect/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/rect/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/rect/dist/rect.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/rect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-rect", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background rect", 5 | "source": "src/index.js", 6 | "main": "dist/rect.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/rect.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/rect.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/rect" 53 | } 54 | -------------------------------------------------------------------------------- /src/rect/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/rect/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/rect/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/rect/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/rect/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/shapes/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/shapes/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/shapes/dist/shapes.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/shapes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-shapes", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background shapes", 5 | "source": "src/index.js", 6 | "main": "dist/shapes.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/shapes.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/shapes.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/shapes" 53 | } 54 | -------------------------------------------------------------------------------- /src/shapes/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/shapes/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/shapes/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/shapes/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/shapes/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | -------------------------------------------------------------------------------- /src/waves/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | assets 3 | test 4 | .editorconfig 5 | server.js 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /src/waves/README.md: -------------------------------------------------------------------------------- 1 | # CSS Houdini [Worklet Name] 2 | 3 | A CSS Houdini Worklet to show connected nodes. 4 | 5 | ![CSS Houdini [Worklet Name]]([SCREENSHOT]) 6 | 7 | ## Getting started 8 | 9 | ### 1. Load the worklet 10 | 11 | Using CDN is the easiest way to add the library: 12 | 13 | ```js 14 | if ('paintWorklet' in CSS) { 15 | CSS.paintWorklet.addModule('[URL]'); 16 | } 17 | ``` 18 | 19 | Or, download the latest [Worklet name]([URL]) and import it to your web page: 20 | 21 | ```js 22 | if ('paintWorklet' in CSS) { 23 | CSS.paintWorklet.addModule('[LOCAL_PATH]'); 24 | } 25 | ``` 26 | 27 | #### You can use the polyfill 28 | 29 | To add support for all moder browsers, you can load the worklet with [css-paint-polyfill](https://github.com/GoogleChromeLabs/css-paint-polyfill) fallback. 30 | 31 | ```html 32 | 40 | ``` 41 | 42 | ### 3. Ready to use it in your CSS! 43 | 44 | To use **[Worklet Name]** worlet you need define some custom properties with values and add the value `paint([worklet_name])` on `background-image` property. 45 | 46 | > The worklet has default values if you don't define these 47 | 48 | ```css 49 | .element { 50 | /* CSS code */ 51 | } 52 | ``` 53 | 54 | | property | description | default value | 55 | | -------- | ----------- | ------------- | 56 | | --workletName | | | 57 | 58 | ## License 59 | 60 | MIT License 61 | 62 | Copyright (c) 2020 CSS Houdini 63 | -------------------------------------------------------------------------------- /src/waves/dist/waves.js: -------------------------------------------------------------------------------- 1 | registerPaint("[worklet_name]",class{static get inputProperties(){return[]}parseProps(t){return[].map(r=>t.get(r).toString().trim()||void 0)}paint(t,r,e){}}); 2 | -------------------------------------------------------------------------------- /src/waves/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-houdini-waves", 3 | "version": "0.0.1", 4 | "description": "CSS Houdini Background waves", 5 | "source": "src/index.js", 6 | "main": "dist/waves.js", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "microbundle --entry src/index.js --output dist/waves.js --no-pkg-main --format modern --no-sourcemap", 10 | "prepublish": "npm run build", 11 | "test": "npm run test:copy && npm run test:server", 12 | "test:copy": "cp -fv ./src/index.js ./test/waves.js", 13 | "test:server": "node ./server.js" 14 | }, 15 | "keywords": [ 16 | "houdini", 17 | "css", 18 | "css-houdini", 19 | "PaintWorklet", 20 | "paint", 21 | "worklet" 22 | ], 23 | "author": { 24 | "name": "Joan León", 25 | "email": "joan.leon@gmail.com", 26 | "twitter": "@nucliweb", 27 | "web": "https://joanleon.dev" 28 | }, 29 | "license": "MIT", 30 | "eslintConfig": { 31 | "extends": [ 32 | "./node_modules/@s-ui/lint/eslintrc.js" 33 | ] 34 | }, 35 | "prettier": "./node_modules/@s-ui/lint/.prettierrc.js", 36 | "stylelint": { 37 | "extends": "./node_modules/@s-ui/lint/stylelint.config.js" 38 | }, 39 | "devDependencies": { 40 | "@s-ui/lint": "^3.25.0", 41 | "express": "^4.17.1", 42 | "microbundle": "^0.12.4", 43 | "rimraf": "^3.0.2" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "git+https://github.com/CSSHoudini/css-houdini.git" 48 | }, 49 | "bugs": { 50 | "url": "https://github.com/CSSHoudini/css-houdini/issues" 51 | }, 52 | "homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/waves" 53 | } 54 | -------------------------------------------------------------------------------- /src/waves/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint no-console: "off" */ 3 | 4 | const path = require('path') 5 | const express = require('express') 6 | const app = express() 7 | const htdocs = path.join(__dirname, 'test') 8 | 9 | // Run static server 10 | app.use(express.static(htdocs)) 11 | app.listen(8080) 12 | 13 | console.log('🚀 Paint worklet test up and running at http://localhost:8080/') 14 | console.log('ℹ️ Press Ctrl+C to return to the real world.') 15 | -------------------------------------------------------------------------------- /src/waves/src/index.js: -------------------------------------------------------------------------------- 1 | /* global registerPaint */ 2 | registerPaint( 3 | '[worklet_name]', 4 | class { 5 | static get inputProperties() { 6 | return [] 7 | } 8 | 9 | parseProps(props) { 10 | return [ 11 | ].map( 12 | prop => 13 | props 14 | .get(prop) 15 | .toString() 16 | .trim() || undefined 17 | ) 18 | } 19 | 20 | paint(ctx, geometry, props) { 21 | const {width: w, height: h} = geometry 22 | } 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/waves/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS Houdini [worklet_name] 7 | 8 | 9 | 10 |
11 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/waves/test/js/controls.js: -------------------------------------------------------------------------------- 1 | /* global Tweakpane */ 2 | const element = document.querySelector('.lines') 3 | const PARAMS = { 4 | colors: 5 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 6 | widths: '10, 2, 3, 8', 7 | gaps: '20, 4, 3, 7', 8 | rotate: 0 9 | } 10 | 11 | const pane = new Tweakpane() 12 | const f1 = pane.addFolder({title: 'Lines Parameters'}) 13 | const f2 = pane.addFolder({title: 'Information'}) 14 | f2.expanded = false 15 | 16 | f1.addInput(PARAMS, 'colors', { 17 | label: 'Line colors', 18 | options: { 19 | Palette1: 20 | '#f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e, #577590, #277da1', 21 | Palette2: '#2a9d8f, #e76f51', 22 | Palette3: '#583d72, #9f5f80, #ffba93, #ff8e71', 23 | Palette4: '#fc00ff, #ff67e2, #ff95f9, #bd42ff, #6100ff' 24 | } 25 | }).on('change', value => { 26 | element.style.setProperty('--lines-colors', value) 27 | }) 28 | 29 | f1.addInput(PARAMS, 'widths', { 30 | label: 'Line widths', 31 | options: { 32 | '10, 2, 3, 8': '10, 2, 3, 8', 33 | '10': '10', 34 | '13, 2, 8, 4, 1': '13, 2, 8, 4, 1', 35 | '35, 12, 5': '35, 12, 5' 36 | } 37 | }).on('change', value => { 38 | element.style.setProperty('--lines-widths', value) 39 | }) 40 | 41 | f1.addInput(PARAMS, 'gaps', { 42 | label: 'Line gaps', 43 | options: { 44 | '20, 4, 3, 7': '20, 4, 3, 7', 45 | '8': '8', 46 | '5, 3': '5, 3', 47 | '6, 7, 1, 3': '6, 7, 1, 3' 48 | } 49 | }).on('change', value => { 50 | element.style.setProperty('--lines-gaps', value) 51 | }) 52 | 53 | f1.addInput(PARAMS, 'rotate', { 54 | label: 'Rotation (Degrees)', 55 | step: 1, 56 | min: 0, 57 | max: 360 58 | }).on('change', value => { 59 | element.style.setProperty('--lines-rotate', value) 60 | }) 61 | 62 | f2.addButton({title: 'Source Code'}).on('click', () => 63 | window.open('https://github.com/CSSHoudini/css-houdini', 'CSS Houdini Lines') 64 | ) 65 | f2.addButton({title: '@csshoudini'}).on('click', () => 66 | window.open('https://twitter.com/csshoudini', 'CSS Houdini') 67 | ) 68 | -------------------------------------------------------------------------------- /src/waves/test/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --size: 300px; 3 | } 4 | 5 | @media (min-width: 600px) { 6 | :root { 7 | --size: 600px; 8 | } 9 | } 10 | 11 | html, 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | align-items: center; 20 | background-color: white; 21 | display: flex; 22 | flex-direction: column; 23 | font-family: sans-serif; 24 | justify-content: center; 25 | padding-top: 1em; 26 | } 27 | 28 | .css-houdini { 29 | height: var(--size); 30 | padding: 1em; 31 | box-sizing: content-box; 32 | width: var(--size); 33 | } 34 | --------------------------------------------------------------------------------