<!--
Worklet code here. I can't put this under JS pane anymore since
I can't do CSS.paintWorklet.addModule('/rrenula/pen/js-code.js'); due to
cors issue
-->
<script language="worklet">
if (typeof registerPaint !== 'undefined') {
class Checkbox {
static get inputProperties() {
return ['--checkbox-color', '--edge', '--thickness', '--p1', '--p2'];
}
paint(ctx, size, props) {
const color = props.get('--checkbox-color');
const edge = props.get('--edge').value;
const p1 = props.get('--p1').value;
const p2 = props.get('--p2').value;
const x = edge
const y = edge
const finalX = size.width - edge
const finalY = size.height - edge
ctx.strokeStyle = color.toString()
ctx.lineWidth = 5
/* Top left to bottom right*/
ctx.beginPath()
ctx.moveTo(x, y)
ctx.lineTo((p1 / 100) * finalX, (p1 / 100) * finalY)
if (p1 > 0) {
ctx.stroke()
}
ctx.beginPath();
ctx.moveTo(finalX, y);
ctx.lineTo(finalX, y);
if (p2 > 0) {
// x is gradually moving to its original point
ctx.lineTo(finalX - ((p2 / 100) * finalX) + edge, finalY * (p2 / 100));
ctx.stroke();
}
}
}
registerPaint('checkbox', Checkbox)
}
</script>
<script type="module">
CSS.registerProperty({
name: `--checkbox-color`,
syntax: '<color>',
inherits: false,
initialValue: 'transparent'
})
CSS.registerProperty({
name: `--edge`,
syntax: '<number>',
inherits: false,
initialValue: 0
})
CSS.registerProperty({
name: `--thickness`,
syntax: '<number>',
inherits: false,
initialValue: 0
})
CSS.registerProperty({
name: `--p1`,
syntax: '<percentage>',
inherits: false,
initialValue: '0%'
})
CSS.registerProperty({
name: `--p2`,
syntax: '<percentage>',
inherits: false,
initialValue: '0%'
})
function ready(fn) {
if (document.readyState != 'loading'){
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(() => {
function blobWorklet() {
const qs = document.querySelector('script[language="worklet"]')
const src = qs.innerHTML;
const blob = new Blob([src], {type: 'text/javascript'});
return URL.createObjectURL(blob);
}
CSS.paintWorklet.addModule(blobWorklet())
if ('paintWorklet' in CSS) {
document.querySelector('.notice').classList.add('hidden')
}
})
</script>
<div class="wrapper">
Write up on this demo can be found <a href="https://aysha.me/019/08/css-houdini-properties-values-and-the-paint-api/" target="_blank">here on my blog</a>
<div class="notice">
This demo uses CSS Houdini. If you are seeing this, you need to enable CSS Houdini by navigating to <code>chrome://flags</code> and enable <code>Experimental Web Platform features</code>
</div>
<p class="q">Who would you take out on a date?</p>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Lord Voldemort</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Harry Potter</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Margaery Tyrell</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Robb Stark</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Legolas</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Yennefer</span></label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" class="checkbox">
<label> <span class="checkbox-label">Geralt</span></label>
</div>
</div>
/* CSS files add styling rules to your content */
body {
font-family: "Benton Sans", "Helvetica Neue", helvetica, arial, sans-serif;
margin: 2em;
background: #9e4fdb;
color: #fff;
font-family: 'Lato', sans-serif;
}
h1 {
font-style: italic;
color: #373fff;
}
a,
a:visited {
color: white;
}
a:hover {
color: darkblue;
}
.q {
font-size: 2.5rem;
font-weight: 300;
}
.wrapper {
max-width: 960px;
margin: 20px auto;
}
.checkbox-label {
font-size: 2rem;
vertical-align: middle;
color: #68388e;
}
.checkbox-wrapper {
margin-bottom: 16px;
}
.checkbox {
--edge: 5;
--thickness: 5;
transition: --checkbox-color 500ms, background-color 500ms;
}
@supports (background: paint(id)) {
.checkbox {
appearance: none;
background-image: paint(checkbox);
}
}
.checkbox:hover {
--p1: 100%;
--p2: 100%;
--checkbox-color: #ccc;
}
.checkbox:checked {
--checkbox-color: white;
--p1: 100%;
--p2: 100%;
background-color: deeppink;
animation: draw 500ms ease-in-out;
}
.checkbox:checked + label > .checkbox-label {
color: #fff;
}
.checkbox {
--checkbox-color: transparent;
margin-right: 24px;
vertical-align: middle;
width: 50px;
height: 50px;
border-radius: 2px;
border: 3px solid #fff;
transition: --checkbox-color 500ms, background-color 500ms;
}
.notice {
background-color: darkred;
padding: 8px;
font-size: 20px;
line-height: 1.5;
}
.hidden {
display: none;
}
@keyframes draw {
0% {
--p1: 0%;
--p2: 0%;
}
50% {
--p1: 100%;
--p2: 0%;
}
80% {
--p1: 100%;
}
100% {
--p1: 100%;
--p2: 100%;
}
}
// The JS code for this pen is at the top of the HTML
This Pen doesn't use any external JavaScript resources.