Skip to content

Instantly share code, notes, and snippets.

@fabrizzio-gz
Last active January 30, 2023 15:07
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fabrizzio-gz/8458bb13418e5bb6ea49133ba122930c to your computer and use it in GitHub Desktop.
Save fabrizzio-gz/8458bb13418e5bb6ea49133ba122930c to your computer and use it in GitHub Desktop.
Zoom and pan effects on a SVG element [demo](https://onestepcode.com/zoom-pan-effect-svg)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<div class="container row">
<button id="left-button">left</button>
<button id="right-button">right</button>
<button id="up-button">up</button>
<button id="down-button">down</button>
<button id="zoom-in-button">zoom-in</button>
<button id="zoom-out-button">zoom-out</button>
</div>
<div class="svg-container">
<svg
id="svg"
width="500"
height="500"
viewBox="0 0 500 500"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="250" cy="250" r="100" />
</svg>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
const svg = document.getElementById("svg");
const getTransformParameters = (element) => {
const transform = element.style.transform;
let scale = 1,
x = 0,
y = 0;
if (transform.includes("scale"))
scale = parseFloat(transform.slice(transform.indexOf("scale") + 6));
if (transform.includes("translateX"))
x = parseInt(transform.slice(transform.indexOf("translateX") + 11));
if (transform.includes("translateY"))
y = parseInt(transform.slice(transform.indexOf("translateY") + 11));
return { scale, x, y };
};
const getTransformString = (scale, x, y) =>
"scale(" + scale + ") " + "translateX(" + x + "%) translateY(" + y + "%)";
const pan = (direction) => {
const { scale, x, y } = getTransformParameters(svg);
let dx = 0,
dy = 0;
switch (direction) {
case "left":
dx = -3;
break;
case "right":
dx = 3;
break;
case "up":
dy = -3;
break;
case "down":
dy = 3;
break;
}
svg.style.transform = getTransformString(scale, x + dx, y + dy);
};
const zoom = (direction) => {
const { scale, x, y } = getTransformParameters(svg);
let dScale = 0.1;
if (direction == "out") dScale *= -1;
if (scale == 0.1 && direction == "out") dScale = 0;
svg.style.transform = getTransformString(scale + dScale, x, y);
};
document.getElementById("left-button").onclick = () => pan("left");
document.getElementById("right-button").onclick = () => pan("right");
document.getElementById("up-button").onclick = () => pan("up");
document.getElementById("down-button").onclick = () => pan("down");
document.getElementById("zoom-in-button").onclick = () => zoom("in");
document.getElementById("zoom-out-button").onclick = () => zoom("out");
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.row {
flex-direction: row;
}
.svg-container {
overflow: hidden;
height: 500px;
width: 500px;
}
svg {
transition: transform 0.1s linear 0.1s;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment