Ahm*_*otb 23 html javascript css
我正在尝试对以可滚动容器div为中心的div进行缩放转换.
我用来反映转换后的新div大小的技巧是使用包装器并为其设置新的宽度/高度,以便父级可以正确显示滚动条.
.container {
position: relative;
border: 3px solid red;
width: 600px; height: 400px;
background-color: blue;
overflow-x: scroll; overflow-y: scroll;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.wrapper {
order: 1;
background-color: yellow;
}
.content-outer {
width: 300px;
height: 200px;
transform-origin: 50% 50%;
/*transform-origin: 0 0;*/
}
.content-outer.animatted {
animation: scaleAnimation 1s ease-in forwards;
}
.content-outer.animatted2 {
animation: scaleAnimation2 1s ease-in forwards;
}
.content-inner {
width: 300px;
height: 200px;
background: linear-gradient(to right, red, white);
}
Run Code Online (Sandbox Code Playgroud)
如果转换原点是0,0 div在没有动画跳跃的情况下居中,但滚动条不正确.如果原点位于中间,则div位置和滚动条都会被错过
我尝试了两种方法来进行居中,使用flexbox(http://jsfiddle.net/r3jqyjLz/1/)和使用负边距(http://jsfiddle.net/roLf5tph/1/).
有一个更好的方法吗 ?
这就是你追求的吗?
我使用CSS过渡来缩放动画.
#centered {
background-image: linear-gradient(to bottom,yellow,red);
height: 200px;
transform: scale(1);
transition: transform 1s ease-out;
width: 200px;
}
#scrollable {
align-items: center;
border: 1px solid red;
display: flex;
height: 300px;
justify-content: center;
overflow: auto;
width: 300px;
}
Run Code Online (Sandbox Code Playgroud)
我假设您所遇到的部分问题可归纳为:
div
,您希望将其作为一个组进行扩展.(如果它是单个元素,使用矩阵就可以轻松实现).div
缩放超出容器的边界时,如果不控制宽度/高度,则不会获得滚动条.div
保持居中,同时,滚动条应该反映正确的位置.有了这个,有两个(实际上是三个)简单的选项.
在问题中使用相同的标记,div
当比例因子低于1时,您可以保持居中.对于高于1的比例因子,您可以将其更改为左上角.的overflow: auto
,因为在容器上会照顾滚动的自身div
来缩放(通过变换)被包裹的另一个内div
.你真的不需要Javascript.
这解决了您的问题1和2.
小提琴1:http://jsfiddle.net/abhitalks/c0okhznc/
小片1:
* { box-sizing: border-box; }
#container {
position: relative;
border: 1px solid red; background-color: blue;
width: 400px; height: 300px;
overflow: auto;
}
.wrapper {
position: absolute;
background-color: transparent; border: 2px solid black;
width: 300px; height: 200px;
top: 50%; left: 50%;
transform-origin: top left;
transform: translate(-50%, -50%);
transition: all 1s;
}
.box {
width: 300px; height: 200px;
background: linear-gradient(to right, red, white);
border: 2px solid yellow;
}
.inner { width:50px; height: 50px; background-color: green; }
#s0:checked ~ div#container .wrapper { transform: scale(0.5) translate(-50%, -50%); }
#s1:checked ~ div#container .wrapper { transform: scale(0.75) translate(-50%, -50%); }
#s2:checked ~ div#container .wrapper { transform: scale(1) translate(-50%, -50%); }
#s3:checked ~ div#container .wrapper { top: 0%; left: 0%; transform-origin: top left; transform: scale(1.5) translate(0%, 0%); }
#s4:checked ~ div#container .wrapper { top: 0%; left: 0%; transform-origin: top left; transform: scale(2) ; }
#s5:checked ~ div#container .wrapper { top: 0%; left: 0%; transform-origin: top left; transform: scale(3) ; }
Run Code Online (Sandbox Code Playgroud)
<input id="s0" name="scale" data-scale="0.5" type="radio" />Scale 0.5
<input id="s1" name="scale" data-scale="0.75" type="radio" />Scale 0.75
<input id="s2" name="scale" data-scale="1" type="radio" checked />Scale 1
<input id="s3" name="scale" data-scale="1.5" type="radio" />Scale 1.5
<input id="s4" name="scale" data-scale="2" type="radio" />Scale 2
<input id="s5" name="scale" data-scale="3" type="radio" />Scale 3
<hr>
<div id="container">
<div id="wrapper" class="wrapper">
<div id="box" class="box">
<div class="inner"></div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
但这会产生另一个问题.该overflow:auto
会导致跳/闪烁时的div
缩放超出容器.这可以通过使其overflow:scroll
始终显示滚动条(您已经这样做的方式)来轻松解决.虽然,它的工作方式类似于Firefox中的魅力,Chrome在这里踌躇不前并且不会更新滚动条位置.这里的技巧是使用JavaScript来强制回流通过改变overflow
来auto
一次你的缩放完成.所以你需要稍微延迟一下.
小提琴2:http://jsfiddle.net/abhitalks/u7sfef0b/
摘录2:
$("input").on("click", function() {
var scroll = 'scroll',
scale = +($(this).data("scale"));
if (scale > 1) { scroll = 'auto'; }
setTimeout(fixScroll, 300, scroll);
});
function fixScroll(scroll) { $("#container").css({ overflow: scroll }); }
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; }
#container {
position: relative;
border: 1px solid red; background-color: blue;
width: 400px; height: 300px;
overflow: scroll;
}
.wrapper {
position: absolute;
background-color: transparent; border: 2px solid black;
width: 300px; height: 200px;
top: 50%; left: 50%;
transform-origin: top left;
transform: translate(-50%, -50%);
transition: all 1s;
}
.box {
width: 300px; height: 200px;
background: linear-gradient(to right, red, white);
border: 2px solid yellow;
}
.inner { width:50px; height: 50px; background-color: green; }
#s0:checked ~ div#container .wrapper { transform: scale(0.5) translate(-50%, -50%); }
#s1:checked ~ div#container .wrapper { transform: scale(0.75) translate(-50%, -50%); }
#s2:checked ~ div#container .wrapper { transform: scale(1) translate(-50%, -50%); }
#s3:checked ~ div#container .wrapper { top: 0%; left: 0%;transform-origin: top left; transform: scale(1.5) translate(0%, 0%); }
#s4:checked ~ div#container .wrapper { top: 0%; left: 0%;transform-origin: top left; transform: scale(2) ; }
#s5:checked ~ div#container .wrapper { top: 0%; left: 0%;transform-origin: top left; transform: scale(3) ; }
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="s0" name="scale" data-scale="0.5" type="radio" />Scale 0.5
<input id="s1" name="scale" data-scale="0.75" type="radio" />Scale 0.75
<input id="s2" name="scale" data-scale="1" type="radio" checked />Scale 1
<input id="s3" name="scale" data-scale="1.5" type="radio" />Scale 1.5
<input id="s4" name="scale" data-scale="2" type="radio" />Scale 2
<input id="s5" name="scale" data-scale="3" type="radio" />Scale 3
<hr>
<div id="container">
<div id="wrapper" class="wrapper">
<div id="box" class="box">
<div class="inner"></div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
为了解决保持div
居中并同时保持正确滚动条位置的问题3 ,您必须回退Javascript.
原理保持不变,对于大于1的比例因子,您需要重置左上角和translate
位置.您还需要重新调整缩放的宽度/高度,然后将其重新分配给包装器div
.然后在容器上设置scrollTop
and scrollLeft
就像获取包装器div
和容器的区别一样简单div
.
这解决了您的问题1,2和3.
小提琴3:http://jsfiddle.net/abhitalks/rheo6o7p/1/
代码段3:
var $container = $("#container"),
$wrap = $("#wrapper"),
$elem = $("#box"),
originalWidth = 300, originalHeight = 200;
$("input").on("click", function() {
var factor = +(this.value);
scaler(factor);
});
function scaler(factor) {
var newWidth = originalWidth * factor,
newHeight = originalHeight * factor;
$wrap.width(newWidth); $wrap.height(newHeight);
if (factor > 1) {
$wrap.css({ left: 0, top: 0, transform: 'translate(0,0)' });
$elem.css({ transform: 'scale(' + factor + ')' });
setTimeout(setScroll, 400);
} else {
$elem.css({ transform: 'scale(' + factor + ') ' });
$wrap.css({ left: '50%', top: '50%', transform: 'translate(-50%, -50%)' });
}
}
function setScroll() {
var horizontal, vertical;
horizontal = ($wrap.width() - $container.width()) / 2;
vertical = ($wrap.height() - $container.height()) / 2;
$container.stop().animate({scrollTop: vertical, scrollLeft: horizontal}, 500);
}
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; }
#container {
position: relative;
border: 1px solid red; background-color: blue;
width: 400px; height: 300px;
overflow: scroll;
}
.wrapper {
position: absolute;
background-color: transparent; border: 2px solid black;
width: 300px; height: 200px;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s;
}
.box {
width: 300px; height: 200px;
background: linear-gradient(to right, red, white);
border: 2px solid yellow;
transform-origin: top left;
transition: all 0.5s;
}
.inner { width:50px; height: 50px; background-color: green; }
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<label for="slider1">Scale: </label>
<input id="slider1" type="range" min="0.5" max="3" value="1" step="0.25" list="datalist" onchange="scaleValue.value=value" />
<output for="slider1" id="scaleValue">1</output>
<datalist id="datalist">
<option>0.5</option>
<option>0.75</option>
<option>1</option>
<option>1.5</option>
<option>2</option>
<option>3</option>
</datalist>
<hr>
<div id="container">
<div id="wrapper" class="wrapper">
<div id="box" class="box">
<div class="inner"></div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
所有脚本都使用IE-11,GC-43和FF-38进行了测试
.
归档时间: |
|
查看次数: |
3183 次 |
最近记录: |