持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
前言
当我实现可视化系统的预览功能时,我想要用户配置的舞台不管是1920*1080,还是1440*900等不同的尺寸,都能自适应当前用户预览的设备尺寸显示。如何优雅的实现呢?
换句话说就是保持用户设定的舞台长宽比例不变的情况下, 在预览时自适应当前设备来展示。
需要满足两个基本需求:
- 最大限度利用当前设备的显示(缩放到目标尺寸)
- 保证展示区域在屏幕中心
具体实现的目标效果就是下面这样:
1、舞台尺寸:820 * 900
2、舞台尺寸: 1920 * 900
实现思路
想要最大限度利用当前屏幕,并且能够完全显示舞台上的内容,那么就需要找到一个合适的比例,对主舞台进行缩放。
获取放缩比例
父容器宽高: parentWidth, parentHeight 舞台实际宽高: width, height
width / parentWidth, height / parentHeight, 二者取较大值,我们就能得到合适的缩放比例。
this.scale = Math.max(width / parentWidth, height / parentHeight)
因为取较大值,才能保证舞台的长宽中较大的那个正好撑满屏幕。 (把容器想象成正方形就很好理解了)
实现平移到屏幕中央
对舞台放缩之后,正常来讲舞台仍然处于外层容器的正中心,但是这样其实并不是我们想要的效果。直接看图:
因为原来的舞台尺寸假如是 2000 * 1000, 现在缩放到 0.5 倍, 现在的舞台确实缩放到了原舞台的中心, 但是并没有在我们屏幕显示的中心, 我们需要使它向上向左偏移黄色箭头的距离。
这个距离如何计算呢?
- 相比原来,缩小到了
scale倍, 就是缩小了(1 - scale)倍, 那么左右上下各个方向空出来的大小就是(1 - scale) / 2倍, 注意这里的倍数是相对舞台原尺寸的。 所以偏移量应为:(1 - scale) / 2 * width, 转换成百分比(这里的百分比需要根据目前的尺寸来计算哦~),((1 - scale) / 2 * width) / (width * scale) * 100=>(1 / scale - 1) / 2 * 100。 因为向左移动应该是负值, 所以再取一下负。 最后得到:
transform: `scale(${this.scale}) translate(${((1 - 1 / this.scale) / 2) * 100}%, ${
((1 - 1 / this.scale) / 2) * 100
}%)`,
niceeee~, 我们已经成功将舞台移到父容器的左上位置了。 下面一步,就可以转换成 div在父容器居中显示 的问题了。
那这问题还不是手拿把掐啊!
方案一: flex大法!
父容器设置:
.screen-content__wrap {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
想必黄色区域这块你应该猜到是什么了吧,就是我们原舞台区域被缩放空出来的那部分,所以我们居中的是原舞台的区域大小。
这个方案不太合适。
方案二: position 50% + 偏移 -50%
.main-screen {
position: absolute;
top: 50%;
left: 50%;
}
然后我们给之前计算的偏移量 - 50%
transform: `scale(${this.scale}) translate(${((1 - 1 / this.scale) / 2) * 100 - 50}%, ${
((1 - 1 / this.scale) / 2) * 100 - 50
}%)`,
这样就实现了 缩放并居中 的需求了!
另一个思路
基于flex居中,其实还有一个思路, 不调整主舞台的偏移,直接flex居中,这时候肯定会以原始舞台区域居中显示, 这时候如何消除左上的偏移量呢? 我觉得可以通过父容器的 -margin 来试试。
但是发现其实flex布局会以当前舞台区域居中,直接打到了我们的理想效果!
意外收获,这样代码逻辑又简洁了不少~
总结
通过 父子容器的比值 确定合适的缩放比例, 然后通过translate偏移实现舞台居中。
通过 Flex 实现舞台居中算是写文章复盘的意外之喜了~ 感谢掘金哈哈哈
更文不易,觉得对你有帮助可以点个赞支持一下作者!感恩~