Skip to content

Instantly share code, notes, and snippets.

@JanMalch
Last active September 12, 2022 15:02
Show Gist options
  • Save JanMalch/ba568b39a8ecedaaca9c6ff2ecef93aa to your computer and use it in GitHub Desktop.
Save JanMalch/ba568b39a8ecedaaca9c6ff2ecef93aa to your computer and use it in GitHub Desktop.
animated waves while scrolling
<template>
<div aria-hidden="true" class="wave-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
<path fill="currentColor"
fill-opacity="1"
:d="d">
</path>
</svg>
<div class="bottom-filler"></div>
</div>
</template>
<script lang="ts" setup>
import { compile, morph } from 'svg-path-morph'
import { onMounted, ref } from 'vue';
// https://getwaves.io/
const paths = [
'M0,288L34.3,261.3C68.6,235,137,181,206,170.7C274.3,160,343,192,411,170.7C480,149,549,75,617,42.7C685.7,11,754,21,823,58.7C891.4,96,960,160,1029,192C1097.1,224,1166,224,1234,202.7C1302.9,181,1371,139,1406,117.3L1440,96L1440,320L1405.7,320C1371.4,320,1303,320,1234,320C1165.7,320,1097,320,1029,320C960,320,891,320,823,320C754.3,320,686,320,617,320C548.6,320,480,320,411,320C342.9,320,274,320,206,320C137.1,320,69,320,34,320L0,320Z',
'M0,192L34.3,170.7C68.6,149,137,107,206,80C274.3,53,343,43,411,64C480,85,549,139,617,176C685.7,213,754,235,823,213.3C891.4,192,960,128,1029,117.3C1097.1,107,1166,149,1234,165.3C1302.9,181,1371,171,1406,165.3L1440,160L1440,320L1405.7,320C1371.4,320,1303,320,1234,320C1165.7,320,1097,320,1029,320C960,320,891,320,823,320C754.3,320,686,320,617,320C548.6,320,480,320,411,320C342.9,320,274,320,206,320C137.1,320,69,320,34,320L0,320Z',
'M0,0L34.3,32C68.6,64,137,128,206,181.3C274.3,235,343,277,411,256C480,235,549,149,617,128C685.7,107,754,149,823,154.7C891.4,160,960,128,1029,133.3C1097.1,139,1166,181,1234,197.3C1302.9,213,1371,203,1406,197.3L1440,192L1440,320L1405.7,320C1371.4,320,1303,320,1234,320C1165.7,320,1097,320,1029,320C960,320,891,320,823,320C754.3,320,686,320,617,320C548.6,320,480,320,411,320C342.9,320,274,320,206,320C137.1,320,69,320,34,320L0,320Z',
];
const compiled = compile(paths);
const d = ref('');
const props = defineProps<{
scrollEl: string;
}>()
onMounted(() => {
applyPercentage(0);
const scrollElement = document.querySelector(props.scrollEl);
if (scrollElement == null) {
return;
}
scrollElement.addEventListener('scroll', () => {
const total = scrollElement.scrollHeight - scrollElement.clientHeight;
applyPercentage(scrollElement.scrollTop / total);
}, {passive: true})
})
function applyPercentage(percentage: number) {
const total = paths.length;
const center = (total - 1) * percentage;
const index = Math.floor(center);
const remainder = center - index;
const percentages = Array(total).fill(0);
percentages[index] = 1 - remainder;
percentages[index + 1] = remainder;
d.value = morph(compiled, percentages.slice(0, total))
}
</script>
<style lang="scss" scoped>
.wave-container {
color: #2c353f;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 70vh;
display: flex;
flex-direction: column;
> .bottom-filler {
background-color: currentColor;
width: 100%;
flex: 1;
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment