var ctx = canvas.getContext('2d');
var angle = 0;
var scale = 1;
var img = new Image();
img.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';
anim();
function anim() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateScale();
drawCircle();
drawTriangle();
drawImage();
ctx.setTransform(1, 0, 0, 1, 0, 0);
requestAnimationFrame(anim);
}
function updateScale() {
angle += Math.PI / 220;
scale = 0.5 + Math.abs(Math.cos(angle));
}
function drawCircle() {
ctx.beginPath();
var cx = 75,
cy = 50,
radius = 25;
// for the circle, centerX and centerY are given
var anchorX = cx,
anchorY = cy;
// with these anchorX, anchorY and scale,
// we can determine where we need to translate our context once scaled
var scaledX = anchorX - (anchorX * scale),
scaledY = anchorY - (anchorY * scale);
// then we apply the matrix in one go
ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
// and we draw normally
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.fill();
}
function drawTriangle() {
ctx.beginPath();
// for the triangle, we need to find the position between minX and maxX,
// and between minY and maxY
var anchorX = 175 + (200 - 175) / 2,
anchorY = 25 + (75 - 25) / 2;
var scaledX = anchorX - (anchorX * scale),
scaledY = anchorY - (anchorY * scale);
ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
ctx.moveTo(175, 50);
ctx.lineTo(200, 75);
ctx.lineTo(200, 25);
ctx.fill();
}
function drawImage() {
if (!img.naturalWidth) return;
// for rects, it's just pos + (length / 2)
var anchorX = 250 + img.naturalWidth / 2,
anchorY = 25 + img.naturalHeight / 2;
var scaledX = anchorX - (anchorX * scale),
scaledY = anchorY - (anchorY * scale);
ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
ctx.drawImage(img, 250, 25);
}
<canvas id="canvas" width="500"></canvas>