官方 Demo:https://vueuse.org/core/useParallax/#demo
個人一直很喜歡視差效果,看到官方 Demo 後,似乎是一個幫助我們花少少的力氣就可以實現出視差效果的工具,本來在 useThrottleFn 之後想繼續講 useDebounceFn,但突然覺得有點膩 XD,所以就先跳來 useParallax。
export function useParallax(target, options = {}) {
const {
deviceOrientationTiltAdjust = i => i,
deviceOrientationRollAdjust = i => i,
mouseTiltAdjust = i => i,
mouseRollAdjust = i => i,
window = defaultWindow,
} = options
const orientation = reactive(useDeviceOrientation({ window }))
const screenOrientation = reactive(useScreenOrientation({ window }))
const {
elementX: x,
elementY: y,
elementWidth: width,
elementHeight: height,
} = useMouseInElement(target, { handleOutside: false, window })
const source = computed(() => {
if (orientation.isSupported
&& ((orientation.alpha != null && orientation.alpha !== 0) || (orientation.gamma != null && orientation.gamma !== 0))
) {
return 'deviceOrientation'
}
return 'mouse'
})
const roll = computed(() => {
if (source.value === 'deviceOrientation') {
let value: number
switch (screenOrientation.orientation) {
case 'landscape-primary':
value = orientation.gamma! / 90
break
case 'landscape-secondary':
value = -orientation.gamma! / 90
break
case 'portrait-primary':
value = -orientation.beta! / 90
break
case 'portrait-secondary':
value = orientation.beta! / 90
break
default:
value = -orientation.beta! / 90
}
return deviceOrientationRollAdjust(value)
}
else {
const value = -(y.value - height.value / 2) / height.value
return mouseRollAdjust(value)
}
})
const tilt = computed(() => {
if (source.value === 'deviceOrientation') {
let value: number
switch (screenOrientation.orientation) {
case 'landscape-primary':
value = orientation.beta! / 90
break
case 'landscape-secondary':
value = -orientation.beta! / 90
break
case 'portrait-primary':
value = orientation.gamma! / 90
break
case 'portrait-secondary':
value = -orientation.gamma! / 90
break
default:
value = orientation.gamma! / 90
}
return deviceOrientationTiltAdjust(value)
}
else {
const value = (x.value - width.value / 2) / width.value
return mouseTiltAdjust(value)
}
})
return { roll, tilt, source }
}
除了根據 mouse event 做視差計算以外,如果裝置有支援 orientation,拿著裝置翻轉的時候,也可以看到視差效果,因為 IOS 裝置需要 requestPermission 才能看到笑果,如果手邊有 Android 裝置的話,可以去官方 Demo 玩玩看~
另外可以看到,useParallax 本身也用到了很多其他 vueuse composition api,以下條列出來:
所以先把上面的 API 全部實作完,最後再處理到 useParallax。接下來的順序會是先從 useEventListener 開始,接著是兩個跟滑鼠相關的:useMouse 和 useMouseInElement。再來看兩個跟裝置方向有關的:useDeviceOrientation 和 useScreenOrientation。最後再回到 useParallax。