Skip to content

Instantly share code, notes, and snippets.

@smolinari
Last active September 4, 2019 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smolinari/37367d96e800c940c289e86f752c2562 to your computer and use it in GitHub Desktop.
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>
@smolinari
Copy link
Author

@trafium - edited. Will that work?

Scott

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment