-
-
Save smolinari/37367d96e800c940c289e86f752c2562 to your computer and use it in GitHub Desktop.
| <template lang="pug"> | |
| div.component(ref="el" :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, reactive, ref, toRefs, watch } from '@vue/composition-api' | |
| export default { | |
| setup () { | |
| let el = ref(null) | |
| const { x, y } = useRelativeMousePosition(el) | |
| const { width, height } = useSizeObserver(el) | |
| const { brightness } = useBrightness(x, width) | |
| const { saturation } = useSaturation(y, height) | |
| return { | |
| el, | |
| width, | |
| height, | |
| x, | |
| y, | |
| brightness, | |
| saturation | |
| } | |
| } | |
| } | |
| function useRelativeMousePosition (el) { | |
| let mousePosition = reactive({ | |
| x: 0, | |
| y: 0 | |
| }) | |
| function update (event) { | |
| const rect = el.getBoundingClientRect() | |
| mousePosition.x = event.clientX - rect.left | |
| mousePosition.y = event.clientY - rect.top | |
| } | |
| onMounted(() => window.addEventListener('mousemove', update)) | |
| onBeforeUnmount(() => window.removeEventListener('mousemove', update)) | |
| return toRefs(mousePosition) | |
| function useSizeObserver (el) { | |
| let attrs = reactive({ | |
| width: 0, | |
| height: 0 | |
| }) | |
| const resizeObserver = new ResizeObserver(entries => { | |
| for (let entry of entries) { | |
| attrs.width = entry.contentRect.width | |
| attrs.height = entry.contentRect.height | |
| } | |
| }) | |
| onMounted(() => resizeObserver.observe(el)) | |
| onBeforeUnmount(() => resizeObserver.unobserve(el)) | |
| return toRefs(attrs) | |
| } | |
| function useBrightness (value, maxValue) { | |
| let brightnessRef = ref(0) | |
| watch([value, maxValue], ([value, max]) => { | |
| brightnessRef = cappedValue(value, { max, min: 0 }) | |
| }, { lazy: true }) | |
| return { brightnessRef } | |
| } | |
| function useSaturation (value, maxValue) { | |
| let saturationRef = ref(0) | |
| watch([value, maxValue], ([value, max]) => { | |
| saturationRef = 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> |
Not too much different than what you had with just Refs. ๐
Scott
Refs look more useful and less confusing than reactive and this final version doesn't look much different than the refs version. I don't see when you would prefer reactive over refs.
I use it to group properties that really do belong together. A mouse position always has an x and y. A date range that has start, end. In the rare occasion you really only need/can pass the y axis along, i'd destructure it into refs.
I actually use it rather often. It might seem that reactive is superfluous, but at this point I would not want to miss it.
@smolinari
Will check your solution soon.
I realised that in my use cases i never had to deal with actual mutable lists or other complex data. Took me long to realise, but seems like I can't really do those with refs only without much pain ๐
@smolinari
Besides couple of typos there are still problems with lines #20 and #21 because primitive values are passed into functions instead of refs/reactive data.
@trafium - And if just the variable is passed in without value? Using value in the function?
Scott
@smolinari
Yes, in fact we don't need to use .value at all since we would pass ref into watch and receive plain values in callback function ([value, max] part)
@trafium - edited. Will that work?
Scott
I'm taking the "Ref" postfix out.
Scott