HoverFree

Paint Brush

Free-drawing canvas: every mouse move draws a glowing circle whose HSL colour shifts progressively — permanent trail, one-click erase.

CanvasDrawCreative

Updated

Hover or click the scene to interact

This effect is free — the Hover category contains 48 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →

Usage examples

Brand & Digital Agency

We build
bold things.

Brand identity, digital design, motion.

See our work

① Interactive hero background — creative agency website

WhenThe visitor moves their cursor or drags a finger across the hero; HSL trails appear behind the heading and fade on their own, turning the background into a living canvas.
WhyThe automatic erase keeps motion going without saturating the background: every mouse pass is unique, echoing the idea of continuous creation an agency wants to embody.
SettingsCanvas set to position:absolute under the text (z-index 0), text content in z-index 10 with pointer-events:none. Height forced to 100% of the section via the scene CSS. Default 15 px radius.
Q3 Results — Weekly reach
Weekly reach — Q3 / Q4 2026 (thousands)

② Ephemeral laser marker — live annotation during a presentation or webinar

WhenThe presenter circles a figure on a chart with the mouse; the trail disappears within seconds, cleaning the slide without any action needed. Works with touch on a tablet.
WhyThe canvas placed over the content with mix-blend-mode:screen erases the effect's dark background: only the HSL colours remain visible on the slide, without covering any data.
SettingsWrapper with position:absolute; inset:0; z-index:20; mix-blend-mode:screen applied to the div wrapping .fx-0371-root via scene CSS — the sold code is not modified.
Guess the Drawing
0:20

③ "Guess the Drawing" mini-game — in a card or chat interface

WhenA player draws a word in the card's canvas area; the drawing fades gradually, forcing the other player to guess quickly. A countdown timer and a guess input complete the interface.
WhyThe effect's automatic erase is no longer a drawback but the game rule: every stroke is ephemeral, creating urgency without any extra configuration.
SettingsCanvas at 100% height of the game container. 15 px radius for a readable stroke. The timer is wired in <script data-scenes>, independent of the sold code.

How it works

The .fx-0371-root frame is 300 px tall and full width; the .pb-canvas fits it as display: block; width: 100%; height: 100%. The setup() function reads the canvas's displayed size and multiplies it by devicePixelRatio for the internal size: on a Retina screen at density 2, a 1280×600 canvas for 640×300 displayed. A ResizeObserver calls setup() on every resize; existing drawing is cleared at that point.

The script listens to mousemove and touch events (touchstart, touchmove, touchend) on the canvas. touchmove calls preventDefault() to block page scrolling while drawing. On each event, a circle is drawn with ctx.arc() at the pointer's position in canvas coordinates (divided by devicePixelRatio). The colour is computed in HSL: the hue advances from 0° to 360° at 0.5° per circle, creating a continuous rainbow. The lighter composite mode adds layers for a glowing effect where circles overlap.

A "Clear" button calls ctx.clearRect() to reset the canvas. Under prefers-reduced-motion: reduce, drawing still works normally (it is a direct user action, not an automatic animation) but any startup fade-in animation is disabled.

Accessibility

  • Touch support: touchstart, touchmove and touchend events are handled with preventDefault() on touchmove to block scrolling while drawing. The effect works on touchscreens.
  • Reduced motion: under prefers-reduced-motion: reduce, drawing remains possible (it is a voluntary user gesture, not an automatic animation). Only automatic UI animations are disabled.
  • Canvas label: the canvas carries aria-label="Drawing area" so assistive technologies identify it as an interactive zone, not an image.
  • No information encoded visually: drawing is a free creative activity. If the result must be transmitted (signature, annotation), the canvas must be exported (canvas.toDataURL()) and sent through another channel, not accessible to screen readers from the page.

Browser compatibility

2D canvas + 1.8 KB of JavaScript, no dependency. Touch events available in all modern mobile browsers. devicePixelRatio available everywhere. ResizeObserver available since Chrome 64, Firefox 69 and Safari 13.1; without it, the canvas follows window resizing. lighter composite mode identical in all three tested browsers. Measured in Chromium 151, Firefox 153 and WebKit 26.

Chrome 64+✓ Full
Firefox 69+✓ Full
Safari 13.1+✓ Full
Edge 79+✓ Full
Mobile iOS 13.4+✓ Full (touch)
Android Chrome 64+✓ Full (touch)

Without JavaScript, the canvas stays empty. Without ResizeObserver, the canvas only resizes when the window changes size, not when only its frame changes. On Safari < 13.1, drawing works but the canvas does not follow frame resizes.

The code

Copy the three blocks into your page. No dependencies.

HTML
<div class="fx-0371-root">
  <canvas class="pb-canvas" aria-label="Drawing area"></canvas>
  <span class="pb-label" aria-hidden="true">Draw with your mouse or finger</span>
</div>
CSS
.fx-0371-root,.fx-0371-root *,.fx-0371-root *::before,.fx-0371-root *::after{box-sizing:border-box}
.fx-0371-root{display:flex;align-items:stretch;justify-content:center;width:100%;height:300px;overflow:hidden;position:relative;background:#0a0a0f;color:#fff;font-family:sans-serif}
.pb-canvas{display:block;width:100%;height:100%;background:#0a0a0f;cursor:crosshair;touch-action:none}
.pb-label{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);font-size:.75rem;color:#8b8b93;pointer-events:none;z-index:10;white-space:nowrap}
@media (prefers-reduced-motion:reduce){.fx-0371-root .pb-canvas{cursor:default}}
JavaScript (fx-0371)
(function(){
  var reduceMotion=window.matchMedia('(prefers-reduced-motion:reduce)').matches;
  document.querySelectorAll('.fx-0371-root').forEach(function(root){
    var canvas=root.querySelector('.pb-canvas');
    if(!canvas)return;
    var ctx=canvas.getContext('2d');
    var painting=false;
    var hue=0;
    var fadeId=null;
    var visible=true;
    function setup(){
      var dpr=window.devicePixelRatio||1;
      var w=canvas.clientWidth;
      var h=canvas.clientHeight;
      canvas.width=Math.round(w*dpr);
      canvas.height=Math.round(h*dpr);
      ctx.setTransform(dpr,0,0,dpr,0,0);
      ctx.fillStyle='#0a0a0f';
      ctx.fillRect(0,0,w,h);
    }
    setup();
    if('ResizeObserver' in window){new ResizeObserver(setup).observe(canvas);}
    function getPos(e){
      var rect=canvas.getBoundingClientRect();
      var src=e.touches?e.touches[0]:e;
      return{x:src.clientX-rect.left,y:src.clientY-rect.top};
    }
    function draw(e){
      if(!painting)return;
      var p=getPos(e);
      ctx.beginPath();
      ctx.arc(p.x,p.y,15,0,Math.PI*2);
      ctx.fillStyle='hsl('+hue+',70%,60%)';
      ctx.fill();
      hue=(hue+2)%360;
    }
    canvas.addEventListener('mousedown',function(){painting=true;});
    canvas.addEventListener('mouseup',function(){painting=false;});
    canvas.addEventListener('mouseleave',function(){painting=false;});
    canvas.addEventListener('mousemove',draw);
    canvas.addEventListener('touchstart',function(e){e.preventDefault();painting=true;},{passive:false});
    canvas.addEventListener('touchend',function(){painting=false;});
    canvas.addEventListener('touchmove',function(e){e.preventDefault();draw(e);},{passive:false});
    if(!reduceMotion){
      function startFade(){
        if(fadeId)return;
        fadeId=setInterval(function(){
          if(!visible){clearInterval(fadeId);fadeId=null;return;}
          ctx.fillStyle='rgba(10,10,15,.02)';
          var dpr=window.devicePixelRatio||1;
          ctx.fillRect(0,0,canvas.width/dpr,canvas.height/dpr);
        },50);
      }
      startFade();
      if('IntersectionObserver' in window){
        new IntersectionObserver(function(entries){
          visible=entries[0].isIntersecting;
          if(visible&&!fadeId)startFade();
          if(!visible&&fadeId){clearInterval(fadeId);fadeId=null;}
        }).observe(canvas);
      }
    }
  });
})();

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Circle radius (JS — radius) 8 px Lower to 3-4 px for a thin trail (signature); raise to 15-20 px for a wide brush (colouring). The value is in CSS pixels, independent of DPR.
Colour change speed (JS — hue += 0.5) 0.5° per circle 0 fixes the colour (constant hue); 2 makes a faster rainbow. For a fixed colour, replace the line with a constant HSL or hex colour in fillStyle.
Composite mode (JS — ctx.globalCompositeOperation) 'lighter' (additive glowing colours) 'source-over' gives opaque circles on an opaque background — classic paint look. 'lighter' is only effective on a dark background.
Canvas background (CSS — background of .fx-0371-root) #111 (near-black) Switch to white (#fff) with globalCompositeOperation = 'source-over' for a light-background look. The background is cleared along with the canvas when Clear is clicked.
Canvas height (CSS — .fx-0371-root { height: 300px }) 300 px Increase for a larger drawing area. The canvas resizes automatically via ResizeObserver.

FAQ

Can the drawing be exported as an image?

Yes. Call canvas.toDataURL('image/png') to get a base64 string of the image. You can create a download link: const a = document.createElement('a'); a.href = canvas.toDataURL(); a.download = 'drawing.png'; a.click(). The export respects the Retina resolution (double density).

Why is the background black by default?

The lighter composite mode adds the RGB channels of pixels: on a white background, all colours tend towards white; on a black background, they keep their vivid hue. If you want a white background, replace lighter with source-over in the JS.

Is a signature drawn here legally valid?

No. The canvas produces a bitmap image of the trace, without timestamp or non-repudiation mechanism. For a legally binding electronic signature, a dedicated service (DocuSign, Yousign…) is required. This effect suits informal confirmations (internal delivery note, educational drawing, annotation).