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) {
...