button
  span.sr-only Reset
  svg.reset(viewBox="0 0 24 24")
    path(d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z")
svg.pencil
  marker#nib(viewBox="0 0 258 201" fill="none" refX="10" refY="100" markerUnits="strokeWidth" markerWidth="9" markerHeight="5.25" orient="auto")
    path(d='m.5.5 254 99-254 101V.5Z' fill='#FDF2CA')
    path(d='M243.581 99.537 4.5 194.605V6.352l239.081 93.185Z' fill='#FDF2CA' stroke='#000' stroke-width='8')
    path(d='m238 99.5-65.5 24V76L238 99.5Z' fill='#6F6F6F')

  marker#rubber(viewBox="0 0 204 200" fill="none" refX="150" refY="100" markerUnits="strokeWidth" markerWidth="5" markerHeight="8" orient="auto")
    mask#a(fill='#fff')
      path(fill-rule='evenodd' clip-rule='evenodd' d='M40 0v200h124c22.091 0 40-44.772 40-100S186.091 0 164 0H40Z')
    path(fill-rule='evenodd' clip-rule='evenodd' d='M40 0v200h124c22.091 0 40-44.772 40-100S186.091 0 164 0H40Z' fill='#D9D9D9')
    path(d='M40 200h-8v8h8v-8ZM40 0v-8h-8v8h8Zm8 200V0H32v200h16Zm116-8H40v16h124v-16Zm32-92c0 26.857-4.369 50.803-11.144 67.74-3.396 8.49-7.24 14.824-11.099 18.905-3.843 4.063-7.143 5.355-9.757 5.355v16c8.431 0 15.654-4.305 21.382-10.362 5.712-6.04 10.488-14.35 14.33-23.956C207.415 154.425 212 128.371 212 100h-16ZM164 8c2.614 0 5.914 1.292 9.757 5.355 3.859 4.081 7.703 10.415 11.099 18.905C191.631 49.197 196 73.143 196 100h16c0-28.371-4.585-54.425-12.288-73.682-3.842-9.606-8.618-17.916-14.33-23.956C179.654-3.695 172.431-8 164-8V8ZM40 8h124V-8H40V8Z' fill='#000' mask='url(#a)')
    path(d='M44 196V4h70c4.069 0 8.349 2.045 12.664 6.607 4.322 4.57 8.399 11.399 11.906 20.168C145.577 48.29 150 72.765 150 100c0 27.236-4.423 51.709-11.43 69.225-3.507 8.769-7.584 15.598-11.906 20.168C122.349 193.955 118.069 196 114 196H44Z' fill='#EBB7B7' stroke='#000' stroke-width='8')
    path(d='M40 4c4.069 0 8.35 2.045 12.664 6.607 4.322 4.57 8.399 11.399 11.906 20.168C71.577 48.29 76 72.765 76 100c0 27.236-4.423 51.709-11.43 69.225-3.507 8.769-7.584 15.598-11.906 20.168C48.349 193.955 44.069 196 40 196c-4.069 0-8.35-2.045-12.664-6.607-4.322-4.57-8.399-11.399-11.906-20.168C8.423 151.709 4 127.236 4 100c0-27.236 4.423-51.709 11.43-69.225 3.507-8.77 7.584-15.598 11.906-20.168C31.651 6.045 35.931 4 40 4Z' fill='#EBB7B7' stroke='#000' stroke-width='8')


  path.outline(stroke-linejoin="round")
  path.squiggle(stroke-linejoin="round")
  path.edge(marker-start="url(#rubber)" marker-end="url(#nib)" stroke-linejoin="round")
  g.clones
View Compiled
* {
  box-sizing: border-box;
  touch-action: none;
}

:root {
 --outline: hsl(0 0% 10%);
 --edge: hsl(45 25% 50% / 0.5);
 --body: hsl(45 95% 70%);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

button {
  height: 48px;
  aspect-ratio: 1;
  position: fixed;
  top: 1rem;
  right: 1rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  transition: transform 0.2s;
  padding: 0;
  transform: scale(var(--scale, 1)) translateY(var(--y));
}

button:hover {
  --scale: 1.1;
  --y: -5%;
}

button:active {
  --scale: 0.9;
  --y: 5%;
}

button svg {
  height: 80%;
  aspect-ratio: 1;
}

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

:root {
  --thickness: 4vmin;
}

#rubber, #nib {
  marker-height: var(--thickness);
  marker-width: var(--thickness);
}

path.squiggle {
  fill: none;
  stroke-width: calc(var(--thickness) * 0.9);
  stroke: var(--body);
}

path.outline {
  fill: none;
  stroke-width: var(--thickness);
  stroke: var(--outline);
}

path.edge {
  fill: none;
  stroke-width: calc(var(--thickness) * 0.2);
  stroke: var(--edge);
}

.point {
  height: 4px;
  aspect-ratio: 1;
  position: fixed;
  background: hsl(var(--hue, 10) 80% 50%);
  left: calc(var(--x, 0) * 1px);
  top: calc(var(--y, 0) * 1px);
  transform: translate(-50%, -50%);
}
const SVG = document.querySelector('svg.pencil')
const OUTLINE = SVG.querySelector('path.outline')
const SQUIGGLE = SVG.querySelector('path.squiggle')
const EDGE = SVG.querySelector('path.edge')
const CLONES = SVG.querySelector('.clones')
const REFRESHER = document.querySelector('button')

const RESET = () => {
  SVG.setAttribute('viewBox', `0 0 ${window.innerWidth} ${window.innerHeight}`)
  // OUTLINE.removeAttribute('d')
  // SQUIGGLE.removeAttribute('d')
  // EDGE.removeAttribute('d')
  CLONES.innerHTML = ''
}

let d
let outlineClone
let squiggleClone
let edgeClone

const CREATE_POINT = ({ x, y }) => {
  d += ` L${x} ${y}`
  // OUTLINE.setAttribute('d', d)
  // SQUIGGLE.setAttribute('d', d)
  // EDGE.setAttribute('d', d)
  outlineClone.setAttribute('d', d)
  squiggleClone.setAttribute('d', d)
  edgeClone.setAttribute('d', d)
}

const CLEAN = () => {
  document.body.removeEventListener('pointermove', CREATE_POINT)
  document.body.removeEventListener('pointerup', CLEAN)
}

const START = ({ x, y }) => {
  // based on <path d="M150 0 L75 200 L225 200 Z" />
  d = `M ${x} ${y}`
  // OUTLINE.setAttribute('d', d)
  // SQUIGGLE.setAttribute('d', d)
  // EDGE.setAttribute('d', d)
  //   Create the elements
  outlineClone = OUTLINE.cloneNode(true)
  squiggleClone = SQUIGGLE.cloneNode(true)
  edgeClone = EDGE.cloneNode(true)
  CLONES.appendChild(outlineClone)
  CLONES.appendChild(squiggleClone)
  CLONES.appendChild(edgeClone)
  outlineClone.setAttribute('d', d)
  squiggleClone.setAttribute('d', d)
  edgeClone.setAttribute('d', d)
  document.body.addEventListener('pointermove', CREATE_POINT)
  document.body.addEventListener('pointerup', CLEAN)
}

document.body.addEventListener('pointerdown', START)

window.addEventListener('resize', RESET)
RESET()

REFRESHER.addEventListener('click', RESET)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.