From 4e901c714c65987f5969af00e9570e7389503f11 Mon Sep 17 00:00:00 2001 From: Mike DelGaudio <43451174+mikedelgaudio@users.noreply.github.com> Date: Wed, 25 Aug 2021 04:08:22 -0400 Subject: [PATCH] [RFC] Add Three Homepage Sections (#1112) --- .../Intro/SlideOnScroll/index.tsx | 51 +++++++ .../Intro/imgs/info-content/secure.svg | 1 + .../Intro/imgs/info-content/simple.svg | 1 + .../Intro/imgs/info-content/small.svg | 1 + src/shared/prerendered-app/Intro/index.tsx | 142 +++++++++++++++--- src/shared/prerendered-app/Intro/style.css | 113 +++++++++++++- src/static-build/pages/index/index.tsx | 1 + static-build-tsconfig.json | 2 +- 8 files changed, 285 insertions(+), 27 deletions(-) create mode 100644 src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx create mode 100644 src/shared/prerendered-app/Intro/imgs/info-content/secure.svg create mode 100644 src/shared/prerendered-app/Intro/imgs/info-content/simple.svg create mode 100644 src/shared/prerendered-app/Intro/imgs/info-content/small.svg diff --git a/src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx b/src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx new file mode 100644 index 00000000..93b24fbe --- /dev/null +++ b/src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx @@ -0,0 +1,51 @@ +import { h, Component, RenderableProps } from 'preact'; + +interface Props {} +interface State {} + +export default class SlideOnScroll extends Component { + private observer?: IntersectionObserver; + + componentDidMount() { + if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; + + const base = this.base as HTMLElement; + let wasOutOfView = false; + + this.observer = new IntersectionObserver( + (entries, observer) => { + for (const entry of entries) { + if (!entry.isIntersecting) { + wasOutOfView = true; + base.style.opacity = '0'; + return; + } + + // Only transition in if the element was at some point out of view. + if (wasOutOfView) { + base.style.opacity = ''; + base.animate( + { offset: 0, opacity: '0', transform: 'translateY(40px)' }, + { duration: 300, easing: 'ease' }, + ); + } + observer.unobserve(entry.target); + } + }, + { threshold: 0.2 }, + ); + + this.observer.observe(base); + } + + componentWillUnmount() { + // Have to manually disconnect due to memory leaks in browsers. + // One day we'll be able to remove this, and the private property. + // https://twitter.com/jaffathecake/status/1405437361643790337 + this.observer!.disconnect(); + } + + render({ children }: RenderableProps) { + return
{children}
; + } +} diff --git a/src/shared/prerendered-app/Intro/imgs/info-content/secure.svg b/src/shared/prerendered-app/Intro/imgs/info-content/secure.svg new file mode 100644 index 00000000..214ef3cc --- /dev/null +++ b/src/shared/prerendered-app/Intro/imgs/info-content/secure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/shared/prerendered-app/Intro/imgs/info-content/simple.svg b/src/shared/prerendered-app/Intro/imgs/info-content/simple.svg new file mode 100644 index 00000000..1a8b2840 --- /dev/null +++ b/src/shared/prerendered-app/Intro/imgs/info-content/simple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/shared/prerendered-app/Intro/imgs/info-content/small.svg b/src/shared/prerendered-app/Intro/imgs/info-content/small.svg new file mode 100644 index 00000000..df9b4b77 --- /dev/null +++ b/src/shared/prerendered-app/Intro/imgs/info-content/small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/shared/prerendered-app/Intro/index.tsx b/src/shared/prerendered-app/Intro/index.tsx index 3174c833..b777a4e3 100644 --- a/src/shared/prerendered-app/Intro/index.tsx +++ b/src/shared/prerendered-app/Intro/index.tsx @@ -10,12 +10,16 @@ import deviceScreen from 'url:./imgs/demos/demo-device-screen.png'; import largePhotoIcon from 'url:./imgs/demos/icon-demo-large-photo.jpg'; import artworkIcon from 'url:./imgs/demos/icon-demo-artwork.jpg'; import deviceScreenIcon from 'url:./imgs/demos/icon-demo-device-screen.jpg'; +import smallSectionAsset from 'url:./imgs/info-content/small.svg'; +import simpleSectionAsset from 'url:./imgs/info-content/simple.svg'; +import secureSectionAsset from 'url:./imgs/info-content/secure.svg'; import logoIcon from 'url:./imgs/demos/icon-demo-logo.png'; import logoWithText from 'url:./imgs/logo-with-text.svg'; import * as style from './style.css'; import type SnackBarElement from 'shared/custom-els/snack-bar'; import 'shared/custom-els/snack-bar'; import { startBlobs } from './blob-anim/meta'; +import SlideOnScroll from './SlideOnScroll'; const demos = [ { @@ -336,37 +340,125 @@ export default class Intro extends Component { -
+ + + +
+
+ +
+
+

Small

+

+ Smaller images mean faster load times. Squoosh can reduce + file size and maintain high quality. +

+
+
+ silhouette of a large 1.4 megabyte image shrunk into a smaller 80 kilobyte image +
+
+
+
+
+ +
+
+ +
+
+

Simple

+

+ Open your image, inspect the differences, then save + instantly. Feeling adventurous? Adjust the settings for even + smaller files. +

+
+
+ grid of multiple shrunk images displaying various options +
+
+
+
+
+ +
+
+ +
+
+

Secure

+

+ Worried about privacy? Images never leave your device since + Squoosh does all the work locally. +

+
+
+ silhouette of a cloud with a 'no' symbol on top +
+
+
+
+
+ + {beforeInstallEvent && (