前言
過了這么久,想起自己還有個博客,更點內容吧!
來,上需求!
最近在做個前端界面,要求在一行中展示一些圖片,展示的圖片數量隨著窗口寬度大小進行變化,除此之外還有以下要求:
- 圖片要均勻分布;
- 所有圖片要完整的填充一整行;
- 圖片的大小隨著窗口寬度變化自適應調整。
不說了,不說了,上個最終實現效果圖。
實現
基本思路
最開始是打算主要依靠 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