I am trying to draw a bell icon on an HTML canvas
and need animation effects on the image like a bell ringing. I haven't been able to find a good way to resolve this. Like draw a bell icon and only do vibration on the lower part of the bell. Can someone give me a hint and show an example? Here's what I've done so far:
var x = 20;
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
var mapSprite = new Image();
mapSprite.src = "https://png.pngtree.com/png-vector/20190411/ourmid/pngtree-vector-bell-icon-png-image_927119.jpg";
function drawIt() {
window.requestAnimationFrame(drawIt);
c.globalAlpha = 0.07;
c.clearRect(0, 0, canvas.width, canvas.height);
// c.fillStyle = "white";
c.fillRect(x, 10, 80, 100);
c.stroke();
c.globalAlpha = 1;
c.drawImage(mapSprite, x, 10, 80, 100);
if (x == 20)
x -= 3
else
x += 1;
}
//window.requestAnimationFrame(drawIt);
drawIt();
#canvas {
border: 1px solid silver;
width: 100%;
}
<canvas id="canvas"></canvas>
You need to separate the bell dome from the clapper and animate them separately (or draw the clapper your self with a circle).
You can either only move the clapper or add different animations to each of them: while the clapper would describe an arc trajectory, bouncing from side to side of the dome, the dome would rotate from the top center.
Here's a simplified version of this:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = document.body.offsetWidth;
const height = canvas.height = document.body.offsetHeight;
const bellImg = new Image();
bellImg.src = "https://i.sstatic.net/Hc7Ih.png";
const clapperRadius = 25;
const lineWidth = 10;
let progress = 0.5;
let progressDelta = 0.05;
function tick() {
ctx.clearRect(0, 0, width, height);
ctx.lineWidth = lineWidth;
ctx.beginPath();
const circleLeftMin = width / 2 - bellImg.width / 2 + clapperRadius + lineWidth;
const circleLeftMax = width / 2 + bellImg.width / 2 - clapperRadius - lineWidth;
const circleLeft = Math.min(Math.max(circleLeftMin + (circleLeftMax - circleLeftMin) * progress, circleLeftMin), circleLeftMax);
progress += progressDelta
if (progress >= 1 || progress <= 0) {
progressDelta = -progressDelta
}
ctx.arc(
circleLeft,
height / 2 + bellImg.height / 2,
clapperRadius,
0,
2 * Math.PI,
);
ctx.stroke();
ctx.drawImage(
bellImg,
width / 2 - bellImg.width / 2,
height / 2 - bellImg.height / 2
);
window.requestAnimationFrame(tick);
}
bellImg.onload = () => {
tick();
}
html,
body {
margin: 0;
height:100%;
}
#canvas {
position:absolute;
width: 100%;
height :100%;
}
<canvas id="canvas"></canvas>