我正在构建一个网格用户界面,用户应该可以点击单元格来缩放它们。
所需行为:
*左:不想要的行为(单元格O
的部分内容已消失)。
正确:期望的行为
我的方法:
显然,我可以同时transform: scale() translate()
达到预期的效果。
您可以使用单元格N
(translateY(22px)
)来查看此内容。
问题:
这种方法不能很好地扩展到9个单元格(更不用说90,这是我的实际用例)。
容器必须为overflow: hidden
。滚动等不是一种选择。
我的问题:
这感觉就像是一个非常粗暴的尝试,已经以编程方式解决某人必须已经解决的问题。
有没有更好的方法来构建这样的用户界面?(我对插件或其他方法持开放态度。)
如果没有,在jQuery中编写脚本的好方法是什么?
$(function() {
$(".cell").click(function() {
$(this).toggleClass("zoom-in");
});
});
.grid {
width: 300px;
height: 300px;
background: gray;
overflow: hidden;
}
.cell {
background: tomato;
width: 30%;
height: 30%;
margin: 5px;
float: left;
text-align: center;
z-index: 999;
transition: all 0.2s ease-in-out;
}
.zoom-in {
transform: scale(2);
transition: all 0.2s ease-in-out;
}
#nord {
background-color: white;
}
#nord.zoom-in {
transform: scale(2) translateY(22px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div> Click white and red cells to scale. Click again to revert.</div>
<div class="grid">
<div class="cell">NW</div>
<div id="nord" class="cell">N</div>
<div class="cell">NO</div>
<div class="cell">W</div>
<div class="cell">C</div>
<div class="cell">O</div>
<div class="cell">SW</div>
<div class="cell">S</div>
<div class="cell">SO</div>
</div>
答案 0 :(得分:1)
我创造了类似于概念证明的东西。我认为这可能有助于指出你正确的方向。在这里查看演示:https://codepen.io/RTakes/pen/aWejOy
这也是我在缩放时处理居中的方式。它根据当前位置计算要设置动画的位置。
function computeCenterPosition(element, sizeFactor = 0) {
const screenCenter = {
x: window.innerWidth / 2,
y: window.innerHeight / 2
};
const elCenter = {
x: (element.offsetWidth / 2) + element.offsetLeft,
y: (element.offsetHeight / 2) + element.offsetTop
};
return {
x: (elCenter.x - screenCenter.x) * -1,
y: (elCenter.y - screenCenter.y) * -1
}
}
答案 1 :(得分:0)
我已经设置了一个函数来评估单元格是否接近网格的边界(任何边框)。如果是这种情况,请在单元格上注入样式,设置变换样式属性,使其在缩放时沿边框的相反方向移动。
这是一种快速而肮脏的方法,显然还有改进的余地。
$(function() {
$(".cell").click(function() {
$(this).toggleClass("zoom-in");
});
});
document.addEventListener('DOMContentLoaded', setEvent, false);
function setEvent () {
var elements = document.getElementsByClassName('cell');
var grid = elements[0].parentElement;
var gridWidth = grid.clientWidth;
var gridHeight = grid.clientHeight;
var maxGrid = {
right: gridWidth,
bottom: gridHeight
}
for (var n = 0; n < elements.length; n++) {
evaluate (elements[n], maxGrid);
}
}
function evaluate (element, maxGrid) {
var transOrigin = "";
var left = element.offsetLeft;
if (left < element.clientWidth) {
transOrigin += 'left ';
}
if (left + element.clientWidth > maxGrid.right - element.clientWidth) {
transOrigin += 'right ';
}
var top = element.offsetTop;
if (top < element.clientHeight) {
transOrigin += 'top';
}
if (top + element.clientHeight > maxGrid.bottom - element.clientHeight) {
transOrigin += 'bottom';
}
element.style.transformOrigin = transOrigin;
}
&#13;
.grid {
width: 300px;
height: 300px;
background: gray;
overflow: hidden;
position: relative; /* important to have this */
}
.cell {
background: tomato;
width: 30%;
height: 30%;
margin: 5px;
float: left;
text-align: center;
z-index: 999;
transition: all 0.2s ease-in-out;
}
.zoom-in {
transform: scale(2);
transition: all 0.2s ease-in-out;
}
#nord {
background-color: white;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div> Click white and red cells to scale. Click again to revert.</div>
<div class="grid">
<div class="cell">NW</div>
<div id="nord" class="cell">N</div>
<div class="cell">NO</div>
<div class="cell">W</div>
<div class="cell">C</div>
<div class="cell">O</div>
<div class="cell">SW</div>
<div class="cell">S</div>
<div class="cell">SO</div>
</div>
&#13;