JSFiddle - React, Tailwind, and code Playground

by velo_ninja

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Beer Mug Fill Animation</title>
  <style>
    body {
      background: #f9f1db;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
    }
    canvas {
      background: #fff;
      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
      border-radius: 12px;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="300" height="600"></canvas>

  <!-- Load OpenCV.js -->
  <script async src="https://docs.opencv.org/4.x/opencv.js"></script>
  <script>
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext("2d");

    const img = new Image();
    img.crossOrigin = "anonymous";
    img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Beer_Mug.png/480px-Beer_Mug.png"; // Replace with your desired image

    let fillLevel = 0;
    let mask = null;

    img.onload = () => {
      const hiddenCanvas = document.createElement("canvas");
      hiddenCanvas.width = canvas.width;
      hiddenCanvas.height = canvas.height;
      const hiddenCtx = hiddenCanvas.getContext("2d");
      hiddenCtx.drawImage(img, 50, 50, 200, 500);

      let src = cv.imread(hiddenCanvas);
      let gray = new cv.Mat();
      cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY);

      let edges = new cv.Mat();
      cv.Canny(gray, edges, 100, 200);

      let contours = new cv.MatVector();
      let hierarchy = new cv.Mat();
      cv.findContours(edges, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);

      // Create mask from the largest contour
      mask = new cv.Mat.zeros(src.rows, src.cols, cv.CV_8UC1);
      let maxContour = null;
      let maxArea = 0;
      for (let i = 0; i < contours.size(); i++) {
        const area = cv.contourArea(contours.get(i));
        if (area > maxArea) {
          maxArea = area;
          maxContour = contours.get(i);
        }
      }
      if (maxContour) {
       ...