スマホ時に現地案内図や敷地配置図が小さくて見づらいとき用のzoom機能です。主にスマホ。
ピンチすればいいじゃないか、という意見は受け付けません。
<div class="zoomFigure__cont">
<img src="https://placehold.jp/300x300.png" alt="Zoomable Image" class="zoomable-image">
<div class="zoom-controls">
<button id="zoomInBtn">ズームイン</button>
<button id="zoomOutBtn">ズームアウト</button>
</div>
</div>
.zoomFigure__cont {
position: relative;
overflow: hidden;
display: inline-block;
width: 300px;
height: 300px;
}
.zoomable-image {
position: absolute; /* 画像を絶対配置にする */
transition: transform 0.3s ease;
width: 100%;
height: 100%;
object-fit: cover;
cursor: grab;
}
.zoom-controls {
position: absolute;
bottom: 10px;
left: 10px;
}
.zoom-controls button {
margin-right: 5px;
padding: 5px 10px;
background-color: #fff;
border: 1px solid #ccc;
cursor: pointer;
}
.zoom-controls button:hover {
background-color: #f0f0f0;
}
document.addEventListener('DOMContentLoaded', function () {
const zoomableImage = document.querySelector('.zoomable-image');
const zoomContainer = document.querySelector('.zoomFigure__cont');
const zoomInBtn = document.getElementById('zoomInBtn');
const zoomOutBtn = document.getElementById('zoomOutBtn');
let scale = 1; // 初期ズームレベル
const zoomLevels = [1, 1.5, 3]; // ズームレベルの設定
let currentZoomLevel = 0; // 初期ズームレベル
let isDragging = false;
let startX, startY, moveX, moveY;
// ズームイン
zoomInBtn.addEventListener('click', function () {
if (currentZoomLevel < zoomLevels.length - 1) {
currentZoomLevel++;
scale = zoomLevels[currentZoomLevel];
zoomableImage.style.transform = `scale(${scale})`;
zoomableImage.style.transformOrigin = 'center center'; // 中央をズーム基準に
}
});
// ズームアウト
zoomOutBtn.addEventListener('click', function () {
if (currentZoomLevel > 0) {
currentZoomLevel--;
scale = zoomLevels[currentZoomLevel];
zoomableImage.style.transform = `scale(${scale})`;
zoomableImage.style.left = '0px'; // 元の位置にリセット
zoomableImage.style.top = '0px'; // 元の位置にリセット
}
});
// 画像のドラッグ動作を無効化(デフォルトの挙動を防止)
zoomableImage.addEventListener('dragstart', function (e) {
e.preventDefault();
});
// ドラッグ開始時
zoomableImage.addEventListener('mousedown', function (e) {
if (scale > 1) { // ズームインしているときだけドラッグ可能
isDragging = true;
startX = e.clientX - zoomableImage.offsetLeft;
startY = e.clientY - zoomableImage.offsetTop;
zoomableImage.style.cursor = 'grabbing';
e.preventDefault(); // デフォルトの挙動を無効化
}
});
// ドラッグ終了時
zoomableImage.addEventListener('mouseup', function () {
isDragging = false;
zoomableImage.style.cursor = 'grab';
});
// ドラッグ終了時(マウスが画像外に出た時)
zoomableImage.addEventListener('mouseleave', function () {
isDragging = false;
zoomableImage.style.cursor = 'grab';
});
// ドラッグ中の処理
zoomableImage.addEventListener('mousemove', function (e) {
if (!isDragging) return; // ドラッグ中でない場合は処理しない
e.preventDefault();
moveX = e.clientX - startX;
moveY = e.clientY - startY;
// コンテナ内でのドラッグ範囲制限
const maxMoveX = (zoomableImage.offsetWidth * scale - zoomContainer.offsetWidth) / 2;
const maxMoveY = (zoomableImage.offsetHeight * scale - zoomContainer.offsetHeight) / 2;
// 左右の範囲制限
if (moveX > maxMoveX) {
moveX = maxMoveX;
} else if (moveX < -maxMoveX) {
moveX = -maxMoveX;
}
// 上下の範囲制限
if (moveY > maxMoveY) {
moveY = maxMoveY;
} else if (moveY < -maxMoveY) {
moveY = -maxMoveY;
}
zoomableImage.style.left = `${moveX}px`;
zoomableImage.style.top = `${moveY}px`;
});
});

コメントを残す