I have created pulse animation using html canvas. There is two rectangles. Rectangle’s positions is updated dynamically. The smaller rectangle has pulse animation. I have problem calculate it’s center position value.
Without scaling I get correct position. But when scaling position is incorrect. How to calculate scaled X and Y?
HTML
<div class="wrap"></div>
JS
const canvas = document.createElement("canvas");
canvas.setAttribute("width", "500px");
canvas.setAttribute("height", "500px");
const ctx = canvas.getContext("2d");
const wrapper = document.getElementsByClassName("wrap")[0];
wrapper.appendChild(canvas);
let scale = 1;
let angle = 0;
const blockSize = 45; // Rectangle size
const pos = {x: 2, y: 1}; // Rectangle position
function anim(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setTransform(1, 0, 0, 1, 0, 0);
draw(ctx, pos)
update();
requestAnimationFrame(anim);
}
anim();
function draw(ctx, position){
ctx.fillStyle = "#000";
ctx.fillRect((position.x * blockSize - blockSize), (position.y * blockSize - blockSize), blockSize, blockSize);
// Smaller rectangle with pulse
ctx.fillStyle = "red";
const centerX = (position.x * blockSize - blockSize) / 2;
const centerY = (position.y * blockSize - blockSize) / 2;
const scaledX = centerX - (centerX * scale);
const scaledY = centerY - (centerY * scale);
ctx.setTransform(scale, 0, 0, scale, centerX, scaledY);
const recSize = 30;
const x = (position.x * blockSize - blockSize) + ((blockSize - recSize) / 2);
const y = (position.y * blockSize - blockSize) + ((blockSize - recSize) / 2);
ctx.fillRect(x, y, recSize, recSize);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
function update(){
angle += Math.PI / 140;
scale = 0.5 + Math.abs(Math.cos(angle));
}
const canvas = document.createElement("canvas");
canvas.setAttribute("width", "500px");
canvas.setAttribute("height", "500px");
const ctx = canvas.getContext("2d");
const wrapper = document.getElementsByClassName("wrap")[0];
wrapper.appendChild(canvas);
let scale = 1;
let angle = 0;
const blockSize = 45; // Rectangle size
const pos = {x: 2, y: 1}; // Rectangle position
function anim(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setTransform(1, 0, 0, 1, 0, 0);
draw(ctx, pos)
update();
requestAnimationFrame(anim);
}
anim();
function draw(ctx, position){
ctx.fillStyle = "#000";
ctx.fillRect((position.x * blockSize - blockSize), (position.y * blockSize - blockSize), blockSize, blockSize);
// Smaller rectangle with pulse
ctx.fillStyle = "red";
const centerX = (position.x * blockSize - blockSize) / 2;
const centerY = (position.y * blockSize - blockSize) / 2;
const scaledX = centerX - (centerX * scale);
const scaledY = centerY - (centerY * scale);
ctx.setTransform(scale, 0, 0, scale, centerX, scaledY);
const recSize = 30;
const x = (position.x * blockSize - blockSize) + ((blockSize - recSize) / 2);
const y = (position.y * blockSize - blockSize) + ((blockSize - recSize) / 2);
ctx.fillRect(x, y, recSize, recSize);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
function update(){
angle += Math.PI / 140;
scale = 0.5 + Math.abs(Math.cos(angle));
}
<div class="wrap">
</div>