Skip to content

Commit 077dde3

Browse files
authored
Merge pull request #2 from CSSHoudini/worklet/lines
Worklet/lines
2 parents b680ef8 + 550a8ae commit 077dde3

File tree

10 files changed

+346
-1
lines changed

10 files changed

+346
-1
lines changed

src/connections/test/js/controls.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const element = document.querySelector('.connections')
2-
console.log(element)
32
const PARAMS = {
43
particleColor: {r: 150, g: 180, b: 200},
54
lineColor: {r: 150, g: 180, b: 200},

src/lines/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# CSS Houdini Lines
2+
3+
A CSS Houdini Worklet to show connected nodes.
4+
5+
![CSS Houdini Lines](https://github.com/CSSHoudini/css-houdini/blob/main/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('...');
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+
<script>
33+
;(async function() {
34+
if (CSS['paintWorklet'] === undefined)
35+
await import('https://unpkg.com/css-paint-polyfill')
36+
37+
CSS.paintWorklet.addModule('./lines.js')
38+
})()
39+
</script>
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

src/lines/assets/lines.png

27.9 KB
Loading

src/lines/package.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "css-houdini-lines",
3+
"version": "1.0.1",
4+
"description": "CSS Houdini Background Lines",
5+
"source": "src/index.js",
6+
"main": "dist/lines.js",
7+
"module": "dist/lines.module.js",
8+
"unpkg": "dist/lines.umd.js",
9+
"scripts": {
10+
"build": "rimraf dist && microbundle --no-sourcemap",
11+
"prepublish": "npm run build",
12+
"test": "npm run test:copy && npm run test:server",
13+
"test:copy": "cp -fv ./src/index.js ./test/lines.js",
14+
"test:server": "node ./server.js"
15+
},
16+
"keywords": [
17+
"houdini",
18+
"css",
19+
"css-houdini",
20+
"PaintWorklet",
21+
"paint",
22+
"worklet"
23+
],
24+
"author": {
25+
"name": "Joan León",
26+
"email": "joan.leon@gmail.com",
27+
"twitter": "@nucliweb",
28+
"web": "https://joanleon.dev"
29+
},
30+
"license": "MIT",
31+
"eslintConfig": {
32+
"extends": [
33+
"./node_modules/@s-ui/lint/eslintrc.js"
34+
]
35+
},
36+
"prettier": "./node_modules/@s-ui/lint/.prettierrc.js",
37+
"stylelint": {
38+
"extends": "./node_modules/@s-ui/lint/stylelint.config.js"
39+
},
40+
"devDependencies": {
41+
"@s-ui/lint": "^3.25.0",
42+
"express": "^4.17.1",
43+
"microbundle": "^0.12.4",
44+
"rimraf": "^3.0.2"
45+
},
46+
"repository": {
47+
"type": "git",
48+
"url": "git+https://github.com/CSSHoudini/css-houdini.git"
49+
},
50+
"bugs": {
51+
"url": "https://github.com/CSSHoudini/css-houdini/issues"
52+
},
53+
"homepage": "https://github.com/CSSHoudini/css-houdini/tree/main/src/lines"
54+
}

src/lines/server.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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.')

src/lines/src/index.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* global registerPaint */
2+
const LINES_PROPS = [
3+
'--lines-colors',
4+
'--lines-widths',
5+
'--lines-gaps',
6+
'--lines-rotate'
7+
]
8+
9+
registerPaint(
10+
'lines',
11+
class {
12+
static get inputProperties() {
13+
return LINES_PROPS
14+
}
15+
16+
parseProps(props) {
17+
return LINES_PROPS.map(
18+
prop =>
19+
props
20+
.get(prop)
21+
.toString()
22+
.trim() || undefined
23+
)
24+
}
25+
26+
paint(ctx, geometry, props) {
27+
const {width: w, height: h} = geometry
28+
const [
29+
colors = '#71a7ee, #7940c1',
30+
widths = '6, 2',
31+
gaps = '8',
32+
rotate = 0
33+
] = this.parseProps(props)
34+
35+
const sqrtArea = Math.floor(Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2)))
36+
const saveArea = sqrtArea * 2
37+
const colorLines = colors.split(',').map(color => color)
38+
const maxColors = colorLines.length
39+
let indexColor = 0
40+
41+
const widthLines = widths.split(',').map(width => +width)
42+
const maxWidth = Math.min(...widthLines)
43+
const maxLines = widthLines.length
44+
let indexLine = 0
45+
46+
const gapLines = gaps.split(',').map(gap => +gap)
47+
const maxGaps = gapLines.length
48+
let indexGap = 0
49+
50+
if (rotate !== 0) {
51+
ctx.rotate((rotate * Math.PI) / 180)
52+
ctx.translate(-saveArea, -saveArea)
53+
}
54+
55+
let posY = 0
56+
57+
for (let i = 0; i < saveArea / maxWidth; i++) {
58+
const lineGap = +widthLines[indexLine] + gapLines[indexGap]
59+
ctx.fillStyle = colorLines[indexColor]
60+
61+
ctx.fillRect(
62+
-saveArea * 0.5,
63+
posY,
64+
saveArea * 2,
65+
+widthLines[indexLine]
66+
)
67+
68+
indexLine >= maxLines - 1 ? (indexLine = 0) : indexLine++
69+
indexGap >= maxGaps - 1 ? (indexGap = 0) : indexGap++
70+
indexColor >= maxColors - 1 ? (indexColor = 0) : indexColor++
71+
72+
posY += lineGap
73+
}
74+
}
75+
}
76+
)

src/lines/test/index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>CSS Houdini Lines</title>
7+
<link rel="stylesheet" href="./styles.css" />
8+
</head>
9+
<body>
10+
<div class="css-houdini lines"></div>
11+
<script>
12+
;(async function() {
13+
if (CSS['paintWorklet'] === undefined)
14+
await import('https://unpkg.com/css-paint-polyfill')
15+
16+
CSS.paintWorklet.addModule('./lines.js')
17+
})()
18+
</script>
19+
<script src="./js/tweakpane-1.5.6.min.js"></script>
20+
<script src="./js/controls.js"></script>
21+
</body>
22+
</html>

src/lines/test/js/controls.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
)

src/lines/test/js/tweakpane-1.5.6.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lines/test/styles.css

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
}

0 commit comments

Comments
 (0)