mirror of
https://github.com/antd-tiny-vue/antd-tiny-vue.git
synced 2024-11-10 09:39:15 +08:00
feat: add wave effect
This commit is contained in:
parent
69388270af
commit
9243370f1c
@ -20,7 +20,7 @@ const Wave = defineComponent({
|
||||
const [, hashId] = useStyle(prefixCls)
|
||||
const showWave = useWave(
|
||||
containerRef,
|
||||
computed(() => classNames(prefixCls, hashId))
|
||||
computed(() => classNames(prefixCls.value, hashId.value))
|
||||
)
|
||||
|
||||
const onClick = (e: MouseEvent) => {
|
||||
|
@ -1,15 +1,91 @@
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
import { unrefElement } from '@vueuse/core'
|
||||
import { defineComponent, render } from 'vue'
|
||||
import { objectType } from '@v-c/utils'
|
||||
|
||||
import { unrefElement, useResizeObserver } from '@vueuse/core'
|
||||
import { computed, defineComponent, onMounted, render, shallowRef, toRef } from 'vue'
|
||||
import { classNames, delayTimer, objectType, safeNextick, useState } from '@v-c/utils'
|
||||
import { getTargetWaveColor } from './util'
|
||||
function validateNum(value: number) {
|
||||
return Number.isNaN(value) ? 0 : value
|
||||
}
|
||||
export const WaveEffect = defineComponent({
|
||||
name: 'WaveEffect',
|
||||
props: {
|
||||
target: objectType<HTMLElement>()
|
||||
},
|
||||
setup() {
|
||||
return () => null
|
||||
setup(props, { attrs }) {
|
||||
const divRef = shallowRef<HTMLDivElement | undefined>(undefined)
|
||||
|
||||
const [color, setWaveColor] = useState<string | null>(null)
|
||||
const [borderRadius, setBorderRadius] = useState<number[]>([])
|
||||
const [left, setLeft] = useState(0)
|
||||
const [top, setTop] = useState(0)
|
||||
const [width, setWidth] = useState(0)
|
||||
const [height, setHeight] = useState(0)
|
||||
const [enabled, setEnabled] = useState(false)
|
||||
const [active, setActive] = useState(false)
|
||||
const waveStyle = computed(() => {
|
||||
const style: Record<string, any> = {
|
||||
left: `${left.value}px`,
|
||||
top: `${top.value}px`,
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
borderRadius: borderRadius.value.map(radius => `${radius}px`).join(' ')
|
||||
}
|
||||
if (color.value) {
|
||||
style['--wave-color'] = color.value
|
||||
}
|
||||
return style
|
||||
})
|
||||
function syncPos() {
|
||||
const { target } = props
|
||||
const nodeStyle = getComputedStyle(target)
|
||||
|
||||
// Get wave color from target
|
||||
setWaveColor(getTargetWaveColor(target))
|
||||
|
||||
const isStatic = nodeStyle.position === 'static'
|
||||
|
||||
// Rect
|
||||
const { borderLeftWidth, borderTopWidth } = nodeStyle
|
||||
setLeft(isStatic ? target.offsetLeft : validateNum(-parseFloat(borderLeftWidth)))
|
||||
setTop(isStatic ? target.offsetTop : validateNum(-parseFloat(borderTopWidth)))
|
||||
setWidth(target.offsetWidth)
|
||||
setHeight(target.offsetHeight)
|
||||
|
||||
// Get border radius
|
||||
const { borderTopLeftRadius, borderTopRightRadius, borderBottomLeftRadius, borderBottomRightRadius } = nodeStyle
|
||||
|
||||
setBorderRadius([borderTopLeftRadius, borderTopRightRadius, borderBottomRightRadius, borderBottomLeftRadius].map(radius => validateNum(parseFloat(radius))))
|
||||
}
|
||||
onMounted(async () => {
|
||||
syncPos()
|
||||
setEnabled(true)
|
||||
await safeNextick()
|
||||
setActive(true)
|
||||
await delayTimer(5000)
|
||||
const holder = divRef.value?.parentElement
|
||||
holder!.parentElement?.removeChild(holder!)
|
||||
})
|
||||
const motionClassName = computed(() =>
|
||||
classNames({
|
||||
'wave-motion-appear': enabled.value,
|
||||
'wave-motion': true
|
||||
})
|
||||
)
|
||||
const motionClassNameActive = computed(() => ({
|
||||
'wave-motion-appear-active': active.value
|
||||
}))
|
||||
useResizeObserver(toRef(props, 'target'), syncPos)
|
||||
|
||||
return () => {
|
||||
if (!enabled.value) return null
|
||||
return (
|
||||
<div
|
||||
ref={divRef}
|
||||
class={[attrs.class, motionClassName.value, motionClassNameActive.value]}
|
||||
style={waveStyle.value}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -12,6 +12,7 @@ title: 基础按钮
|
||||
<template>
|
||||
<div>
|
||||
<a-button>这是按钮</a-button>
|
||||
<div style="height: 10px"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user