Skip to content

Commit

Permalink
chore: 独立了卡片定位时间和飞入时间,添加了定位完成后的事件
Browse files Browse the repository at this point in the history
  • Loading branch information
heikaimu committed Mar 1, 2024
1 parent 609c47b commit 8101681
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 51 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,23 @@ data: {
| `breakpoints` | `Object` | {<br>1200:{rowPerView:3},<br>800:{rowPerView:2},<br>500:{rowPerView:1}<br>} | 类似css的@media, 定义不同容器宽度下每行卡片个数,主要用于对移动端的适配 |
| `gutter` | `Number` | `10` | 卡片之间的间隙 |
| `hasAroundGutter` | `Boolean` | `true` | 容器四周是否有 `gutter` 边距 |
| `posDuration` | `Number` | `300` | 卡片移动到正确位置的动画时间 |
| `animationPrefix` | `String` | `animate__animated` | 详情见下文《动画样式》 |
| `animationEffect` | `String` | `fadeIn` | 卡片入场动画,默认只有 `fadeIn`,引入 `animation.css` 后可使用其他动画 |
| `animationDuration` | `Number` | `1000` | 动画执行时间(单位毫秒),该动画时间只影响卡片重拍的时间,一般情况都不用修改,如果想要修改飞入动画的执行时间,见下文|
| `animationDelay` | `Number` | `300` | 动画延迟(单位毫秒)|
| `animationDuration` | `Number` | `1000` | 卡片入场动画执行时间(单位毫秒),该动画时间只影响卡片重拍的时间,一般情况都不用修改,如果想要修改飞入动画的执行时间,见下文|
| `animationDelay` | `Number` | `300` | 卡片入场动画延迟(单位毫秒)|
| `backgroundColor` | `String` | `#ffffff` | 背景颜色 |
| `loadProps` | `Object` | `loadProps` | 懒加载图片组件的属性设置,详情见下文《懒加载属性》 |
| `lazyload` | `Boolean` | `true` | 是否开启懒加载 |
| `crossOrigin` | `Boolean` | `true` | 图片加载是否开启跨域 |
| `delay` | `Number` | `300` | 布局刷新的防抖时间,默认 `300ms` 内没有再次触发才刷新布局。(图片加载完成;容器大小、`list``width``gutter``hasAroundGutter`变化时均会触发刷新) |
| `align` | `String` | `center` | 卡片的对齐方式,可选值为:`left`,`center`,`right` |

## `WaterfallList` 方法
| 方法名字 | 返回值类型 | 描述 |
| --------- | --------- | -------------- |
| `afterRender` | | 本次卡片坐标计算完成并且移动到了对应位置(列表渲染的过程可能会多次触发,比如有一张图片加载完成就会重新计算位置) |

## `LazyImg` 方法
| 方法名字 | 返回值类型 | 描述 |
| --------- | --------- | -------------- |
Expand All @@ -89,6 +95,7 @@ waterfall.value.renderer()
`WaterFall`组件向外暴露了一个`renderer`函数,可以直接调用,该方法可以主动重绘列表,使用其他懒加载图片组件的回调函数里可以调用这个renderer来重绘。

## 动画样式
首先需要明白,这里的动画指的是数据插入时的动画,比如第一次加载数据已经加载更多的时候的一个插入动画。
想要使用动画必须引入`animate.css`或者定义一个动画`className`
1. 如果引入了`animate.css`,并且版本是`4.x.x`及以上,可以不作任何处理
2. 如果引入了`animate.css`,并且是老版本则需要将`animationPrefix`设置为`animated`
Expand Down
2 changes: 1 addition & 1 deletion example/components/WaterfallApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const options = reactive({
},
// 是否懒加载
lazyload: true,
align: 'right',
align: 'center',
})
const dialogVisible = ref(false)
Expand Down
13 changes: 10 additions & 3 deletions example/components/WaterfallList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @FilePath: /vue3-waterfall/example/components/WaterfallList.vue
-->
<template>
<div style="width:100%">
<div v-loading="loading" style="min-height: 100%; width:100%">
<Waterfall
:list="list"
:row-key="options.rowKey"
Expand All @@ -22,6 +22,7 @@
:load-props="options.loadProps"
:cross-origin="options.crossOrigin"
:align="options.align"
@afterRender="afterRender"
>
<template #item="{ item, url, index }">
<div class="bg-gray-900 rounded-lg shadow-md overflow-hidden transition-all duration-300 ease-linear hover:shadow-lg hover:shadow-gray-600 group" @click="handleClick(item)">
Expand All @@ -47,7 +48,7 @@
</template>
</Waterfall>

<div class="flex justify-center py-10 bg-gray-900">
<div v-show="!loading" class="flex justify-center py-10 bg-gray-900">
<button class="px-5 py-2 rounded-full bg-gray-700 text-md text-white cursor-pointer hover:bg-gray-800 transition-all duration-300" @click="handleLoadMore">
加载更多
</button>
Expand Down Expand Up @@ -84,6 +85,7 @@ const emits = defineEmits({
// 列表
const list = ref<ViewCard[]>([])
const page = ref(1)
const loading = ref(true)
onMounted(() => {
handleLoadMore()
Expand Down Expand Up @@ -118,7 +120,12 @@ function imageError(url: string) {
}
function imageSuccess(url: string) {
// console.log(`${url}: 加载成功`)
console.log(`${url}: 加载成功`)
}
function afterRender() {
loading.value = false
console.log('计算完成')
}
</script>

Expand Down
10 changes: 8 additions & 2 deletions lib/components/Waterfall.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export default defineComponent({
type: Boolean,
default: true,
},
posDuration: {
type: Number,
default: 300,
},
animationPrefix: {
type: String,
default: 'animate__animated',
Expand Down Expand Up @@ -115,7 +119,7 @@ export default defineComponent({
},
},
setup(props) {
setup(props, ctx) {
const lazy: LazyType = new Lazy(props.lazyload, props.loadProps, props.crossOrigin)
provide('lazy', lazy)
Expand All @@ -139,7 +143,9 @@ export default defineComponent({
// 1s内最多执行一次排版,减少性能开销
const renderer = useDebounceFn(() => {
layoutHandle()
layoutHandle().then(() => {
ctx.emit('afterRender')
})
}, props.delay)
// 列表发生变化直接触发排版
Expand Down
1 change: 1 addition & 0 deletions lib/types/waterfall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type Breakpoints = Record<number, Point>
export interface WaterfallProps {
breakpoints: Breakpoints
width: number
posDuration: number
animationDuration: number
animationDelay: number
animationEffect: string
Expand Down
89 changes: 48 additions & 41 deletions lib/use/useLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,52 +35,60 @@ export function useLayout(props: WaterfallProps, colWidth: Ref<number>, cols: Re
const animation = addAnimation(props)

// 排版
const layoutHandle = async() => {
const layoutHandle = async(): Promise<boolean> => {
return new Promise((resolve) => {
// 初始化y集合
initY()

// 构造列表
const items: HTMLElement[] = []
if (waterfallWrapper && waterfallWrapper.value) {
waterfallWrapper.value.childNodes.forEach((el: any) => {
if (el!.className === 'waterfall-item')
items.push(el)
})
}
initY()

// 构造列表
const items: HTMLElement[] = []
if (waterfallWrapper && waterfallWrapper.value) {
waterfallWrapper.value.childNodes.forEach((el: any) => {
if (el!.className === 'waterfall-item')
items.push(el)
})
}

// 获取节点
if (items.length === 0) return false

// 获取节点
if (items.length === 0) return false
// 遍历节点
for (let i = 0; i < items.length; i++) {
const curItem = items[i] as HTMLElement
// 最小的y值
const minY = Math.min.apply(null, posY.value)
// 最小y的下标
const minYIndex = posY.value.indexOf(minY)
// 当前下标对应的x
const curX = getX(minYIndex)

// 遍历节点
for (let i = 0; i < items.length; i++) {
const curItem = items[i] as HTMLElement
// 最小的y值
const minY = Math.min.apply(null, posY.value)
// 最小y的下标
const minYIndex = posY.value.indexOf(minY)
// 当前下标对应的x
const curX = getX(minYIndex)
// 设置x,y,width
const style = curItem.style as CssStyleObject

// 设置x,y,width
const style = curItem.style as CssStyleObject
// 设置偏移
if (transform) style[transform] = `translate3d(${curX}px,${minY}px, 0)`
style.width = `${colWidth.value}px`

// 设置偏移
if (transform) style[transform] = `translate3d(${curX}px,${minY}px, 0)`
style.width = `${colWidth.value}px`
style.visibility = 'visible'

// 更新当前index的y值
const { height } = curItem.getBoundingClientRect()
posY.value[minYIndex] += height + props.gutter
// 更新当前index的y值
const { height } = curItem.getBoundingClientRect()
posY.value[minYIndex] += height + props.gutter

// 添加入场动画
animation(curItem, () => {
// 添加入场动画
animation(curItem, () => {
// 添加动画时间
const time = props.animationDuration / 1000
if (transition) style[transition] = `transform ${time}s`
})
}
const time = props.posDuration / 1000
if (transition) style[transition] = `transform ${time}s`
})
}

wrapperHeight.value = Math.max.apply(null, posY.value)

wrapperHeight.value = Math.max.apply(null, posY.value)
setTimeout(() => {
resolve(true)
}, props.posDuration)
})
}

return {
Expand All @@ -97,7 +105,9 @@ function addAnimation(props: WaterfallProps) {
const durationSec = `${props.animationDuration / 1000}s`
const delaySec = `${props.animationDelay / 1000}s`
const style = content.style as CssStyleObject
style.visibility = 'visible'
addClass(content, props.animationPrefix)
addClass(content, props.animationEffect)

if (duration)
style[duration] = durationSec

Expand All @@ -107,9 +117,6 @@ function addAnimation(props: WaterfallProps) {
if (fillMode)
style[fillMode] = 'both'

addClass(content, props.animationPrefix)
addClass(content, props.animationEffect)

if (callback) {
setTimeout(() => {
callback()
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ const elementStyle = document.createElement('div').style as CssStyleObject

const vendor = (() => {
const transformNames: Record<string, string> = {
standard: 'transform',
webkit: 'webkitTransform',
Moz: 'MozTransform',
O: 'OTransform',
ms: 'msTransform',
standard: 'transform',
}

for (const key in transformNames) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-waterfall-plugin-next",
"version": "2.3.1",
"version": "2.4.1",
"license": "UNLICENSED",
"author": "Yaowen Liu <576079353@qq.com>",
"main": "dist/my-lib.umd.js",
Expand Down

0 comments on commit 8101681

Please sign in to comment.