[RFC] Add Three Homepage Sections (#1112)
This commit is contained in:
51
src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx
Normal file
51
src/shared/prerendered-app/Intro/SlideOnScroll/index.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { h, Component, RenderableProps } from 'preact';
|
||||
|
||||
interface Props {}
|
||||
interface State {}
|
||||
|
||||
export default class SlideOnScroll extends Component<Props, State> {
|
||||
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<Props>) {
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<svg width="498" height="333" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M401.17 125.52C387.072 53.923 324.253.173 248.787.173c-59.916 0-111.954 34.035-137.869 83.841C48.513 90.655 0 143.574 0 207.7c0 68.692 55.77 124.516 124.394 124.516h269.519c57.221 0 103.662-46.486 103.662-103.763 0-54.787-42.502-99.198-96.405-102.933z" fill="#91D3FF" fill-opacity=".3"/><path d="M187.247 121.321l-3.987-3.987-3.481 4.434c-11.519 14.67-18.366 33.15-18.366 53.242 0 48.003 38.882 86.885 86.885 86.885 20.091 0 38.572-6.848 53.242-18.366l4.434-3.482-3.987-3.986-114.74-114.74zM309.348 228.7l3.987 3.986 3.481-4.434c11.519-14.669 18.366-33.15 18.366-53.242 0-48.002-38.882-86.884-86.884-86.884-20.092 0-38.573 6.847-53.242 18.365l-4.435 3.482 3.987 3.986L309.348 228.7zm-158.406-53.69c0-53.739 43.617-97.355 97.356-97.355 53.738 0 97.355 43.616 97.355 97.355 0 53.739-43.617 97.356-97.355 97.356-53.739 0-97.356-43.617-97.356-97.356z" fill="#FF3385" stroke="#FF3385" stroke-width="10"/></svg>
|
After Width: | Height: | Size: 991 B |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.2 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.4 KiB |
@ -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<Props, State> {
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class={style.footer}>
|
||||
|
||||
<div class={style.bottomWave}>
|
||||
<svg viewBox="0 0 1920 79" class={style.topWave}>
|
||||
<path
|
||||
d="M0 59l64-11c64-11 192-34 320-43s256-5 384 4 256 23 384 34 256 21 384 14 256-30 320-41l64-11v94H0z"
|
||||
class={style.footerWave}
|
||||
class={style.infoWave}
|
||||
/>
|
||||
</svg>
|
||||
<div class={style.contentPadding}>
|
||||
<footer class={style.footerItems}>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/blob/dev/README.md#privacy"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli"
|
||||
>
|
||||
Squoosh CLI
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLinkWithLogo}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh"
|
||||
>
|
||||
<img src={githubLogo} alt="" width="10" height="10" />
|
||||
Source on Github
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class={style.info}>
|
||||
<div class={style.infoContainer}>
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Small</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Smaller images mean faster load times. Squoosh can reduce
|
||||
file size and maintain high quality.
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
<img
|
||||
class={style.infoImg}
|
||||
src={smallSectionAsset}
|
||||
alt="silhouette of a large 1.4 megabyte image shrunk into a smaller 80 kilobyte image"
|
||||
width="536"
|
||||
height="522"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SlideOnScroll>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class={style.info}>
|
||||
<div class={style.infoContainer}>
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Simple</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Open your image, inspect the differences, then save
|
||||
instantly. Feeling adventurous? Adjust the settings for even
|
||||
smaller files.
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
<img
|
||||
class={style.infoImg}
|
||||
src={simpleSectionAsset}
|
||||
alt="grid of multiple shrunk images displaying various options"
|
||||
width="538"
|
||||
height="384"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SlideOnScroll>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class={style.info}>
|
||||
<div class={style.infoContainer}>
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Secure</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Worried about privacy? Images never leave your device since
|
||||
Squoosh does all the work locally.
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
<img
|
||||
class={style.infoImg}
|
||||
src={secureSectionAsset}
|
||||
alt="silhouette of a cloud with a 'no' symbol on top"
|
||||
width="498"
|
||||
height="333"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SlideOnScroll>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class={style.footer}>
|
||||
<div class={style.footerContainer}>
|
||||
<svg viewBox="0 0 1920 79" class={style.topWave}>
|
||||
<path
|
||||
d="M0 59l64-11c64-11 192-34 320-43s256-5 384 4 256 23 384 34 256 21 384 14 256-30 320-41l64-11v94H0z"
|
||||
class={style.footerWave}
|
||||
/>
|
||||
</svg>
|
||||
<div class={style.footerPadding}>
|
||||
<footer class={style.footerItems}>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/blob/dev/README.md#privacy"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli"
|
||||
>
|
||||
Squoosh CLI
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLinkWithLogo}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh"
|
||||
>
|
||||
<img src={githubLogo} alt="" width="10" height="10" />
|
||||
Source on Github
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{beforeInstallEvent && (
|
||||
<button class={style.installBtn} onClick={this.onInstallClick}>
|
||||
Install
|
||||
|
@ -118,7 +118,114 @@
|
||||
fill: var(--light-blue);
|
||||
}
|
||||
|
||||
.bottom-wave {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: var(--white);
|
||||
position: relative;
|
||||
padding: 5em 2em;
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
padding: 5em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1em;
|
||||
|
||||
grid-template-areas:
|
||||
'text'
|
||||
'img';
|
||||
|
||||
@media (min-width: 712px) {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-areas: 'text img';
|
||||
|
||||
.info:nth-child(even) & {
|
||||
grid-template-areas: 'img text';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-title {
|
||||
color: var(--pink);
|
||||
font-size: 3em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-caption {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.75;
|
||||
margin: 1em 0 0.5em 0;
|
||||
}
|
||||
|
||||
.info-link {
|
||||
font-size: 1.25em;
|
||||
text-underline-offset: 0.25em;
|
||||
color: var(--off-black);
|
||||
transition: color 400ms ease-in-out;
|
||||
margin-top: 1em;
|
||||
&:hover {
|
||||
color: var(--dim-blue);
|
||||
}
|
||||
}
|
||||
|
||||
.info-text-wrapper {
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
max-width: 27em;
|
||||
justify-self: center;
|
||||
grid-area: text;
|
||||
|
||||
@media (min-width: 712px) {
|
||||
justify-self: start;
|
||||
.info:nth-child(even) & {
|
||||
text-align: right;
|
||||
justify-self: end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-img-wrapper {
|
||||
grid-area: img;
|
||||
}
|
||||
|
||||
.info-img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
margin: 0 0 0 auto;
|
||||
|
||||
.info:nth-child(even) & {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-wave {
|
||||
fill: var(--white);
|
||||
}
|
||||
|
||||
.footer {
|
||||
background: var(--white);
|
||||
padding-top: 5em;
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
position: relative;
|
||||
background: var(--light-gray);
|
||||
}
|
||||
@ -128,7 +235,11 @@
|
||||
}
|
||||
|
||||
.content-padding {
|
||||
padding: 2rem;
|
||||
padding: 2em 0;
|
||||
}
|
||||
|
||||
.footer-padding {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.footer-items {
|
||||
|
@ -59,6 +59,7 @@ const Index: FunctionalComponent<Props> = () => (
|
||||
<link rel="shortcut icon" href={favicon} />
|
||||
<meta name="theme-color" content="#ff3385" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="canonical" href={siteOrigin} />
|
||||
<style
|
||||
dangerouslySetInnerHTML={{ __html: escapeStyleScriptContent(baseCss) }}
|
||||
/>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"extends": "./generic-tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["esnext", "dom"],
|
||||
"lib": ["esnext", "dom", "dom.iterable"],
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/shared/**/*", "src/static-build/**/*"]
|
||||
|
Reference in New Issue
Block a user