媒体报道&联系我们
This commit is contained in:
@@ -8,6 +8,15 @@
|
||||
* 参数
|
||||
* GetRoot: 获取根元素函数-优先级(GetRoot > parent > document)
|
||||
* activeClass: 激活类名-默认值(active)
|
||||
* duration: 动画时间-默认值(0.5s)
|
||||
* delay: 延迟时间-默认值(0s)
|
||||
* easing: 缓动函数-默认值(ease-out)
|
||||
* transformDuration: 变换时间-默认值 duration
|
||||
* transformDelay: 变换延迟时间-默认值 delay
|
||||
* transformEasing: 变换缓动函数-默认值 easing
|
||||
* opacityDuration: 透明度时间-默认值 duration
|
||||
* opacityDelay: 透明度延迟时间-默认值 delay
|
||||
* opacityEasing: 透明度缓动函数-默认值 easing
|
||||
*
|
||||
* 子元素动画
|
||||
* <div translate-x-s="-100" translate-x="100"></div>
|
||||
@@ -40,6 +49,16 @@ const T = {
|
||||
rotateZ: 'rotate-z',
|
||||
opacity_s: 'opacity-s',
|
||||
opacity: 'opacity',
|
||||
// 动画属性配置
|
||||
duration: 'duration',
|
||||
delay: 'delay',
|
||||
easing: 'easing',
|
||||
transformDuration: 'transform-duration',
|
||||
transformDelay: 'transform-delay',
|
||||
transformEasing: 'transform-easing',
|
||||
opacityDuration: 'opacity-duration',
|
||||
opacityDelay: 'opacity-delay',
|
||||
opacityEasing: 'opacity-easing',
|
||||
}
|
||||
const types = Object.values(T)
|
||||
const typesStr = types.map(v => `[${v}]`).join(',')
|
||||
@@ -55,8 +74,22 @@ export default {
|
||||
const { value, modifiers } = binding
|
||||
const {
|
||||
GetRoot,// 获取根元素函数
|
||||
activeClass = 'active'// 激活类名
|
||||
activeClass = 'active',// 激活类名
|
||||
duration = '0.5s',// 动画时间
|
||||
delay = '0s',// 延迟时间
|
||||
easing = 'ease-out',// 缓动函数
|
||||
} = value || {}
|
||||
const transition = {
|
||||
duration,
|
||||
delay,
|
||||
easing,
|
||||
transformDuration: value?.transformDuration || value?.[T.transformDuration],
|
||||
transformDelay: value?.transformDelay || value?.[T.transformDelay],
|
||||
transformEasing: value?.transformEasing || value?.[T.transformEasing],
|
||||
opacityDuration: value?.opacityDuration || value?.[T.opacityDuration],
|
||||
opacityDelay: value?.opacityDelay || value?.[T.opacityDelay],
|
||||
opacityEasing: value?.opacityEasing || value?.[T.opacityEasing],
|
||||
}
|
||||
const {
|
||||
scroll = false,// 是否监听滚动事件
|
||||
once = false,// 是否只执行一次
|
||||
@@ -64,22 +97,28 @@ export default {
|
||||
} = modifiers
|
||||
const root = GetRoot ? GetRoot() : parent ? el.parentElement : document;
|
||||
if (el === root) return;
|
||||
add(el, root)
|
||||
els.set(el, {
|
||||
const config = {
|
||||
root,// 根元素
|
||||
scroll,
|
||||
once,
|
||||
activeClass,
|
||||
isActive: false,
|
||||
})
|
||||
transition,
|
||||
}
|
||||
els.set(el, config)
|
||||
add(el, root, config)
|
||||
},
|
||||
beforeUnmount(el, binding) {
|
||||
remove(el)
|
||||
els.delete(el)
|
||||
}
|
||||
};
|
||||
function add(el, root = document) {
|
||||
requestAnimationFrame(() => handleScroll({ target: root }))
|
||||
function add(el, root = document, config) {
|
||||
if (config.scroll) {
|
||||
requestAnimationFrame(() => handleScroll({ target: root }))
|
||||
} else {
|
||||
getChildren(el).forEach((child) => setDocumentStyles(el, child, 0))
|
||||
}
|
||||
resize.observe(el)
|
||||
if (roots.has(root)) {
|
||||
let obj = roots.get(root)
|
||||
@@ -97,6 +136,9 @@ function add(el, root = document) {
|
||||
if (obj.once && obj.isActive) return;// 只执行一次,且已可见,不执行
|
||||
obj.isActive = entry.isIntersecting;
|
||||
target.classList.toggle(obj.activeClass, obj.isActive)
|
||||
getChildren(target).forEach((el) => {
|
||||
setDocumentStyles(target, el, obj.isActive ? 1 : 0)
|
||||
})
|
||||
})
|
||||
}, { root })
|
||||
observer.observe(el)
|
||||
@@ -128,8 +170,7 @@ async function handleScroll({ target: root }) {
|
||||
const item = els.get(el)
|
||||
if (!item) return
|
||||
if (!item.scroll) return
|
||||
const children = Array.from(el.querySelectorAll(typesStr))
|
||||
if (Object.values(T).some(v => hasAttr(el, v))) children.push(el)
|
||||
const children = getChildren(el)
|
||||
if (children.length === 0) return
|
||||
const rootEl = isDocumentRoot(root)
|
||||
const offsetHeight = root === document ? window.innerHeight : rootEl.offsetHeight
|
||||
@@ -139,27 +180,53 @@ async function handleScroll({ target: root }) {
|
||||
const maxHeight = offsetHeight + el.offsetHeight
|
||||
const p = Math.min(1, Math.max(0, elTop_bottom / maxHeight))
|
||||
children.forEach((item) => {
|
||||
item.style.transition = 'transform 0.5s ease-out'
|
||||
|
||||
const tX = getCurrentValue(item, T.translateX_s, T.translateX, p)
|
||||
const tY = getCurrentValue(item, T.translateY_s, T.translateY, p)
|
||||
const sx = getCurrentValue(item, T.scaleX_s, T.scaleX, p, T.scale_s, T.scale, 1)
|
||||
const sy = getCurrentValue(item, T.scaleY_s, T.scaleY, p, T.scale_s, T.scale, 1)
|
||||
const r = getCurrentValue(item, T.rotate_s, T.rotate, p)
|
||||
const rx = getCurrentValue(item, T.rotateX_s, T.rotateX, p)
|
||||
const ry = getCurrentValue(item, T.rotateY_s, T.rotateY, p)
|
||||
const rz = getCurrentValue(item, T.rotateZ_s, T.rotateZ, p)
|
||||
const transform = `translate(${tX}px, ${tY}px) scale(${sx}, ${sy}) rotate(${r}deg) rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`
|
||||
item.style.transform = transform
|
||||
if (hasAttr(item, [T.opacity_s, T.opacity])) {
|
||||
item.style.opacity = getCurrentValue(item, T.opacity_s, T.opacity, p, T.opacity_s, T.opacity, 1)
|
||||
}
|
||||
setDocumentStyles(el, item, p)
|
||||
})
|
||||
})
|
||||
}
|
||||
function getChildren(el, oneself = true) {
|
||||
const children = Array.from(el.querySelectorAll(typesStr))
|
||||
if (oneself && Object.values(T).some(v => hasAttr(el, v))) children.push(el)
|
||||
return children
|
||||
}
|
||||
function setDocumentStyles(parent, el, p = 0) {
|
||||
const item = els.get(parent)
|
||||
if (!item) return
|
||||
const t = getAttrs(el, item.transition)
|
||||
const tDuration = t.duration || t.transformDuration
|
||||
const tDelay = t.delay || t.transformDelay
|
||||
const tEasing = t.easing || t.transformEasing
|
||||
const oDuration = t.duration || t.opacityDuration
|
||||
const oDelay = t.delay || t.opacityDelay
|
||||
const oEasing = t.easing || t.opacityEasing
|
||||
const transitionArr = [
|
||||
`transform ${tDuration} ${tDelay} ${tEasing}`,
|
||||
`opacity ${oDuration} ${oDelay} ${oEasing}`,
|
||||
]
|
||||
el.style.transition = transitionArr.join(', ')
|
||||
const tX = getCurrentValue(el, T.translateX_s, T.translateX, p)
|
||||
const tY = getCurrentValue(el, T.translateY_s, T.translateY, p)
|
||||
const sx = getCurrentValue(el, T.scaleX_s, T.scaleX, p, T.scale_s, T.scale, 1)
|
||||
const sy = getCurrentValue(el, T.scaleY_s, T.scaleY, p, T.scale_s, T.scale, 1)
|
||||
const r = getCurrentValue(el, T.rotate_s, T.rotate, p)
|
||||
const rx = getCurrentValue(el, T.rotateX_s, T.rotateX, p)
|
||||
const ry = getCurrentValue(el, T.rotateY_s, T.rotateY, p)
|
||||
const rz = getCurrentValue(el, T.rotateZ_s, T.rotateZ, p)
|
||||
const transform = `translate(${tX}px, ${tY}px) scale(${sx}, ${sy}) rotate(${r}deg) rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`
|
||||
el.style.transform = transform
|
||||
if (hasAttr(el, [T.opacity_s, T.opacity])) {
|
||||
el.style.opacity = getCurrentValue(el, T.opacity_s, T.opacity, p, T.opacity_s, T.opacity, 1)
|
||||
}
|
||||
}
|
||||
function getAttrs(el, attrs = {}) {
|
||||
const arrs = Object.keys(attrs)
|
||||
const obj = {}
|
||||
arrs.forEach((item) => {
|
||||
obj[item] = el.getAttribute(T[item]) || attrs[item]
|
||||
})
|
||||
return obj
|
||||
}
|
||||
function getCurrentValue(el, start, end, progress, bStart, bEnd, defaultValue = 0) {
|
||||
// const startNum = Number(el.getAttribute(start) || el.getAttribute(bStart)) || defaultValue
|
||||
// const endNum = Number(el.getAttribute(end) || el.getAttribute(bEnd)) || defaultValue
|
||||
const startNum = hasAttr(el, start) ? Number(el.getAttribute(start)) : hasAttr(el, bStart) ? Number(el.getAttribute(bStart)) : defaultValue
|
||||
const endNum = hasAttr(el, end) ? Number(el.getAttribute(end)) : hasAttr(el, bEnd) ? Number(el.getAttribute(bEnd)) : defaultValue
|
||||
return startNum + (endNum - startNum) * progress
|
||||
|
||||
Reference in New Issue
Block a user