<div class='example'>CSS</div>
<div class='example'>Painting</div>
<div class='example'>API</div>
<div class='example'>is NOT here yet</div>
<div class='example'>BUT</div>
<div class='example'>we can use</div>
<div class='example'>the standard canvas</div>
<div class='example'>to</div>
<div class='example'>paint</div>
<div class='example'>some borders</div>
<div class='example'>...</div>
<div class='example'>Why not?</div>
<div class='example'>OOOOO</div>
<div class='example'>Lorem ipsum</div>
<div class='example'>dolor sit amet</div>
<div class='example'>consectetur adipiscing elit</div>
<div class='example'>sed</div>
<div class='example'>do</div>
<div class='example'>eiusmod tempor incididunt ut labore</div>
<div class='example'>et dolore</div>
<div class='example'>magna</div>
<div class='example'>aliqua</div>
<div class='example'>.</div>
@import url('https://fonts.googleapis.com/css2?family=Zeyada&display=swap');

.example {
    display: block;
    float: left;
    max-width: 80vw;
    margin: 4px;
    position: relative;
    font-family: 'Zeyada', cursive;
    font-size: 32px;
    font-weight: 400;
    font-style: normal;
    line-height: 1;
    padding: 16px 16px 8px 28px;

    > canvas {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
        z-index: -1;
    }
}
const examples = document.querySelectorAll('.example');

function drawLine(context, width, x1, y1, x2, y2) {
    const dx = x2 - x1;
    const dy = y2 - y1;
    const length = Math.sqrt(dx ** 2 + dy ** 2);
    const radius = width / 2;
    const step = radius / 2;
    const n = length / step;
    const stepX = dx / n;
    const stepY = dy / n;

    for (let i = 0; i < n; i++) {
        const progress = i / n;
        const x = x1 + i * stepX + radius * Math.sin(2 * progress);
        const y = y1 + i * stepY + radius * Math.cos(2 * progress);

        context.beginPath();
        context.arc(x, y, radius, 0, 2 * Math.PI);
        context.fill();
    }
}

function drawEverything() {
    examples.forEach((example) => {
        let canvas = example.querySelector('canvas');

        if (!canvas) {
            canvas = document.createElement('canvas');

            example.appendChild(canvas);
        }

        const context = canvas.getContext('2d');
        const scale = window.devicePixelRatio;
        const width = example.offsetWidth;
        const height = example.offsetHeight;
        const canvasWidth = Math.floor(width * scale);
        const canvasHeight = Math.floor(height * scale);
        const boldWidth = 2;
        const standardWidth = 1;
        const delta = 3;
        const p = boldWidth + delta; // padding
        const s = 8; // skew
        const sp = s + p;
        const step = 8;
        const x1 = sp + delta * Math.random();
        const y1 = p + delta * Math.random();
        const x2 = width - p + delta * Math.random();
        const y2 = p + delta * Math.random();
        const x3 = width - p + delta * Math.random();
        const y3 = height - sp + delta * Math.random();
        const x4 = sp + delta * Math.random();
        const y4 = height - sp + delta * Math.random();
        const x5 = p + delta * Math.random();
        const y5 = sp + delta * Math.random();
        const x6 = p + delta * Math.random();
        const y6 = height - p + delta * Math.random();
        const x7 = width - sp + delta * Math.random();
        const y7 = height - p + delta * Math.random();

        canvas.height = canvasHeight;
        canvas.width = canvasWidth;
        context.scale(scale, scale);

        context.clearRect(0, 0, width, height);
        context.fillStyle = '#777777';

        for (let x = x1; x < x7 - p; x += step) {
            drawLine(
                context,
                standardWidth,
                x + delta * Math.random(),
                (y6 + y7) / 2,
                x + s + delta * Math.random(),
                (y4 + y3) / 2 + 1,
            );
        }

        for (let y = y1 + step; y < y4 - p; y += step) {
            drawLine(
                context,
                standardWidth,
                (x1 + x4) / 2,
                y + delta * Math.random(),
                (x5 + x6) / 2,
                y + s + delta * Math.random(),
            );
        }

        context.fillStyle = '#000000';

        drawLine(context, boldWidth, x1, y1, x2, y2);
        drawLine(context, boldWidth, x2, y2, x3, y3);
        drawLine(context, boldWidth, x3, y3, x4, y4);
        drawLine(context, boldWidth, x4, y4, x1, y1);

        drawLine(context, boldWidth, x1, y1, x5, y5);
        drawLine(context, boldWidth, x5, y5, x6, y6);
        drawLine(context, boldWidth, x6, y6, x4, y4);
        drawLine(context, boldWidth, x6, y6, x7, y7);
        drawLine(context, boldWidth, x7, y7, x3, y3);
    });
}

function main() {
    drawEverything();

    window.addEventListener('resize', drawEverything);
}

document.addEventListener('DOMContentLoaded', main);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.