Last active
February 7, 2023 16:41
-
-
Save trafium/2a3a2cd820bf2d80e33dbfbd1857d040 to your computer and use it in GitHub Desktop.
Vue composition api example (using only refs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template lang="pug"> | |
| div.component(ref="elRef" :style="{ filter: `saturate(${saturation}) brightness(${brightness})` }") | |
| div | |
| div Brightness: {{brightness}} | |
| div Saturation: {{saturation}} | |
| div Width: {{width}} | |
| div Height: {{height}} | |
| div X: {{x}} | |
| div Y: {{y}} | |
| </template> | |
| <script> | |
| import { onBeforeUnmount, onMounted, ref, watch } from '@vue/composition-api'; | |
| export default { | |
| setup () { | |
| const elRef = ref(null); | |
| const { xRef, yRef } = useRelativeMousePosition(elRef); | |
| const { widthRef, heightRef } = useSizeObserver(elRef); | |
| const { brightnessRef } = useBrightness(xRef, widthRef); | |
| const { saturationRef } = useSaturation(yRef, heightRef); | |
| return { | |
| elRef, | |
| brightness: brightnessRef, | |
| saturation: saturationRef, | |
| width: widthRef, | |
| height: heightRef, | |
| x: xRef, | |
| y: yRef | |
| }; | |
| } | |
| }; | |
| function useRelativeMousePosition (elRef) { | |
| const xRef = ref(0); | |
| const yRef = ref(0); | |
| function update (event) { | |
| const rect = elRef.value.getBoundingClientRect(); | |
| xRef.value = event.clientX - rect.left; | |
| yRef.value = event.clientY - rect.top; | |
| } | |
| onMounted(() => window.addEventListener('mousemove', update)); | |
| onBeforeUnmount(() => window.removeEventListener('mousemove', update)); | |
| return { | |
| xRef, | |
| yRef | |
| }; | |
| } | |
| function useSizeObserver (elRef) { | |
| const widthRef = ref(0); | |
| const heightRef = ref(0); | |
| const resizeObserver = new ResizeObserver(entries => { | |
| for (let entry of entries) { | |
| widthRef.value = entry.contentRect.width; | |
| heightRef.value = entry.contentRect.height; | |
| } | |
| }); | |
| onMounted(() => resizeObserver.observe(elRef.value)); | |
| onBeforeUnmount(() => resizeObserver.unobserve(elRef.value)); | |
| return { | |
| widthRef, | |
| heightRef | |
| }; | |
| } | |
| function useBrightness (valueRef, maxValueRef) { | |
| const brightnessRef = ref(0); | |
| watch([valueRef, maxValueRef], ([value, max]) => { | |
| brightnessRef.value = cappedValue(value, { max, min: 0 }); | |
| }, { lazy: true }); | |
| return { brightnessRef }; | |
| } | |
| function useSaturation (valueRef, maxValueRef) { | |
| const saturationRef = ref(0); | |
| watch([valueRef, maxValueRef], ([value, max]) => { | |
| saturationRef.value = cappedValue(value, { max, min: 0 }); | |
| }, { lazy: true }); | |
| return { saturationRef }; | |
| } | |
| function cappedValue (value, { max, min }) { | |
| return Math.max(min, Math.min(value, max)) / max; | |
| } | |
| </script> | |
| <style | |
| lang="scss" | |
| scoped | |
| > | |
| .component { | |
| max-width: 700px; | |
| min-height: 300px; | |
| background: royalblue; | |
| color: white; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-direction: column; | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment