在下面的代码段中,我试图获得一个效果,其中显示在可见滚动部分中间的div
处于满刻度scale(1);
,而另一个div的比例当他们接近边缘时,向scale(0);
下降。
我在中间绘制了一个调试框,其中应出现满刻度div。
var viewport = {
x: $("#scroll").scrollLeft(),
width: $("#scroll").width(),
}
$("#scroll").scroll(function() {
viewport.x = $("#scroll").scrollLeft();
recalculateScale();
});
recalculateScale();
function recalculateScale() {
$("#example > div").each(function() {
let middleOfThis = ($(this).position().left + ($(this).width() * 0.5)); // calculate from the middle of each div
let scale = Math.sin(middleOfThis / $("content").width());
$(this).css('transform', 'scale(' + scale + ')');
});
}

content {
position: relative;
display: block;
width: 500px;
height: 100px;
}
content::after {
content: '';
position: absolute;
display: block;
width: 20%;
height: 100%;
left: 50%;
top: 0;
transform: translateX(-50%);
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}
#scroll {
display: block;
width: 100%;
height: 100%;
overflow-x: scroll;
border: 1px solid #000;
}
#example {
display: block;
width: 200%;
height: 100%;
font-size: 0;
overflow: none;
}
#example>div {
display: inline-block;
width: 10%;
height: 100%;
background-color: #f00;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<content>
<div id="scroll">
<section id="example">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</div>
</content>
&#13;
目前,比例从#example
的最左侧到右侧。我知道我需要在评估Math.sin
之前将视口尺寸计算到等式中,我只是不能把它弄得恰到好处。
注意:没有箭头功能,因为我必须以IE11为目标。
答案 0 :(得分:1)
两个问题:
.position().left
在缩放后返回元素的渲染位置,.width()
返回元素的宽度,而不进行缩放帐户。显然,这种不同的测量方式会导致中间点的错误计算。请改为使用.getBoundingClientRect().width
:这将考虑当前的缩放
使用三角函数时,需要确保参数表示以弧度表示的角度。在您的代码中,值的范围是0到1,而正弦值的最大值不是0.5,而是π/ 2。因此,您应该使用π进行乘法以获得所需的结果。
以下是改编的代码:
var viewport = {
x: $("#scroll").scrollLeft(),
width: $("#scroll").width(),
}
$("#scroll").scroll(function() {
viewport.x = $("#scroll").scrollLeft();
recalculateScale();
});
recalculateScale();
function recalculateScale() {
$("#example > div").each(function() {
// 1. Use different way to read the width: this will give the rendered width
// after scaling, just like the left position will be the actually rendered
// position after scaling:
let middleOfThis = $(this).position().left
+ this.getBoundingClientRect().width * 0.5;
// 2. Convert fraction to a number of radians:
let scale = Math.sin(middleOfThis / $("content").width() * Math.PI);
$(this).css('transform', 'scale(' + scale + ')');
});
}
content {
position: relative;
display: block;
width: 500px;
height: 100px;
}
content::after {
content: '';
position: absolute;
display: block;
width: 20%;
height: 100%;
left: 50%;
top: 0;
transform: translateX(-50%);
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}
#scroll {
display: block;
width: 100%;
height: 100%;
overflow-x: scroll;
border: 1px solid #000;
}
#example {
display: block;
width: 200%;
height: 100%;
font-size: 0;
overflow: none;
}
#example>div {
display: inline-block;
width: 10%;
height: 100%;
background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<content>
<div id="scroll">
<section id="example">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</div>
</content>
注意:由于浮点精度的限制,中点的计算可能会以很小的分数滑落。这将是如此微小,以至于它不应该对实际像素距离产生影响,但预先计算元素的中心并不会有害,因此您总是使用相同的值。