Skip to content

Commit

Permalink
fix(home): Relax scroll snap behaviour on home page (#198)
Browse files Browse the repository at this point in the history
* fix(home): Relax home page scrolling behaviour

* refactor(home): Remove unused scroll functionality
  • Loading branch information
Hanziness committed Apr 7, 2022
1 parent 182a328 commit 81c85f7
Showing 1 changed file with 40 additions and 92 deletions.
132 changes: 40 additions & 92 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<div class="overflow-x-hidden snap-y snap-mandatory overflow-y-scroll h-screen" @wheel.prevent="handleScroll">
<div class="snap-y snap-proximity h-screen overflow-x-hidden overflow-y-scroll">
<div ref="top" class="invisible" />

<!-- FAB -->
<Transition name="fab-transition">
<nuxt-link v-show="showFAB" v-slot="{ navigate }" to="/timer" custom>
<div role="button" tabindex="0" class="transition absolute w-full bottom-0 rounded-t-lg xl:w-auto xl:right-6 xl:bottom-4 z-10 xl:rounded-lg text-xl shadow-md px-4 py-3 bg-amber-300 hover:bg-amber-400 shadow-amber-300/30 hover:shadow-amber-300/60 active:duration-500 active:shadow-xl active:shadow-amber-300/80 active:bg-amber-500 text-black font-bold uppercase cursor-pointer flex flex-row space-x-2 items-center border border-neutral-100" @click="navigate">
<div role="button" tabindex="0" class="xl:w-auto xl:right-6 xl:bottom-4 xl:rounded-lg bg-amber-300 hover:bg-amber-400 shadow-amber-300/30 hover:shadow-amber-300/60 active:duration-500 active:shadow-xl active:shadow-amber-300/80 active:bg-amber-500 border-neutral-100 absolute bottom-0 z-10 flex flex-row items-center w-full px-4 py-3 space-x-2 text-xl font-bold text-black uppercase transition border rounded-t-lg shadow-md cursor-pointer" @click="navigate">
<img src="/favicon.svg" width="32" height="32" role="presentation">
<span v-text="$i18n.t('index.launch')" />
</div>
Expand All @@ -14,31 +14,31 @@

<!-- Section 1: intro -->

<Section ref="section-1" class="snap-center bg-gray-100 justify-center flex flex-col overflow-hidden items-center">
<Columns class="flex-col xl:flex-row xl:space-x-16 px-4 xl:px-24 pt-8 xl:pt-0">
<Section ref="section-1" class="snap-center flex flex-col items-center justify-center overflow-hidden bg-gray-100">
<Columns class="xl:flex-row xl:space-x-16 xl:px-24 xl:pt-0 flex-col px-4 pt-8">
<template #left>
<!-- App title and CTAs -->
<div class="transition-all duration-1000 flex flex-col justify-center" :class="{ 'opacity-0 -translate-x-4': !loading.mainText }">
<div class="flex flex-row items-start xl:mr-16">
<div class="flex flex-col justify-center transition-all duration-1000" :class="{ 'opacity-0 -translate-x-4': !loading.mainText }">
<div class="xl:mr-16 flex flex-row items-start">
<!-- App icon -->
<div class="mr-4 mt-1 min-w-max min-h-max">
<img src="/favicon.svg" width="68" height="68" class="bg-red-200 rounded-lg p-2" role="presentation">
<div class="min-w-max min-h-max mt-1 mr-4">
<img src="/favicon.svg" width="68" height="68" class="p-2 bg-red-200 rounded-lg" role="presentation">
</div>
<!-- App name and slogan -->
<div class="flex flex-col">
<h1 class="text-3xl md:text-5xl font-bold">
<h1 class="md:text-5xl text-3xl font-bold">
AnotherPomodoro
</h1>
<div class="text-lg md:text-xl" v-text="$i18n.t('index.app_description')" />
<div class="md:text-xl text-lg" v-text="$i18n.t('index.app_description')" />
</div>
</div>
<!-- CTAs -->
<div class="grid grid-flow-row md:grid-flow-col grid-cols-1 md:grid-cols-2 mt-6 gap-2">
<div class="md:grid-flow-col md:grid-cols-2 grid grid-flow-row grid-cols-1 gap-2 mt-6">
<nuxt-link v-slot="{ navigate }" to="/timer" custom>
<div class="flex-grow text-center px-6 py-4 bg-amber-300 hover:bg-amber-400 shadow-amber-300/30 hover:shadow-amber-300/60 active:duration-500 active:shadow-xl active:shadow-amber-300/80 active:bg-amber-500 shadow-lg text-2xl rounded-lg font-bold uppercase cursor-pointer transition-all" role="button" tabindex="0" @click="navigate" v-text="$i18n.t('index.cta.quickstart')" />
<div class="bg-amber-300 hover:bg-amber-400 shadow-amber-300/30 hover:shadow-amber-300/60 active:duration-500 active:shadow-xl active:shadow-amber-300/80 active:bg-amber-500 flex-grow px-6 py-4 text-2xl font-bold text-center uppercase transition-all rounded-lg shadow-lg cursor-pointer" role="button" tabindex="0" @click="navigate" v-text="$i18n.t('index.cta.quickstart')" />
</nuxt-link>
<nuxt-link v-slot="{ navigate }" to="/setup" custom>
<div class="flex-grow text-center px-6 py-4 bg-slate-300 hover:bg-gray-300 text-2xl rounded-lg font-bold uppercase cursor-pointer transition-all shadow-slate-300/0 hover:shadow-slate-300/40 hover:shadow-lg active:shadow-slate-300/60 active:bg-slate-400" role="button" tabindex="0" @click="navigate" v-text="$i18n.t('index.cta.configure')" />
<div class="bg-slate-300 hover:bg-gray-300 shadow-slate-300/0 hover:shadow-slate-300/40 hover:shadow-lg active:shadow-slate-300/60 active:bg-slate-400 flex-grow px-6 py-4 text-2xl font-bold text-center uppercase transition-all rounded-lg cursor-pointer" role="button" tabindex="0" @click="navigate" v-text="$i18n.t('index.cta.configure')" />
</nuxt-link>
</div>
</div>
Expand All @@ -62,16 +62,16 @@
</Columns>

<template #after>
<div class="flex-grow xl:absolute xl:bottom-4 flex flex-col items-center justify-end">
<div class="xl:absolute xl:bottom-4 flex flex-col items-center justify-end flex-grow">
<!-- Source code, support and social buttons -->
<div class="flex flex-row space-x-2 mb-4">
<div class="flex flex-row mb-4 space-x-2">
<SupportButton
:aria-label="$i18n.t('index.alt.links.source')"
icon-size="28"
type="github"
:show-text="false"
:default-colours="false"
class="p-2 bg-black hover:bg-gray-800 active:bg-gray-900 text-gray-100"
class="hover:bg-gray-800 active:bg-gray-900 p-2 text-gray-100 bg-black"
utm-tags="?utm_source=AnotherPomodoro&utm_medium=web&utm_content=home"
tabindex="0"
/>
Expand All @@ -81,7 +81,7 @@
type="support"
:show-text="false"
:default-colours="false"
class="p-2 bg-black hover:bg-gray-800 active:bg-gray-900 text-gray-100"
class="hover:bg-gray-800 active:bg-gray-900 p-2 text-gray-100 bg-black"
utm-tags="?utm_source=AnotherPomodoro&utm_medium=web&utm_content=home"
tabindex="0"
/>
Expand All @@ -93,10 +93,10 @@
</Section>

<!-- Section 2: about Pomodoro and the app -->
<Section ref="section-2" class="snap-center bg-sky-100 justify-center flex flex-col overflow-hidden px-2">
<div class="mt-8 text-sky-900 flex flex-col items-center">
<h2 class="text-5xl font-bold uppercase tracking-tight" v-text="$i18n.t('index.section_whatitdoes.title')" />
<div class="mt-2 text-lg xl:text-xl text-center">
<Section ref="section-2" class="snap-center bg-sky-100 flex flex-col justify-center px-2 overflow-hidden">
<div class="text-sky-900 flex flex-col items-center mt-8">
<h2 class="text-5xl font-bold tracking-tight uppercase" v-text="$i18n.t('index.section_whatitdoes.title')" />
<div class="xl:text-xl mt-2 text-lg text-center">
<client-only>
<i18n path="index.section_whatitdoes.subtitle.main" tag="p">
<b>AnotherPomodoro</b>
Expand All @@ -106,66 +106,66 @@
</div>

<!-- Schedule display imitation -->
<div class="rounded-lg bg-slate-800 p-3 flex flex-row space-x-3 shadow-lg shadow-slate-500/20 mt-16">
<div class="bg-slate-800 shadow-slate-500/20 flex flex-row p-3 mt-16 space-x-3 rounded-lg shadow-lg">
<div :class="['transition duration-500 ring-2 ring-inset ring-transparent w-12 h-12 bg-work rounded-lg', { '!ring-white': section2selectedBox === 1 }]" />
<div :class="['transition duration-500 ring-2 ring-inset ring-transparent w-12 h-12 bg-shortpause rounded-lg', { '!ring-white': section2selectedBox === 2 }]" />
<div :class="['transition duration-500 ring-2 ring-inset ring-transparent w-12 h-12 bg-longpause rounded-lg', { '!ring-white': section2selectedBox === 3 }]" />
</div>

<!-- Schedule cards -->
<div class="mt-4 grid grid-flow-row xl:grid-flow-col xl:auto-cols-auto gap-4 items-start">
<div class="xl:grid-flow-col xl:auto-cols-auto grid items-start grid-flow-row gap-4 mt-4">
<ScheduleCard :title="$i18n.t('index.section_whatitdoes.cards[0].title')" :description="$i18n.t('index.section_whatitdoes.cards[0].description')" :duration="$i18n.t('index.section_whatitdoes.cards[0].duration')" dot-class="bg-work" :class="[{ 'shadow-lg shadow-slate-700/30 !bg-slate-600': section2selectedBox === 1 }]" />

<IconNext class="hidden xl:block self-center" />
<IconNext class="xl:block self-center hidden" />

<ScheduleCard :title="$i18n.t('index.section_whatitdoes.cards[1].title')" :description="$i18n.t('index.section_whatitdoes.cards[1].description')" :duration="$i18n.t('index.section_whatitdoes.cards[1].duration')" dot-class="bg-shortpause" :class="[{ 'shadow-lg shadow-slate-700/30 !bg-slate-600': section2selectedBox === 2 }]" />

<IconNext class="hidden xl:block self-center" />
<IconDots class="hidden xl:block self-center" />
<IconNext class="hidden xl:block self-center" />
<IconNext class="xl:block self-center hidden" />
<IconDots class="xl:block self-center hidden" />
<IconNext class="xl:block self-center hidden" />

<ScheduleCard :title="$i18n.t('index.section_whatitdoes.cards[2].title')" :description="$i18n.t('index.section_whatitdoes.cards[2].description')" :duration="$i18n.t('index.section_whatitdoes.cards[2].duration')" dot-class="bg-longpause" :class="[{ 'shadow-lg shadow-slate-700/30 !bg-slate-600': section2selectedBox === 3 }]" />
</div>
</div>
</Section>

<!-- Section 3: Features -->
<Section ref="section-3" class="snap-center bg-amber-50 justify-center items-center flex flex-col overflow-hidden text-center px-4">
<h2 class="text-5xl font-bold uppercase tracking-tight text-amber-900" v-text="$i18n.t('index.section_features.title')" />
<Section ref="section-3" class="snap-center bg-amber-50 flex flex-col items-center justify-center px-4 overflow-hidden text-center">
<h2 class="text-amber-900 text-5xl font-bold tracking-tight uppercase" v-text="$i18n.t('index.section_features.title')" />

<div class="mt-8 grid grid-cols-2 text-lg xl:text-xl xl:grid-cols-4 grid-flow-row gap-4 xl:gap-8 max-w-5xl">
<div class="xl:text-xl xl:grid-cols-4 xl:gap-8 grid max-w-5xl grid-flow-row grid-cols-2 gap-4 mt-8 text-lg">
<div v-for="(feature, index) in section3.smallFeatures" :key="feature" :class="['transition duration-1000 py-4 px-4 rounded-lg text-gray-900 text-opacity-80 flex flex-col justify-center', { '!text-gray-100 text-opacity-100 bg-slate-800': section3.activeFeature === index }]" v-text="$i18n.t('index.section_features.list.' + feature)" />
</div>
</Section>

<!-- Section 4: FAQ -->
<Section ref="section-4" class="snap-center bg-amber-300 justify-center items-center flex flex-col overflow-hidden text-center">
<h2 class="text-5xl font-bold uppercase tracking-tight text-black" v-text="$i18n.t('index.faq.title')" />
<Section ref="section-4" class="snap-center bg-amber-300 flex flex-col items-center justify-center overflow-hidden text-center">
<h2 class="text-5xl font-bold tracking-tight text-black uppercase" v-text="$i18n.t('index.faq.title')" />

<div class="mt-8 px-4 w-full xl:w-[1280px] xl:h-96 h-[36rem] text-left flex flex-col space-y-2">
<details v-for="(question, i) in faq" :key="'faq-' + i" class="open:bg-gray-50 bg-gray-100 ring-1 ring-transparent open:ring-gray-400 shadow-slate-400/30 open:shadow-lg rounded-lg p-4 w-full transition text-gray-700 open:text-gray-900" :open="openfaq === i" @click.prevent="openfaq = i">
<details v-for="(question, i) in faq" :key="'faq-' + i" class="open:bg-gray-50 ring-1 ring-transparent open:ring-gray-400 shadow-slate-400/30 open:shadow-lg open:text-gray-900 w-full p-4 text-gray-700 transition bg-gray-100 rounded-lg" :open="openfaq === i" @click.prevent="openfaq = i">
<summary class="font-bold cursor-pointer" v-text="$i18n.t('index.faq.accordion.' + question.q +'.q')" />
<div class="mt-2" v-text="$i18n.t('index.faq.accordion.' + question.q + '.a')" />
<div v-if="question.hint" class="mt-2">
<span class="rounded-lg bg-amber-400 text-gray-900 py-1 px-2 font-bold" v-text="$i18n.t('index.faq.hint')" />
<span class="bg-amber-400 px-2 py-1 font-bold text-gray-900 rounded-lg" v-text="$i18n.t('index.faq.hint')" />
{{ $i18n.t('index.faq.accordion.' + question.q + '.hint') }}
</div>
</details>
</div>
</Section>

<!-- Section 5: Support -->
<Section ref="section-5" class="snap-center bg-stone-100 justify-center items-center flex flex-col overflow-hidden text-center px-4">
<h2 class="text-5xl font-bold uppercase tracking-tight text-black leading-tight" v-text="$i18n.t('index.support.title')" />
<Section ref="section-5" class="snap-center bg-stone-100 flex flex-col items-center justify-center px-4 overflow-hidden text-center">
<h2 class="text-5xl font-bold leading-tight tracking-tight text-black uppercase" v-text="$i18n.t('index.support.title')" />

<div class="mt-3 flex flex-col space-y-1">
<div class="flex flex-col mt-3 space-y-1">
<p v-text="$i18n.t('index.support.subtitle[0]')" />
<i18n path="index.support.subtitle[1].base">
<b>{{ $i18n.t('index.support.subtitle[1].action') }}</b>
</i18n>
</div>

<div class="mt-8 flex flex-row space-x-2">
<div class="flex flex-row mt-8 space-x-2">
<SupportButton type="github" default-classes />
<SupportButton type="support" default-classes />
</div>
Expand All @@ -184,9 +184,9 @@
</div>

<template #after>
<div class="absolute bottom-20 xl:bottom-4 flex flex-col justify-center items-center">
<div class="bottom-20 xl:bottom-4 absolute flex flex-col items-center justify-center">
<div class="" v-text="$i18n.t('index.support.credits')" />
<div class="mt-1 px-2 py-1 bg-gray-800 text-gray-50 rounded-lg select-none" v-text="$store.state.version" />
<div class="text-gray-50 px-2 py-1 mt-1 bg-gray-800 rounded-lg select-none" v-text="$store.state.version" />
</div>
</template>
</Section>
Expand All @@ -212,10 +212,7 @@ export default {
mainText: false,
screenshot: false
},
currentSection: 0,
scroll: {
sections: [],
sectionObserver: null,
fabObserver: null
},
section2: {
Expand Down Expand Up @@ -259,42 +256,7 @@ export default {
}
},
watch: {
currentSection (newValue) {
if (this.scroll.sections[newValue]) {
this.scroll.sections[newValue].scrollIntoView({
behavior: 'smooth'
})
}
}
},
mounted () {
const sectionKeys = Object.keys(this.$refs).filter(key => key.startsWith('section-'))
for (const key of sectionKeys) {
this.$refs[key].dataset.scrollkey = this.scroll.sections.length
this.scroll.sections.push(this.$refs[key])
}
this.scroll.sectionObserver = new IntersectionObserver((entries) => {
// Find section that was scrolled into view
for (const item of entries) {
if (item.isIntersecting) {
this.currentSection = Number.parseInt(item.target.dataset.scrollkey)
break
}
}
}, {
root: this.$el,
threshold: 0.1
})
// Register the scroll observer for all sections
for (const section of this.scroll.sections) {
this.scroll.sectionObserver.observe(section)
}
this.$nextTick(() => {
// Float in the app title and icon
this.loading.mainText = true
Expand Down Expand Up @@ -332,25 +294,11 @@ export default {
if (this.scroll.fabObserver) {
this.scroll.fabObserver.disconnect()
}
if (this.scroll.sectionObserver) {
this.scroll.sectionObserver.disconnect()
}
},
methods: {
setIntersecting (value) {
this.showFAB = value
},
handleScroll (event) {
if (event.deltaY > 0) {
// scroll downwards
this.currentSection = Math.min(this.currentSection + 1, this.scroll.sections.length - 1)
} else if (event.deltaY < 0) {
// scroll upwards
this.currentSection = Math.max(this.currentSection - 1, 0)
}
}
}
}
Expand Down

0 comments on commit 81c85f7

Please sign in to comment.