Skip to content

Instantly share code, notes, and snippets.

@trafium
Last active February 7, 2023 16:41
Show Gist options
  • Select an option

  • Save trafium/2a3a2cd820bf2d80e33dbfbd1857d040 to your computer and use it in GitHub Desktop.

Select an option

Save trafium/2a3a2cd820bf2d80e33dbfbd1857d040 to your computer and use it in GitHub Desktop.
Vue composition api example (using only refs)
<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