Живой пример: https://jsfiddle.net/b8vLg0ny/
Можно использовать функции CSS scale
и translate
для увеличения элемента.
Возьмем этот пример из 4 ящиков в сетке 2x2.
HTML:
<div id="container">
<div id="zoom-container">
<div class="box red">A</div>
<div class="box blue">B</div>
<div class="box green">C</div>
<div class="box black">D</div>
</div>
</div>
CSS:
* { margin: 0; }
body, html { height: 100%; }
#container {
height: 100%;
width: 50%;
margin: 0 auto;
}
#zoom-container {
height: 100%;
width: 100%;
transition: all 0.2s ease-in-out;
}
.box {
float: left;
width: 50%;
height: 50%;
color: white;
text-align: center;
display: block;
}
.red { background: red; }
.blue { background: blue; }
.green { background: green; }
.black { background: black; }
JavaScript:
window.zoomedIn = false;
$(".box").click(function(event) {
var el = this;
var zoomContainer = $("#zoom-container");
if (window.zoomedIn) {
console.log("resetting zoom");
zoomContainer.css("transform", "");
$("#container").css("overflow", "auto");
window.zoomedIn = false;
} else {
console.log("applying zoom");
var top = el.offsetTop;
var left = el.offsetLeft - 0.25*zoomContainer[0].clientWidth;
var translateY = 0.5*zoomContainer[0].clientHeight - top;
var translateX = 0.5*zoomContainer[0].clientWidth - left;
$("#container").css("overflow", "scroll");
zoomContainer.css("transform", "translate(" + 2 * translateX + "px, " + 2 * translateY + "px) scale(2)");
window.zoomedIn = true;
}
});
Управляя значением translateX
и translateY
, вы можете изменить способ масштабирования.
Начальный визуализированный вид выглядит примерно так:
Нажав на поле A, вы увеличите масштаб соответствующим образом:
(Обратите внимание, что щелчок D в конце просто показывает сброс путем уменьшения масштаба.)
Проблема: масштабирование до поля D масштабирует контейнер масштабирования таким образом, что прокрутка вверх и влево не работает, поскольку содержимое переполняется. То же самое происходит при приближении к полям B (обрезается левая половина) и C (обрезается верхняя половина). Только с A содержимое не выходит за пределы контейнера.
В подобных ситуациях, связанных с масштабированием (см. CSS3 Transform Scale and Container with Overflow), одним из возможных решений является указание transform-origin: top left
(или 0 0
). Из-за того, как работает масштабирование относительно верхнего левого угла, функция прокрутки остается. Однако здесь это не работает, потому что это означает, что вы больше не перемещаете содержимое, чтобы сфокусироваться на поле, по которому щелкнули (A, B, C или D).
Другое возможное решение — добавить margin-left
и margin-top
в контейнер масштабирования, что добавит достаточно места, чтобы компенсировать переполненное содержимое. Но опять же: значения перевода больше не совпадают.
Итак: есть ли способ оба увеличить данный элемент, и переполниться прокруткой, чтобы содержимое не обрезалось?
Обновление: есть грубое почти решение путем анимации scrollTop
и scrollLeft
, похожее на https://stackoverflow.com/a/31406704/528044 (см. пример jsfiddle), но это не совсем правильное решение, потому что сначала оно приближается к левому верхнему углу, а не к намеченной цели. Я начинаю подозревать, что на самом деле это невозможно, потому что это, вероятно, равносильно тому, чтобы просить, чтобы scrollLeft
было отрицательным.