# Conflicts:
#	codecs/cpp.Dockerfile
#	codecs/imagequant/example.html
#	codecs/webp/dec/webp_dec.d.ts
#	codecs/webp/dec/webp_dec.js
#	codecs/webp/dec/webp_dec.wasm
#	codecs/webp/enc/webp_enc.d.ts
#	codecs/webp/enc/webp_enc.js
#	codecs/webp/enc/webp_enc.wasm
#	package-lock.json
#	package.json
#	src/codecs/tiny.webp
#	src_old/codecs/encoders.ts
#	src_old/codecs/processor-worker/tiny.avif
#	src_old/codecs/processor-worker/tiny.webp
#	src_old/codecs/tiny.webp
#	src_old/components/compress/index.tsx
#	src_old/lib/util.ts
#	src_old/sw/util.ts
This commit is contained in:
Jake Archibald
2020-09-16 09:59:24 +01:00
parent dfee848a39
commit a6477b82fc
202 changed files with 10435 additions and 16953 deletions

View File

@@ -0,0 +1,62 @@
import * as styles from './styles.css';
/**
* A simple spinner. This custom element has no JS API. Just put it in the document, and it'll
* spin. You can configure the following using CSS custom properties:
*
* --size: Size of the spinner element (it's always square). Default: 28px.
* --color: Color of the spinner. Default: #4285f4.
* --stroke-width: Width of the stroke of the spinner. Default: 3px.
* --delay: Once the spinner enters the DOM, how long until it shows. This prevents the spinner
* appearing on the screen for short operations. Default: 300ms.
*/
export default class LoadingSpinner extends HTMLElement {
private _delayTimeout: number = 0;
constructor() {
super();
// Ideally we'd use shadow DOM here, but we're targeting browsers without shadow DOM support.
// You can't set attributes/content in a custom element constructor, so I'm waiting a microtask.
Promise.resolve().then(() => {
this.style.display = 'none';
this.innerHTML =
'' +
`<div class="${styles.spinnerContainer}">` +
`<div class="${styles.spinnerLayer}">` +
`<div class="${styles.spinnerCircleClipper} ${styles.spinnerLeft}">` +
`<div class="${styles.spinnerCircle}"></div>` +
'</div>' +
`<div class="${styles.spinnerGapPatch}">` +
`<div class="${styles.spinnerCircle}"></div>` +
'</div>' +
`<div class="${styles.spinnerCircleClipper} ${styles.spinnerRight}">` +
`<div class="${styles.spinnerCircle}"></div>` +
'</div>' +
'</div>' +
'</div>';
});
}
disconnectedCallback() {
this.style.display = 'none';
clearTimeout(this._delayTimeout);
}
connectedCallback() {
const delayStr = getComputedStyle(this).getPropertyValue('--delay').trim();
let delayNum = parseFloat(delayStr);
// If seconds…
if (/\ds$/.test(delayStr)) {
// Convert to ms.
delayNum *= 1000;
}
this._delayTimeout = self.setTimeout(() => {
this.style.display = '';
}, delayNum);
}
}
customElements.define('loading-spinner', LoadingSpinner);

View File

@@ -0,0 +1,7 @@
interface LoadingSpinner extends JSX.HTMLAttributes {}
declare namespace JSX {
interface IntrinsicElements {
'loading-spinner': LoadingSpinner;
}
}

View File

@@ -0,0 +1,158 @@
@keyframes spinner-left-spin {
from {
transform: rotate(130deg);
}
50% {
transform: rotate(-5deg);
}
to {
transform: rotate(130deg);
}
}
@keyframes spinner-right-spin {
from {
transform: rotate(-130deg);
}
50% {
transform: rotate(5deg);
}
to {
transform: rotate(-130deg);
}
}
@keyframes spinner-fade-out {
to {
opacity: 0;
}
}
@keyframes spinner-container-rotate {
to {
transform: rotate(360deg);
}
}
@keyframes spinner-fill-unfill-rotate {
12.5% {
transform: rotate(135deg);
} /* 0.5 * ARCSIZE */
25% {
transform: rotate(270deg);
} /* 1 * ARCSIZE */
37.5% {
transform: rotate(405deg);
} /* 1.5 * ARCSIZE */
50% {
transform: rotate(540deg);
} /* 2 * ARCSIZE */
62.5% {
transform: rotate(675deg);
} /* 2.5 * ARCSIZE */
75% {
transform: rotate(810deg);
} /* 3 * ARCSIZE */
87.5% {
transform: rotate(945deg);
} /* 3.5 * ARCSIZE */
to {
transform: rotate(1080deg);
} /* 4 * ARCSIZE */
}
loading-spinner {
--size: 28px;
--color: #4285f4;
--stroke-width: 3px;
--delay: 300ms;
pointer-events: none;
display: inline-block;
position: relative;
width: var(--size);
height: var(--size);
border-color: var(--color);
}
loading-spinner .spinner-circle {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-sizing: border-box;
height: 100%;
width: 200%;
border-width: var(--stroke-width);
border-style: solid;
border-color: inherit;
border-bottom-color: transparent !important;
border-radius: 50%;
}
/*
Patch the gap that appear between the two adjacent div.circle-clipper while the
spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*/
loading-spinner .spinner-gap-patch {
position: absolute;
box-sizing: border-box;
top: 0;
left: 45%;
width: 10%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
loading-spinner .spinner-gap-patch .spinner-circle {
width: 1000%;
left: -450%;
}
loading-spinner .spinner-circle-clipper {
display: inline-block;
position: relative;
width: 50%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
loading-spinner .spinner-left .spinner-circle {
border-right-color: transparent !important;
transform: rotate(129deg);
animation: spinner-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
}
loading-spinner .spinner-right .spinner-circle {
left: -100%;
border-left-color: transparent !important;
transform: rotate(-129deg);
animation: spinner-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite
both;
}
loading-spinner.spinner-fadeout {
animation: spinner-fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
loading-spinner .spinner-container {
width: 100%;
height: 100%;
border-color: inherit;
/* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
animation: spinner-container-rotate 1568ms linear infinite;
}
loading-spinner .spinner-layer {
position: absolute;
width: 100%;
height: 100%;
border-color: inherit;
/* durations: 4 * ARCTIME */
animation: spinner-fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1)
infinite both;
}