<canvas id="full-canvas"></canvas>
<canvas id="prev-canvas"></canvas>
html, body {
height: 100%;
}
body {
margin: 0;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
#prev-canvas {
width: 128px;
height: 128px;
top: 20px;
left: 20px;
outline: 2px solid red;
pointer-events: none;
}
const imageUrl =
"https://images.unsplash.com/photo-1548681528-6a5c45b66b42?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1024&q=90";
const previewScale = 1.5;
// const dpr = window.devicePixelRatio || 1;
const dpr = 2;
const canvas = document.getElementById("full-canvas");
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
const ctx = canvas.getContext("2d");
const canvasPrev = document.getElementById("prev-canvas");
canvasPrev.width = 128 * dpr;
canvasPrev.height = 128 * dpr;
const ctxPrev = canvasPrev.getContext("2d");
ctx.scale(dpr, dpr);
ctxPrev.scale(dpr, dpr);
function draw(image) {
const iw = image.naturalWidth;
const ih = image.naturalHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(
image,
coverImage(window.innerWidth, window.innerHeight, iw, ih)
);
}
loadImg(imageUrl).then((image) => {
draw(image);
window.addEventListener("resize", () => {
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
ctx.scale(dpr, dpr);
draw(image);
});
canvas.addEventListener("mousemove", (event) => {
const x = event.clientX * dpr;
const y = event.clientY * dpr;
const invScale = previewScale <= 0 ? 0 : 1 / previewScale;
ctxPrev.clearRect(0, 0, canvasPrev.width, canvasPrev.height);
ctxPrev.drawImage(
canvas,
x - (canvasPrev.width / 2) * invScale,
y - (canvasPrev.height / 2) * invScale,
canvasPrev.width * invScale,
canvasPrev.height * invScale,
0,
0,
canvasPrev.width / dpr,
canvasPrev.height / dpr
);
});
});
// ========== utils ==========
function loadImg(src) {
return new Promise((resolve) => {
const img = new Image();
img.addEventListener("load", () => resolve(img));
// img.crossOrigin = 'Anonymous';
img.src = src;
});
}
function coverImage(tSizeX, tSizeY, iSizeX, iSizeY, pivotX = 0.5, pivotY = 0.5) {
const ratio = Math.max(tSizeX / iSizeX, tSizeY / iSizeY);
const dw = iSizeX * ratio;
const dh = iSizeY * ratio;
const dx = (tSizeX - dw) * pivotX;
const dy = (tSizeY - dh) * pivotY;
return [0, 0, iSizeX, iSizeY, dx, dy, dw, dh];
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.