Last active
September 4, 2019 07:40
-
-
Save smolinari/37367d96e800c940c289e86f752c2562 to your computer and use it in GitHub Desktop.
This file contains 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="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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@trafium - edited. Will that work?
Scott