4 Beispiele was man mit der Paint API machen kann
Code
<html>
<head>
<style>
body {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: center;
justify-content: space-evenly;
}
iframe{
height:500px;
width:100%;
outline:none;
border:none;
}
h1{
border-bottom:2px solid black;
text-align:center;
}
</style>
</head>
<body>
<h1> Beispiel 1 </h1>
<iframe srcdoc="<style>
@supports (background: paint(something)) {
h1 {
/*
Optionally set property values.
This can be done at root or local scope
*/
--extra-confettiNumber: 80;
/* defaults to 30 */
--extra-confettiLengthVariance: 12;
/* Defaults to 15 */
--extra-confettiWeightVariance: 3;
/* Defaults to 4 */
background: paint(extra-confetti);
}
i {
--extra-sparkleNumber: 10;
/* defaults to 30 */
--extra-sparkleHue: 30;
/* Defaults to 60 (yellow) */
--extra-sparkleHeightVariance: 5;
/* Defaults to 9 */
--extra-sparkleWeightVariance: 2;
/* Defaults to 2 */
background: paint(extra-sparkles);
}
}
body {
font-family: monospace;
height: 100vh;
width: 100vw;
text-align: center;
padding: 0;
margin: 0;
}
h1 {
font-size: 4rem;
display: inline-block;
font-weight: 100;
padding: 1rem;
margin: 1rem auto;
position: relative;
}
p {
max-width: 660px;
margin: 0 auto;
font-weight: 300;
font-size: 1.2rem;
line-height: 2;
text-align: left;
}
</style>
<h1>Hello World</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit <i>asperiores</i> cupiditate dolor quo iste animi, eveniet in inventore <i>obcaecati</i> quisquam architecto pariatur et perspiciatis, deleniti voluptatum consequuntur <i>voluptas</i> voluptatibus repellat!</p>
<!-- This is where we register the worklet -->
<script>
// See files in confetti/*
CSS.registerProperty({
name: '--extra-confettiNumber',
syntax: '<number>',
inherits: false,
initialValue: 30,
});
CSS.registerProperty({
name: '--extra-confettiLengthVariance',
syntax: '<number>',
inherits: false,
initialValue: 15,
});
CSS.registerProperty({
name: '--extra-confettiWeightVariance',
syntax: '<number>',
inherits: false,
initialValue: 4,
});
(() => {
const worklet = `
const getRandom = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min
}
if (typeof registerPaint !== 'undefined') {
class ExtraConfetti {
static get inputProperties() {
return ['--extra-confettiNumber','--extra-confettiLengthVariance', '--extra-confettiWeightVariance']
}
paint(ctx, size, properties) {
const confettiNum = properties.get('--extra-confettiNumber')
const minLength = 3
const maxLength = minLength + parseInt(properties.get('--extra-confettiLengthVariance'))
const minWeight = 1
const maxWeight = minWeight + parseInt(properties.get('--extra-confettiWeightVariance'))
for (var i = 0; i < confettiNum; i++) {
const x = Math.random() * size.width
const y = Math.random() * (size.height - maxLength)
const confettiLength = getRandom(minLength, maxLength)
const confettiWeight = getRandom(minWeight, maxWeight)
// Set Color
const hue = getRandom(0,360)
const sat = getRandom(90,100)
const light = getRandom(40,90)
const color = 'hsl(' + hue + 'deg,' + sat + '%,' + light + '%)'
// Set Paint Info
ctx.lineWidth = confettiWeight
ctx.strokeStyle = color
// Calculate New Position
const angle = getRandom(0,89)
const hypotenuse = confettiLength
const newX = x + Math.cos(angle) * hypotenuse
const newY = y + Math.sin(angle) * hypotenuse
// Paint
ctx.beginPath();
ctx.moveTo(x,y)
ctx.lineTo(newX, newY)
ctx.stroke()
}
}
}
registerPaint('extra-confetti', ExtraConfetti)
}`
const workletBlob = URL.createObjectURL(new Blob([worklet], { type: 'application/javascript' }))
window.CSS.paintWorklet.addModule(workletBlob)
})()
</script>"></iframe>
<h1>Beispiel 2</h1>
<iframe srcdoc="<style>
@supports (background: paint(something)) {
h1 {
/*
Optionally set property values.
This can be done at root or local scope
*/
--extra-scallopRadius: 15;
/* default: 10 */
--extra-scallopColor: #8266ff;
/* default: black */
--extra-scallopWeight: 3;
/* default: 2 */
background: paint(extra-scallopedBorder);
line-height: 1.5;
}
i {
--extra-scallopRadius: 5;
/* default: 10 */
--extra-scallopColor: #00eeff;
/* default: black */
--extra-scallopWeight: 1;
/* default: 2 */
/* Must add padding to show border properly*/
padding: 0.75rem;
background: paint(extra-scallopedBorder);
}
}
body {
font-family: monospace;
height: 100vh;
width: 100vw;
text-align: center;
padding: 0;
margin: 0;
}
h1 {
font-size: 4rem;
display: inline-block;
font-weight: 100;
margin: 1rem auto;
padding: 1rem 2rem;
}
p {
max-width: 660px;
margin: 0 auto;
font-weight: 300;
font-size: 1.2rem;
line-height: 2;
text-align: left;
}
</style>
<h1>Hello World</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit <i>asperiores</i> cupiditate dolor quo iste animi, eveniet in inventore <i>obcaecati</i> quisquam architecto pariatur et perspiciatis, deleniti voluptatum consequuntur <i>voluptas</i> voluptatibus repellat!</p>
<!-- This is where we include the worklet -->
<script>
// See files in scallopedBorder/*
CSS.registerProperty({
name: '--extra-scallopRadius',
syntax: '<number>',
inherits: false,
initialValue: 10
});
CSS.registerProperty({
name: '--extra-scallopColor',
syntax: '<color>',
inherits: true,
initialValue: 'black'
});
CSS.registerProperty({
name: '--extra-scallopWeight',
syntax: '<number>',
inherits: false,
initialValue: 2
});
(() => { const worklet = `
if (typeof registerPaint !== 'undefined') {
class ScallopedBorder {
static get inputProperties() {
return ['--extra-scallopRadius', '--extra-scallopWeight', '--extra-scallopColor']
}
paint(ctx, size, properties) {
const radius = properties.get('--extra-scallopRadius').value
const scallopWeight = properties.get('--extra-scallopWeight')
const color = properties.get('--extra-scallopColor')
const height = size.height
const width = size.width
ctx.lineWidth = scallopWeight
ctx.strokeStyle = color
const getSteps = (sizeVal) => {
return Math.floor(sizeVal / (radius * 2) - 2)
}
const getOwnRadius = (sizeVal, otherRad) => {
const steps = getSteps(sizeVal) + 1
const totalSpace = sizeVal - (radius * 2)
const spaceTaken = steps * (radius * 2)
let pixelsRemaining = totalSpace - spaceTaken
if (otherRad) {
const radDif = otherRad - radius
pixelsRemaining = totalSpace - spaceTaken - radDif
}
const newRadius = radius + ((pixelsRemaining / 2) / (steps + 1))
return (newRadius)
}
const horizRadius = getOwnRadius(width, getOwnRadius(height))
const vertRadius = getOwnRadius(height, getOwnRadius(width))
// top
for (let i = 0; i <= getSteps(width); i++) {
ctx.beginPath()
ctx.arc(horizRadius + horizRadius + (horizRadius * i * 2), horizRadius + (scallopWeight * 1) , horizRadius, 0, Math.PI, true)
ctx.stroke()
}
// bottom
for (let i = 0; i <= getSteps(width); i++) {
ctx.beginPath()
ctx.arc(horizRadius + horizRadius + (horizRadius * i * 2), height - horizRadius - (scallopWeight * 1), horizRadius, 0, Math.PI, false)
ctx.stroke()
}
// left
for (let i = 0; i <= getSteps(height); i++) {
ctx.beginPath()
ctx.arc(vertRadius + (scallopWeight * 1), vertRadius + vertRadius + (vertRadius * i * 2), vertRadius, Math.PI * 0.5, Math.PI * 1.5, false);
ctx.stroke()
}
// right
for (let i = 0; i <= getSteps(height); i++) {
ctx.beginPath()
ctx.arc(width - vertRadius - (scallopWeight * 1), vertRadius + vertRadius + (vertRadius * i * 2), vertRadius, Math.PI * 0.5, Math.PI * 1.5, true);
ctx.stroke()
}
}
}
registerPaint('extra-scallopedBorder', ScallopedBorder)
}`
const workletBlob = URL.createObjectURL(new Blob([worklet], { type: 'application/javascript' }))
window.CSS.paintWorklet.addModule(workletBlob)
})()
</script>"></iframe>
<h1>Beispiel 3</h1>
<iframe srcdoc="<style>@supports (background: paint(something)) {
h1 {
/*
Optionally set property values.
This can be done at root or local scope
*/
--extra-underlineNumber: 5;
/* default: 3 */
--extra-underlineColor: #8266ff;
/* default: black */
--extra-underlineSpread: 15;
/* default: 20 */
--extra-underlineWidth: 1;
/* default: 2 */
background: paint(extra-superUnderline);
line-height: 1.5;
}
i {
--extra-underlineColor: #00eeff;
/* default: black */
--extra-underlineSpread: 10;
/* default: 20 */
background: paint(extra-superUnderline);
}
}
body {
font-family: monospace;
height: 100vh;
width: 100vw;
text-align: center;
padding: 0;
margin: 0;
}
h1 {
font-size: 4rem;
display: inline-block;
font-weight: 100;
margin: 1rem auto;
padding: 1rem 2rem;
}
p {
max-width: 660px;
margin: 0 auto;
font-weight: 300;
font-size: 1.2rem;
line-height: 2;
text-align: left;
}</style><h1>Hello World</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit <i>asperiores</i> cupiditate dolor quo iste animi, eveniet in inventore <i>obcaecati</i> quisquam architecto pariatur et perspiciatis, deleniti voluptatum consequuntur <i>voluptas</i> voluptatibus repellat!</p>
<!-- This is where we include the worklet -->
<script>
// See files in superUnderline/*
CSS.registerProperty({
name: '--extra-underlineNumber',
syntax: '<number>',
inherits: false,
initialValue: 3
});
CSS.registerProperty({
name: '--extra-underlineColor',
syntax: '<color>',
inherits: true,
initialValue: 'black'
});
CSS.registerProperty({
name: '--extra-underlineSpread',
syntax: '<number>',
inherits: false,
initialValue: 20
});
CSS.registerProperty({
name: '--extra-underlineWidth',
syntax: '<number>',
inherits: false,
initialValue: 2
});
(() => { const worklet = `
const getRandom = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min
}
if (typeof registerPaint !== 'undefined') {
class SuperUnderline {
static get inputProperties() {
return ['--extra-underlineNumber', '--extra-underlineColor', '--extra-underlineSpread', '--extra-underlineWidth']
}
paint(ctx, size, properties) {
const numUnderlines = properties.get('--extra-underlineNumber')
const lineWidth = properties.get('--extra-underlineWidth')
const color = properties.get('--extra-underlineColor')
const spread = properties.get('--extra-underlineSpread')
ctx.lineWidth = lineWidth
ctx.strokeStyle = color
for (let i = 0; i < numUnderlines; i++) {
ctx.beginPath()
ctx.moveTo(0, getRandom(0, spread) + size.height/1.4)
ctx.lineTo(size.width, getRandom(0, spread) + size.height/1.4)
ctx.stroke()
}
}
}
registerPaint('extra-superUnderline', SuperUnderline)
}`
const workletBlob = URL.createObjectURL(new Blob([worklet], { type: 'application/javascript' }))
window.CSS.paintWorklet.addModule(workletBlob)
})()
</script>"></iframe>
<h1>Beispiel 4 </h1>
<iframe srcdoc="<style></style><h1>Hello World</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit <i>asperiores</i> cupiditate dolor quo iste animi, eveniet in inventore <i>obcaecati</i> quisquam architecto pariatur et perspiciatis, deleniti voluptatum consequuntur <i>voluptas</i> voluptatibus repellat!</p>
// This is where we use the custom properties
@supports (background: paint(something)) {
h1 {
/*
Optionally set property values.
This can be done at root or local scope
*/
--extra-sparkleNumber: 160; /* defaults to 30 */
--extra-sparkleHue: 80; /* Defaults to 60 (yellow) */
--extra-sparkleHeightVariance: 112; /* Defaults to 9 */
--extra-sparkleWidthVariance: 115; /* Defaults to 12 */
--extra-sparkleWeightVariance: 13; /* Defaults to 2 */
background: paint(extra-sparkles);
}
i {
--extra-sparkleNumber: 10; /* defaults to 30 */
--extra-sparkleHue: 30; /* Defaults to 60 (yellow) */
--extra-sparkleHeightVariance: 5; /* Defaults to 9 */
--extra-sparkleWeightVariance: 2; /* Defaults to 2 */
background: paint(extra-sparkles);
}
}
// Additional Styling
body {
font-family: monospace;
height: 100vh;
width: 100vw;
text-align: center;
padding: 0;
margin: 0;
}
h1 {
font-size: 4rem;
display: inline-block;
font-weight: 100;
padding: 1rem;
margin: 1rem auto;
position: relative;
}
p {
max-width: 660px;
margin: 0 auto;
font-weight: 300;
font-size: 1.2rem;
line-height: 2;
text-align: left;
}
<!-- This is where we include the worklet -->
<script>
CSS.registerProperty({
name: '--extra-sparkleNumber',
syntax: '<number>',
inherits: false,
initialValue: 30,
});
CSS.registerProperty({
name: '--extra-sparkleHue',
syntax: '<number>',
inherits: false,
initialValue: 60,
});
CSS.registerProperty({
name: '--extra-sparkleHeightVariance',
syntax: '<number>',
inherits: false,
initialValue: 9,
});
CSS.registerProperty({
name: '--extra-sparkleWidthVariance',
syntax: '<number>',
inherits: false,
initialValue: 12,
});
CSS.registerProperty({
name: '--extra-sparkleWeightVariance',
syntax: '<number>',
inherits: false,
initialValue: 2,
});
(() => { const worklet = `
const getRandom = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min
}
if (typeof registerPaint !== 'undefined') {
class ExtraSparkles {
static get inputProperties() {
return ['--extra-sparkleNumber', '--extra-sparkleHue', '--extra-sparkleHeightVariance', '--extra-sparkleWidthVariance', '--extra-sparkleWeightVariance']
}
paint(ctx, size, properties) {
const sparkles = properties.get('--extra-sparkleNumber')
const minHeight = 3
const maxHeight = minHeight + parseInt(properties.get('--extra-sparkleHeightVariance'))
const minWidth = 3
const maxWidth = minWidth + parseInt(properties.get('--extra-sparkleWidthVariance'))
const minWeight = 1
const maxWeight = minWeight + parseInt(properties.get('--extra-sparkleWeightVariance'))
for (let i = 0; i < sparkles; i++) {
const x = Math.random() * size.width
const y = Math.random() * (size.height - maxHeight)
const sparkleHeight = getRandom(minHeight, maxHeight)
const sparkleWidth = getRandom(minWidth, maxWidth)
const strokeWidth = getRandom(minWeight, maxWeight)
// Set Color
const hueVal = parseInt(properties.get('--extra-sparkleHue'))
const hue = getRandom(hueVal, hueVal + 20)
const sat = getRandom(90,100)
const light = getRandom(50,100)
const color = 'hsl(' + hue + 'deg,' + sat + '%,' + light + '%)'
// Set Stroke Info
ctx.lineWidth = strokeWidth
ctx.strokeStyle = color
// Paint
ctx.beginPath()
ctx.moveTo((x - sparkleWidth / 2), sparkleHeight/2 + y)
ctx.lineTo((x + sparkleWidth / 2), sparkleHeight/2 + y)
ctx.moveTo(x, 0 + y)
ctx.lineTo(x, sparkleHeight + y)
ctx.stroke()
}
}
}
registerPaint('extra-sparkles', ExtraSparkles)
}`
const workletBlob = URL.createObjectURL(new Blob([worklet], { type: 'application/javascript' }))
window.CSS.paintWorklet.addModule(workletBlob)
})()
</script>"></iframe>
</body>
</html>