前言
过了这么久,想起自己还有个博客,更点内容吧!
来,上需求!
最近在做个前端界面,要求在一行中展示一些图片,展示的图片数量随着窗口宽度大小进行变化,除此之外还有以下要求:
- 图片要均匀分布;
- 所有图片要完整的填充一整行;
- 图片的大小随着窗口宽度变化自适应调整。
不说了,不说了,上个最终实现效果图。
实现
基本思路
最开始是打算主要依靠 CSS 的布局来实现,几乎把自己了解的布局方式都想了一遍了,最后默默的给自己找了个借口:刚开始学,不要为难自己!不要为难自己!
最终思路:
- 每张图片设定一个最小宽度;
- 当JS监测到窗口宽度变化后获取窗口宽度;
- 计算在当前窗口宽度,使用最小宽度图片的情况下一行中可以容纳的最多图片数量;
- 计算出一行中剩余的空间,然后平均分配给所有图片,得到最终的图片宽度;
- 最后通过 CSS 调整图片大小。
代码实现
测试环境:vite + vue3 + ts + sass
<!--* @Author : KK* @Date : 2022-02-19 12:30:41* @LastEditTime : 2022-02-19 13:58:02
--><script setup lang="ts">
import { reactive, onMounted, onUnmounted } from 'vue'
// 计算中心 content 的可视宽度 viewpoint-width,content 占据一行的85%宽度
const vw = () => document.body.clientWidth * 0.85;
const minBoxCnt = 3; // 最少可显示的盒子数量
const maxBoxCnt = 8; // 最多可显示的盒子数量
const boxInfo = reactive({w: 160, // 盒子的宽度mw: 160, // 盒子的最小宽度ratio: 1.45,// 高宽比gap: 20, // 盒子间的 gap 大小cnt: 3, // 可显示的盒子数量
})// 计算中心区域可以容纳的盒子数量并设定盒子的宽度
const cal_box_cnt = () => {let c = Math.floor(vw() / boxInfo.mw);c = Math.min(c, maxBoxCnt);const cal_lave_space = (c: number) => {return vw() - boxInfo.mw * c - boxInfo.gap * (c - 1);}let lave_space = 0;let width = 0;if ((lave_space = cal_lave_space(c)) > 0) {width = boxInfo.mw + lave_space / c;} else {c--;width = boxInfo.mw + cal_lave_space(c) / c;}// console.log(lave_space, c, vw());boxInfo.w = width;if (c < minBoxCnt) {boxInfo.w = boxInfo.mw;}// console.log(boxInfo.w);return Math.max(c, minBoxCnt);
}boxInfo.cnt = cal_box_cnt()
onMounted(() => window.onresize = () => boxInfo.cnt = cal_box_cnt());
onUnmounted(() => window.onresize = null);
</script><template><div class="outer"><div class="inner" v-for="item in boxInfo.cnt"><img src="./assets/bg.jpg" alt="background" /></div></div>
</template><style lang="scss">
body {background-color: darkcyan;
}
#app {width: 85%;min-width: 520px; // 160 * 3 + 2 * 20margin: 100px auto;background-color: #fff;
}.outer {display: flex;flex-wrap: nowrap;transition: all 0.5s;.inner {img {width: 100%;height: 100%;}}.inner:nth-child(n) {width: v-bind('boxInfo.w + "px"');height: v-bind('boxInfo.w * boxInfo.ratio + "px"');margin-right: v-bind('boxInfo.gap + "px"');}.inner:last-child {margin-right: 0;}
}
</style>
本文章转自:https://blog.nas-kk.top/?p=449