gpt4 book ai didi

javascript - 使用 CSS transform scale() 在不裁剪的情况下放大元素,保持滚动

转载 作者:技术小花猫 更新时间:2023-10-29 12:21:09 26 4
gpt4 key购买 nike

实例:https://jsfiddle.net/b8vLg0ny/

可以使用 CSS scaletranslate 函数来放大元素。

以 2x2 网格中的 4 个框为例。

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;
}
});

通过控制 translateXtranslateY 的值,您可以更改缩放的工作方式。

初始渲染 View 看起来像这样:

initial rendered view

单击 A 框将适本地放大您:

zooming to A and then zooming out

(请注意,最后单击 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,这样可以增加足够的空间来弥补溢出的内容。但同样:翻译值不再排列。

那么:有没有一种方法可以同时放大给定元素,滚动溢出,这样内容就不会被裁剪?

更新:通过为scrollTopscrollLeft 设置动画,有一个大致的解决方案,类似于https://stackoverflow.com/a/31406704/528044 (参见 the jsfiddle example ),但这不是一个合适的解决方案,因为它首先缩放到左上角,而不是预期的目标。我开始怀疑这实际上是不可能的,因为这可能等同于要求 scrollLeft 为负数。

最佳答案

为什么不只是将 TransformOrigin 重新定位到 0 0 并使用适当的 scrollTop/scrollLeft 之后动画?

如果您不需要动画,TransformOrigin 可以始终保持 0 0 并且仅滚动用于显示框。

为了使动画不那么跳动,只对 transform 属性使用 transition,否则 transform-origin 也会得到动画。我已经用 4x4 元素编辑了示例,但我认为将框完全缩放到 View 中是有意义的,这就是我更改缩放级别的原因。但是如果你保持缩放级别 2 和网格大小 15x15 例如,那么使用这种方法应该计算真正精确的原点以进行变换,然后还应该计算正确的滚动。

无论如何,我不知道您是否觉得这种方法有用。

堆栈片段

var zoomedIn = false;
var zoomContainer = $("#zoom-container");

$(".box").click(function(event) {
var el = this;

if (zoomedIn) {
zoomContainer.css({
transform: "scale(1)",
transformOrigin: "0 0"
});
zoomContainer.parent().scrollTop(0).scrollLeft(0);
zoomedIn = false;
return;
}
zoomedIn = true;
var $el = $(el);
animate($el);
zoomContainer.on('transitionend', function(){
zoomContainer.off('transitionend');
reposition($el);
})
});

var COLS = 4, ROWS = 4,
COLS_STEP = 100 / (COLS - 1), ROWS_STEP = 100 / (ROWS - 1),
ZOOM = 4;


function animate($box) {
var cell = getCell($box);
var col = cell.col * COLS_STEP + '%',
row = cell.row * ROWS_STEP + '%';
zoomContainer.parent().css('overflow', 'hidden');
zoomContainer.css({
transition: 'transform 0.2s ease-in-out',
transform: "scale(" + ZOOM + ")",
transformOrigin: col + " " + row
});
}
function reposition($box) {
zoomContainer.css({
transition: 'none',
transform: "scale(" + ZOOM + ")",
transformOrigin: '0 0'
});
zoomContainer.parent().css('overflow', 'auto');
$box.get(0).scrollIntoView();
}
function getCell ($box) {
var idx = $box.index();
var col = idx % COLS,
row = (idx / ROWS) | 0;
return { col: col, row: row };
}
* { margin: 0; }

body, html { height: 100%; }

#container {
height: 100%;
width: 50%;
margin: 0 auto;
overflow: hidden;
}

#zoom-container {
height: 100%;
width: 100%;
will-change: transform;
}

.box {
float: left;
width: 25%;
height: 25%;
color: white;
text-align: center;
}

.red { background: red; }
.blue { background: blue; }
.green { background: green; }
.black { background: black; }
.l { opacity: .3 }
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<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 class="box red l">E</div>
<div class="box blue l">F</div>
<div class="box green l">G</div>
<div class="box black l">H</div>

<div class="box red">I</div>
<div class="box blue">J</div>
<div class="box green">K</div>
<div class="box black">L</div>

<div class="box red l">M</div>
<div class="box blue l">N</div>
<div class="box green l">O</div>
<div class="box black l">P</div>
</div>
</div>

关于javascript - 使用 CSS transform scale() 在不裁剪的情况下放大元素,保持滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36388485/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com