JSFiddle - React, Tailwind, and code Playground

by tJener

JavaScript

var createShadow = function( w, h, blur, color ) {
  typeof blur === 'number' || ( blur = 4 );
  color || ( color = 'black' );

  var scratch = document.createElement( 'canvas' );
  scratch.width = 2 * blur + w;
  scratch.height = 2 * ( blur + h );

  var ctx = scratch.getContext( '2d' );
  ctx.shadowColor = color;
  ctx.shadowBlur = blur;
  ctx.shadowOffsetX = 0;
  ctx.shadowOffsetY = -( h + blur ) * 1;
  ctx.translate( blur, 2 * blur + h );

  var shadow = document.createElement( 'canvas' );
  shadow.width = 2 * blur + w;
  shadow.height = 2 * blur + h;

  var draw = (function() {
    var ctx = shadow.getContext( '2d' );
    return function() {
      ctx.drawImage( scratch, 0, 0 );
    };
  }());

  return {
    _scratch: scratch,
    img: shadow,
    ctx: ctx,
    generateShadow: draw
  };
};

var drawHeart = function( ctx ) {
  ctx.beginPath();
  ctx.moveTo(55,15);
  ctx.bezierCurveTo(55,12,50,0,30,0);
  ctx.bezierCurveTo(0,0,0,37.5,0,37.5);
  ctx.bezierCurveTo(0,55,20,77,55,95);
  ctx.bezierCurveTo(90,77,110,55,110,37.5);
  ctx.bezierCurveTo(110,37.5,110,0,80,0);
  ctx.bezierCurveTo(65,0,55,13,55,15);
  ctx.fill();
};

var canvas = document.createElement( 'canvas' );
canvas.height = 400;
canvas.width = 600;
document.body.appendChild( canvas );
var ctx = canvas.getContext( '2d' );

// Draw black heart.
ctx.save();
ctx.translate( 45, 150 );
drawHeart( ctx );
ctx.restore();

// Draw warm fuzzy heart.
var fuzziness = 10;
var fuzzyHeart = createShadow( 110, 100, fuzziness, 'rgba(255,0,0,0.8)' );
// Draw heart to special canvas.
drawHeart( fuzzyHeart.ctx );
// Generate the blurred canvas based on what was drawn to the special canvas.
fuzzyHeart.generateShadow();
ctx.drawImage( fuzzyHeart.img, 445 - fuzziness, 150 - fuzziness );

ctx.drawImage( fuzzyHeart._scratch, 245 - fuzziness, 150 - fuzziness );