Skip to content

Instantly share code, notes, and snippets.

@Niedzwiedzw
Created April 13, 2021 10:50
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 Niedzwiedzw/e5f421e3e79986ef7fa07045f0515397 to your computer and use it in GitHub Desktop.
Save Niedzwiedzw/e5f421e3e79986ef7fa07045f0515397 to your computer and use it in GitHub Desktop.
Vue 3 element overlay wrapper
<template>
<div class="FillOverlay" ref="element">
<slot class="overlay-content"></slot>
<div class="overlay" :style="currentOverlayStyle" :key="percent"></div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed, onMounted } from "vue";
import { useInterval } from "../../composables/forms";
function px(val: number): string {
return `${val}px`;
}
export default defineComponent({
name: "FillOverlay",
props: {
percent: {
type: Number,
required: true,
},
},
setup(props) {
const isChromium = !!(window as any).chrome;
const element = ref<HTMLDivElement | null>(null);
const percent_ = computed(() => props.percent);
const currentOverlayStyle = ref<Partial<CSSStyleDeclaration>>({});
const overlayStyle = (): Partial<CSSStyleDeclaration> => {
if (element.value == null) {
console.error("percentage for overlay is missing");
return {};
}
const height = element.value.offsetHeight * percent_.value;
const heightOffset =
element.value.offsetHeight * (1 - percent_.value) * 0.5;
return {
width: px(element.value.offsetWidth),
height: px(height),
...(isChromium && {
transform: `translate3d(-1rem, calc(${px(
heightOffset * 2
)} - 1rem), 0)`,
}),
...(!isChromium && {
transform: `translate3d(-1rem, calc(${px(heightOffset)} - 1rem), 0)`,
}),
};
};
const setOverlay = async () => {
const newStyle = overlayStyle();
currentOverlayStyle.value = newStyle;
};
const overlayHash = computed(() =>
JSON.stringify(currentOverlayStyle.value)
);
onMounted(() => {
setOverlay();
useInterval(setOverlay, 1000);
});
return { currentOverlayStyle, element, overlayHash, percent_ };
},
});
</script>
<style scoped lang="scss">
@import "@/styles/main";
.FillOverlay {
cursor: pointer;
display: grid;
.overlay-content,
.overlay {
grid-column: 1 / -1;
grid-row: 1 / -1;
}
.overlay {
position: absolute;
background-color: $petroleum-primary;
transition: opacity 0.2s ease-in-out;
opacity: 0.05;
border-radius: 1rem;
pointer-events: none;
}
&:hover {
.overlay {
opacity: 0.2;
}
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment