Skip to content

Commit 4af71ed

Browse files
committed
feat: 新增waterfall.js
1 parent 02d0e4a commit 4af71ed

File tree

9 files changed

+253
-0
lines changed

9 files changed

+253
-0
lines changed

vue/Access/Access.vue

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<div>
3+
4+
</div>
5+
</template>
6+
7+
<script setup lang="ts">
8+
9+
</script>
10+
11+
<style scoped>
12+
13+
</style>

vue/Access/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import useAccess, { setAccessState } from "./useAccess"
2+
import Access from "./Access.vue"
3+
export {
4+
Access,
5+
setAccessState,
6+
useAccess
7+
}

vue/Access/useAccess.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { toRefs, reactive } from "vue";
2+
import { toBoolean } from "./utils";
3+
type AccessInit = () => Promise<Record<string, boolean | (() => boolean)>>;
4+
5+
let accessObject: any = null;
6+
7+
export async function setAccessState(fn: AccessInit) {
8+
const data = await fn();
9+
for (const key in data) {
10+
if (typeof data[key] === "function") {
11+
data[key] = toBoolean((data[key] as () => boolean)());
12+
} else {
13+
data[key] = toBoolean(data[key]);
14+
}
15+
}
16+
accessObject = data;
17+
}
18+
19+
export default async function useAccess() {
20+
accessObject = reactive(accessObject);
21+
return accessObject;
22+
}

vue/Access/utils.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const toBoolean = (value: any) => {
2+
if (
3+
value === undefined ||
4+
value === null ||
5+
value === "" ||
6+
value === 0 ||
7+
value === false ||
8+
value === "false"
9+
) {
10+
return false;
11+
} else {
12+
return true;
13+
}
14+
};

waterfall/REDAME.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# waterfall
2+
一个瀑布流js库,可以很方便的使用该库实现常规瀑布流

waterfall/core/help.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const debounce = (fn, delay) => {
2+
let timer = null;
3+
return function (...args) {
4+
if (timer) {
5+
clearTimeout(timer);
6+
}
7+
timer = setTimeout(() => {
8+
fn.apply(this, args);
9+
}, delay);
10+
};
11+
};

waterfall/core/waterfall.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { debounce } from "./help.js";
2+
/**
3+
* 瀑布流
4+
* @param {Object} options
5+
* @param {HTMLElement} options.$el 父容器
6+
* @param {Number} options.count 列数
7+
* @param {Number} options.gap 间距
8+
* @param {Number} options.complete 列的宽度
9+
*/
10+
export default class Waterfall {
11+
constructor(options) {
12+
this.$el = null; // 父容器
13+
this.count = 4; // 列数
14+
this.gap = 10; // 间距
15+
Object.assign(this, options);
16+
this.width = 0; // 列的宽度
17+
this.items = []; // 子元素集合
18+
this.H = []; // 存储每列的高度方便计算
19+
this.flag = null; // 虚拟节点集合
20+
this.init();
21+
}
22+
#resize() {
23+
debounce(() => {
24+
this.rerender();
25+
}, 300).call(this);
26+
}
27+
28+
init() {
29+
this.items = Array.from(this.$el.children);
30+
this.reset();
31+
this.render();
32+
window.addEventListener("resize", this.#resize.bind(this));
33+
}
34+
35+
reset() {
36+
this.flag = document.createDocumentFragment();
37+
const containerWidth = this.$el.clientWidth - (this.count - 1) * this.gap;
38+
this.width = containerWidth / this.count;
39+
this.H = new Array(this.count).fill(0);
40+
this.$el.innerHTML = "";
41+
}
42+
43+
rerender() {
44+
this.items = Array.from(this.$el.children);
45+
this.reset();
46+
this.render();
47+
}
48+
49+
render() {
50+
const { width, items, flag, H, gap } = this;
51+
items.forEach((item) => {
52+
item.style.width = width + "px";
53+
item.style.position = "absolute";
54+
let img = item.querySelector("img");
55+
if (img.complete) {
56+
let tag = H.indexOf(Math.min(...H));
57+
item.style.left = tag * (width + gap) + "px";
58+
item.style.top = H[tag] + "px";
59+
H[tag] += (img.height * width) / img.width + gap;
60+
flag.appendChild(item);
61+
} else {
62+
img.addEventListener("load", () => {
63+
let tag = H.indexOf(Math.min(...H));
64+
item.style.left = tag * (width + gap) + "px";
65+
item.style.top = H[tag] + "px";
66+
H[tag] += (img.height * width) / img.width + gap;
67+
flag.appendChild(item);
68+
this.$el.append(flag);
69+
});
70+
}
71+
});
72+
this.$el.append(flag);
73+
}
74+
}

waterfall/example/index.html

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>瀑布流</title>
8+
<style>
9+
html{
10+
width: 100%;
11+
height: 100%;
12+
}
13+
body{
14+
height: 100%;
15+
padding: 0;
16+
margin: 0;
17+
}
18+
.list {
19+
width: 100%;
20+
position: relative;
21+
list-style: none;
22+
height: 1000px;
23+
overflow-y: scroll;
24+
padding: 0;
25+
margin: 0;
26+
}
27+
.list-item{
28+
overflow: hidden;
29+
}
30+
.list-item img {
31+
width: 100%;
32+
display: block;
33+
}
34+
</style>
35+
</head>
36+
<body>
37+
<ul class="list">
38+
<li class="list-item">
39+
<img
40+
src="https://img2.baidu.com/it/u=3334115308,1054927257&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
41+
alt=""
42+
/>
43+
</li>
44+
<li class="list-item">
45+
<img
46+
src="https://img2.baidu.com/it/u=2988589017,2923917558&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
47+
alt=""
48+
/>
49+
</li>
50+
<li class="list-item">
51+
<img
52+
src="https://img2.baidu.com/it/u=2243573419,589412055&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
53+
alt=""
54+
/>
55+
</li>
56+
<li class="list-item">
57+
<img
58+
src="https://img2.baidu.com/it/u=3902309251,2849519907&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889"
59+
alt=""
60+
/>
61+
</li>
62+
<li class="list-item">
63+
<img
64+
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201702%2F05%2F20170205213628_dj3ic.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1682648912&t=185a3d75a4ae0c992dbfd855fd595980"
65+
alt=""
66+
/>
67+
</li>
68+
<li class="list-item">
69+
<img
70+
src="https://img2.baidu.com/it/u=3334115308,1054927257&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
71+
alt=""
72+
/>
73+
</li>
74+
<li class="list-item">
75+
<img
76+
src="https://img2.baidu.com/it/u=2988589017,2923917558&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
77+
alt=""
78+
/>
79+
</li>
80+
<li class="list-item">
81+
<img
82+
src="https://img2.baidu.com/it/u=2243573419,589412055&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
83+
alt=""
84+
/>
85+
</li>
86+
<li class="list-item">
87+
<img
88+
src="https://img2.baidu.com/it/u=3902309251,2849519907&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889"
89+
alt=""
90+
/>
91+
</li>
92+
<li class="list-item">
93+
<img
94+
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201702%2F05%2F20170205213628_dj3ic.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1682648912&t=185a3d75a4ae0c992dbfd855fd595980"
95+
alt=""
96+
/>
97+
</li>
98+
</ul>
99+
<script src="./waterfall.js" type="module"></script>
100+
<script src="./index.js" type="module"></script>
101+
</body>
102+
</html>

waterfall/example/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Waterfall from "../core/waterfall.js";
2+
3+
const w = new Waterfall({
4+
$el: document.querySelector(".list"),
5+
count: 4,
6+
gap: 10
7+
});
8+
w.init();

0 commit comments

Comments
 (0)