Start
//

This tutorial guides you through the essential concepts of working with ef-pan-zoom. Each step builds on the previous one, teaching you how to create interactive panning and zooming experiences.

Step 1: Basic Pan and Zoom

Let's start with the simplest pan-zoom — wrapping content in a pan-zoom container to enable interactive exploration.

What you'll learn: How to create a pan-zoom container that enables mouse/touch panning and wheel zooming.

<ef-pan-zoom class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-gray-100">
<div class="bg-gradient-to-br from-blue-400 to-purple-500 p-8 inline-flex items-center justify-center text-white text-4xl">
Pan &amp; Zoom
</div>
</ef-pan-zoom>

Try it yourself: Drag to pan and use Ctrl+Wheel (Cmd+Wheel on Mac) to zoom. Try scrolling the wheel without modifiers to pan vertically.

Step 2: Programmatic Control

Now let's control the pan-zoom transform programmatically by setting properties directly.

What you'll learn: How to set initial pan position and zoom level using attributes.

<ef-pan-zoom x="200" y="150" scale="1.5" class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-gray-100">
<div class="w-[1200px] h-[800px] bg-gradient-to-br from-green-400 to-blue-500 flex items-center justify-center text-white text-4xl">
Pan &amp; Zoom
</div>
</ef-pan-zoom>

Try it yourself: Modify the x, y, and scale values to see how they affect the initial view.

Step 3: Listening to Transform Changes

Pan-zoom elements dispatch events when the transform changes, allowing you to track user interactions.

What you'll learn: How to listen to transform-changed events to react to pan and zoom actions.

<ef-pan-zoom id="step3-pz" class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-gray-100">
<div class="w-[1200px] h-[800px] bg-gradient-to-br from-red-400 to-pink-500 flex items-center justify-center text-white text-4xl">
Track Transform Changes
</div>
</ef-pan-zoom>
<div id="step3-output" class="mt-2 font-mono text-sm text-gray-700">x: 0, y: 0, scale: 1</div>
<script>
document.getElementById('step3-pz').addEventListener('transform-changed', (e) => {
const { x, y, scale } = e.detail;
document.getElementById('step3-output').textContent =
'x: ' + x.toFixed(1) + ', y: ' + y.toFixed(1) + ', scale: ' + scale.toFixed(2);
});
</script>

Try it yourself: Pan and zoom the container — the transform values update in real time below it.

Step 4: Pan-Zoom with Video Content

Pan-zoom works with any content, including video elements. This enables creating interactive video viewers.

What you'll learn: How to combine ef-pan-zoom with video elements for explorable video content.

<ef-pan-zoom class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-black">
<ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="w-[1440px] h-[1080px] object-contain"></ef-video>
</ef-pan-zoom>

Try it yourself: Pan around the video and zoom in to explore details. The video continues playing while you interact with the pan-zoom.

Next Steps

Now that you understand the basics, explore:


How-To: Control Pan-Zoom Programmatically

Problem: You need to programmatically set or update the pan position and zoom level.

Solution: Set the x, y, and scale properties directly on the pan-zoom element.

<ef-pan-zoom id="prog-pz" x="300" y="200" scale="2" class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-gray-100">
<div class="w-[1200px] h-[800px] bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl">
Programmatically Positioned
</div>
</ef-pan-zoom>
// Set initial transform via attributes
// <ef-pan-zoom x="100" y="50" scale="1.5">
// Update transform via JS property assignment
const panZoom = document.querySelector('ef-pan-zoom');
panZoom.x = 200;
panZoom.y = 150;
panZoom.scale = 2;

Properties are reactive — updating them immediately updates the visual transform. Scale is automatically clamped between 0.1 and 5.


How-To: Listen to Transform Changes

Problem: You need to track when users pan or zoom to save state, update UI, or sync with other components.

Solution: Listen to the transform-changed event, which fires whenever the transform updates.

panZoom.addEventListener('transform-changed', (e) => {
const { x, y, scale } = e.detail;
// Save to state, localStorage, or sync with other components
console.log('Pan: (' + x + ', ' + y + '), Zoom: ' + scale);
});

The event detail contains { x, y, scale } representing the current transform. This fires for both user interactions and programmatic property updates.


How-To: Reset Transform to Default

Problem: You need to reset the pan-zoom back to its initial position and zoom level.

Solution: Call the reset() method, or set x, y, and scale back to their default values (0, 0, 1).

<ef-pan-zoom id="reset-pz" class="w-[720px] h-[480px] border-2 border-gray-300 overflow-hidden bg-gray-100">
<div class="w-[1200px] h-[800px] bg-gradient-to-br from-orange-400 to-red-500 flex items-center justify-center text-white text-4xl">
Pan and zoom, then reset
</div>
</ef-pan-zoom>
<div class="mt-4 flex gap-2">
<button onclick="document.getElementById('reset-pz').reset()" class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600">Reset View</button>
<button onclick="document.getElementById('reset-pz').scale = 2" class="px-3 py-1 bg-purple-500 text-white rounded hover:bg-purple-600">Zoom 2x</button>
</div>
const panZoom = document.querySelector('ef-pan-zoom');
function resetTransform() {
panZoom.reset(); // equivalent to: panZoom.x = 0; panZoom.y = 0; panZoom.scale = 1;
}

The transform updates immediately when properties are set. Apply a CSS transition to ef-pan-zoom's inner wrapper if you want a smooth animated reset.