chore(site-2): Run prettier

pull/8593/head
Puru Vijay 2 years ago
parent 21a0141b8c
commit f3396cfd4c

@ -254,11 +254,11 @@ All except `scrollX` and `scrollY` are readonly.
## `<svelte:document>` ## `<svelte:document>`
```svelte ```svelte
<svelte:document on:event={handler}/> <svelte:document on:event={handler} />
``` ```
```svelte ```svelte
<svelte:document bind:prop={value}/> <svelte:document bind:prop={value} />
``` ```
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](/docs/element-directives#use-action) on `document`. Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](/docs/element-directives#use-action) on `document`.
@ -266,10 +266,7 @@ Similarly to `<svelte:window>`, this element allows you to add listeners to even
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element. As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
```svelte ```svelte
<svelte:document <svelte:document on:visibilitychange={handleVisibilityChange} use:someAction />
on:visibilitychange={handleVisibilityChange}
use:someAction
/>
``` ```
You can also bind to the following properties: You can also bind to the following properties:

@ -58,11 +58,11 @@ When constructing a custom element, you can tailor several aspects by defining `
```svelte ```svelte
<svelte:options <svelte:options
customElement={{ customElement={{
tag: "custom-element", tag: 'custom-element',
shadow: "none", shadow: 'none',
props: { props: {
name: { reflect: true, type: "Number", attribute: "element-index" }, name: { reflect: true, type: 'Number', attribute: 'element-index' }
}, }
}} }}
/> />
@ -75,7 +75,7 @@ When constructing a custom element, you can tailor several aspects by defining `
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of: Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:
- Styles are *encapsulated*, rather than merely *scoped* (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier - Styles are _encapsulated_, rather than merely _scoped_ (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier
- Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string - Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
- Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads - Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
- In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times - In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times

@ -4,4 +4,4 @@
</script> </script>
<!-- {src} is short for src={src} --> <!-- {src} is short for src={src} -->
<img {src} alt="{name} dancing"> <img {src} alt="{name} dancing" />

@ -3,7 +3,7 @@
</script> </script>
<p>These styles...</p> <p>These styles...</p>
<Nested/> <Nested />
<style> <style>
p { p {

@ -7,5 +7,6 @@
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'} Clicked {count}
{count === 1 ? 'time' : 'times'}
</button> </button>

@ -12,5 +12,6 @@
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'} Clicked {count}
{count === 1 ? 'time' : 'times'}
</button> </button>

@ -2,4 +2,4 @@
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
</script> </script>
<Nested answer={42}/> <Nested answer={42} />

@ -2,5 +2,5 @@
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
</script> </script>
<Nested answer={42}/> <Nested answer={42} />
<Nested/> <Nested />

@ -9,4 +9,4 @@
}; };
</script> </script>
<Info {...pkg}/> <Info {...pkg} />

@ -6,7 +6,7 @@
</script> </script>
<p> <p>
The <code>{name}</code> package is {speed} fast. The <code>{name}</code> package is {speed} fast. Download version {version} from
Download version {version} from <a href="https://www.npmjs.com/package/{name}">npm</a> <a href="https://www.npmjs.com/package/{name}">npm</a>
and <a href={website}>learn more here</a> and <a href={website}>learn more here</a>
</p> </p>

@ -7,13 +7,9 @@
</script> </script>
{#if user.loggedIn} {#if user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log out </button>
Log out
</button>
{/if} {/if}
{#if !user.loggedIn} {#if !user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log in </button>
Log in
</button>
{/if} {/if}

@ -7,11 +7,7 @@
</script> </script>
{#if user.loggedIn} {#if user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log out </button>
Log out
</button>
{:else} {:else}
<button on:click={toggle}> <button on:click={toggle}> Log in </button>
Log in
</button>
{/if} {/if}

@ -14,22 +14,20 @@
} }
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}> Remove first thing </button>
Remove first thing
</button>
<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em"> <div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em">
<div> <div>
<h2>Keyed</h2> <h2>Keyed</h2>
{#each things as thing (thing.id)} {#each things as thing (thing.id)}
<Thing current={thing.color}/> <Thing current={thing.color} />
{/each} {/each}
</div> </div>
<div> <div>
<h2>Unkeyed</h2> <h2>Unkeyed</h2>
{#each things as thing} {#each things as thing}
<Thing current={thing.color}/> <Thing current={thing.color} />
{/each} {/each}
</div> </div>
</div> </div>

@ -17,9 +17,7 @@
} }
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}> generate random number </button>
generate random number
</button>
{#await promise} {#await promise}
<p>...waiting</p> <p>...waiting</p>

@ -12,5 +12,8 @@
</div> </div>
<style> <style>
div { width: 100%; height: 100%; } div {
width: 100%;
height: 100%;
}
</style> </style>

@ -2,10 +2,13 @@
let m = { x: 0, y: 0 }; let m = { x: 0, y: 0 };
</script> </script>
<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}"> <div on:mousemove={(e) => (m = { x: e.clientX, y: e.clientY })}>
The mouse position is {m.x} x {m.y} The mouse position is {m.x} x {m.y}
</div> </div>
<style> <style>
div { width: 100%; height: 100%; } div {
width: 100%;
height: 100%;
}
</style> </style>

@ -1,9 +1,7 @@
<script> <script>
function handleClick() { function handleClick() {
alert('no more alerts') alert('no more alerts');
} }
</script> </script>
<button on:click|once={handleClick}> <button on:click|once={handleClick}> Click me </button>
Click me
</button>

@ -6,4 +6,4 @@
} }
</script> </script>
<Inner on:message={handleMessage}/> <Inner on:message={handleMessage} />

@ -10,6 +10,4 @@
} }
</script> </script>
<button on:click={sayHello}> <button on:click={sayHello}> Click to say hello </button>
Click to say hello
</button>

@ -6,4 +6,4 @@
} }
</script> </script>
<Outer on:message={handleMessage}/> <Outer on:message={handleMessage} />

@ -10,6 +10,4 @@
} }
</script> </script>
<button on:click={sayHello}> <button on:click={sayHello}> Click to say hello </button>
Click to say hello
</button>

@ -2,4 +2,4 @@
import Inner from './Inner.svelte'; import Inner from './Inner.svelte';
</script> </script>
<Inner on:message/> <Inner on:message />

@ -6,4 +6,4 @@
} }
</script> </script>
<CustomButton on:click={handleClick}/> <CustomButton on:click={handleClick} />

@ -1,6 +1,4 @@
<button on:click> <button on:click> Click me </button>
Click me
</button>
<style> <style>
button { button {

@ -2,5 +2,5 @@
let name = ''; let name = '';
</script> </script>
<input bind:value={name} placeholder="enter your name"> <input bind:value={name} placeholder="enter your name" />
<p>Hello {name || 'stranger'}!</p> <p>Hello {name || 'stranger'}!</p>

@ -4,13 +4,13 @@
</script> </script>
<label> <label>
<input type=number bind:value={a} min=0 max=10> <input type="number" bind:value={a} min="0" max="10" />
<input type=range bind:value={a} min=0 max=10> <input type="range" bind:value={a} min="0" max="10" />
</label> </label>
<label> <label>
<input type=number bind:value={b} min=0 max=10> <input type="number" bind:value={b} min="0" max="10" />
<input type=range bind:value={b} min=0 max=10> <input type="range" bind:value={b} min="0" max="10" />
</label> </label>
<p>{a} + {b} = {a + b}</p> <p>{a} + {b} = {a + b}</p>

@ -3,7 +3,7 @@
</script> </script>
<label> <label>
<input type=checkbox bind:checked={yes}> <input type="checkbox" bind:checked={yes} />
Yes! Send me regular email spam Yes! Send me regular email spam
</label> </label>
@ -13,6 +13,4 @@
<p>You must opt-in to continue. If you're not paying, you're the product.</p> <p>You must opt-in to continue. If you're not paying, you're the product.</p>
{/if} {/if}
<button disabled={!yes}> <button disabled={!yes}> Subscribe </button>
Subscribe
</button>

@ -2,11 +2,7 @@
let scoops = 1; let scoops = 1;
let flavours = ['Mint choc chip']; let flavours = ['Mint choc chip'];
let menu = [ let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
function join(flavours) { function join(flavours) {
if (flavours.length === 1) return flavours[0]; if (flavours.length === 1) return flavours[0];
@ -17,17 +13,17 @@
<h2>Size</h2> <h2>Size</h2>
<label> <label>
<input type=radio bind:group={scoops} value={1}> <input type="radio" bind:group={scoops} value={1} />
One scoop One scoop
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={2}> <input type="radio" bind:group={scoops} value={2} />
Two scoops Two scoops
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={3}> <input type="radio" bind:group={scoops} value={3} />
Three scoops Three scoops
</label> </label>
@ -35,7 +31,7 @@
{#each menu as flavour} {#each menu as flavour}
<label> <label>
<input type=checkbox bind:group={flavours} value={flavour}> <input type="checkbox" bind:group={flavours} value={flavour} />
{flavour} {flavour}
</label> </label>
{/each} {/each}
@ -46,7 +42,8 @@
<p>Can't order more flavours than scoops!</p> <p>Can't order more flavours than scoops!</p>
{:else} {:else}
<p> <p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'} You ordered {scoops}
{scoops === 1 ? 'scoop' : 'scoops'}
of {join(flavours)} of {join(flavours)}
</p> </p>
{/if} {/if}

@ -3,10 +3,13 @@
let text = `Some words are *italic*, some are **bold**`; let text = `Some words are *italic*, some are **bold**`;
</script> </script>
<textarea bind:value={text}></textarea> <textarea bind:value={text} />
{@html marked(text)} {@html marked(text)}
<style> <style>
textarea { width: 100%; height: 200px; } textarea {
width: 100%;
height: 200px;
}
</style> </style>

@ -13,25 +13,14 @@
</script> </script>
<label for="avatar">Upload a picture:</label> <label for="avatar">Upload a picture:</label>
<input <input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
<label for="many">Upload multiple files of any type:</label> <label for="many">Upload multiple files of any type:</label>
<input <input bind:files id="many" multiple type="file" />
bind:files
id="many"
multiple
type="file"
/>
{#if files} {#if files}
<h2>Selected files:</h2> <h2>Selected files:</h2>
{#each Array.from(files) as file} {#each Array.from(files) as file}
<p>{file.name} ({file.size} bytes) </p> <p>{file.name} ({file.size} bytes)</p>
{/each} {/each}
{/if} {/if}

@ -17,7 +17,7 @@
<h2>Insecurity questions</h2> <h2>Insecurity questions</h2>
<form on:submit|preventDefault={handleSubmit}> <form on:submit|preventDefault={handleSubmit}>
<select bind:value={selected} on:change="{() => answer = ''}"> <select bind:value={selected} on:change={() => (answer = '')}>
{#each questions as question} {#each questions as question}
<option value={question}> <option value={question}>
{question.text} {question.text}
@ -25,15 +25,17 @@
{/each} {/each}
</select> </select>
<input bind:value={answer}> <input bind:value={answer} />
<button disabled={!answer} type=submit> <button disabled={!answer} type="submit"> Submit </button>
Submit
</button>
</form> </form>
<p>selected question {selected ? selected.id : '[waiting...]'}</p> <p>selected question {selected ? selected.id : '[waiting...]'}</p>
<style> <style>
input { display: block; width: 500px; max-width: 100%; } input {
display: block;
width: 500px;
max-width: 100%;
}
</style> </style>

@ -2,11 +2,7 @@
let scoops = 1; let scoops = 1;
let flavours = ['Mint choc chip']; let flavours = ['Mint choc chip'];
let menu = [ let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
function join(flavours) { function join(flavours) {
if (flavours.length === 1) return flavours[0]; if (flavours.length === 1) return flavours[0];
@ -17,17 +13,17 @@
<h2>Size</h2> <h2>Size</h2>
<label> <label>
<input type=radio bind:group={scoops} value={1}> <input type="radio" bind:group={scoops} value={1} />
One scoop One scoop
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={2}> <input type="radio" bind:group={scoops} value={2} />
Two scoops Two scoops
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={3}> <input type="radio" bind:group={scoops} value={3} />
Three scoops Three scoops
</label> </label>
@ -47,7 +43,8 @@
<p>Can't order more flavours than scoops!</p> <p>Can't order more flavours than scoops!</p>
{:else} {:else}
<p> <p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'} You ordered {scoops}
{scoops === 1 ? 'scoop' : 'scoops'}
of {join(flavours)} of {join(flavours)}
</p> </p>
{/if} {/if}

@ -10,35 +10,24 @@
} }
function clear() { function clear() {
todos = todos.filter(t => !t.done); todos = todos.filter((t) => !t.done);
} }
$: remaining = todos.filter(t => !t.done).length; $: remaining = todos.filter((t) => !t.done).length;
</script> </script>
<h1>Todos</h1> <h1>Todos</h1>
{#each todos as todo} {#each todos as todo}
<div> <div>
<input <input type="checkbox" bind:checked={todo.done} />
type=checkbox
bind:checked={todo.done} <input placeholder="What needs to be done?" bind:value={todo.text} disabled={todo.done} />
>
<input
placeholder="What needs to be done?"
bind:value={todo.text}
disabled={todo.done}
>
</div> </div>
{/each} {/each}
<p>{remaining} remaining</p> <p>{remaining} remaining</p>
<button on:click={add}> <button on:click={add}> Add new </button>
Add new
</button>
<button on:click={clear}> <button on:click={clear}> Clear completed </button>
Clear completed
</button>

@ -14,7 +14,7 @@
// Make the controls visible, but fade out after // Make the controls visible, but fade out after
// 2.5 seconds of inactivity // 2.5 seconds of inactivity
clearTimeout(showControlsTimeout); clearTimeout(showControlsTimeout);
showControlsTimeout = setTimeout(() => showControls = false, 2500); showControlsTimeout = setTimeout(() => (showControls = false), 2500);
showControls = true; showControls = true;
if (!duration) return; // video not loaded yet if (!duration) return; // video not loaded yet
@ -22,7 +22,7 @@
const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
const { left, right } = this.getBoundingClientRect(); const { left, right } = this.getBoundingClientRect();
time = duration * (clientX - left) / (right - left); time = (duration * (clientX - left)) / (right - left);
} }
// we can't rely on the built-in click event, because it fires // we can't rely on the built-in click event, because it fires
@ -62,12 +62,13 @@
on:mouseup={handleMouseup} on:mouseup={handleMouseup}
bind:currentTime={time} bind:currentTime={time}
bind:duration bind:duration
bind:paused> bind:paused
<track kind="captions"/> >
<track kind="captions" />
</video> </video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}"> <div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/> <progress value={time / duration || 0} />
<div class="info"> <div class="info">
<span class="time">{format(time)}</span> <span class="time">{format(time)}</span>
@ -107,7 +108,9 @@
width: 3em; width: 3em;
} }
.time:last-child { text-align: right } .time:last-child {
text-align: right;
}
progress { progress {
display: block; display: block;
@ -118,11 +121,11 @@
} }
progress::-webkit-progress-bar { progress::-webkit-progress-bar {
background-color: rgba(0,0,0,0.2); background-color: rgba(0, 0, 0, 0.2);
} }
progress::-webkit-progress-value { progress::-webkit-progress-value {
background-color: rgba(255,255,255,0.6); background-color: rgba(255, 255, 255, 0.6);
} }
video { video {

@ -5,8 +5,8 @@
let text = 'edit me'; let text = 'edit me';
</script> </script>
<input type=range bind:value={size}> <input type="range" bind:value={size} />
<input bind:value={text}> <input bind:value={text} />
<p>size: {w}px x {h}px</p> <p>size: {w}px x {h}px</p>
@ -15,6 +15,10 @@
</div> </div>
<style> <style>
input { display: block; } input {
div { display: inline-block; } display: block;
}
div {
display: inline-block;
}
</style> </style>

@ -15,12 +15,12 @@
for (let p = 0; p < imageData.data.length; p += 4) { for (let p = 0; p < imageData.data.length; p += 4) {
const i = p / 4; const i = p / 4;
const x = i % canvas.width; const x = i % canvas.width;
const y = i / canvas.height >>> 0; const y = (i / canvas.height) >>> 0;
const t = window.performance.now(); const t = window.performance.now();
const r = 64 + (128 * x / canvas.width) + (64 * Math.sin(t / 1000)); const r = 64 + (128 * x) / canvas.width + 64 * Math.sin(t / 1000);
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1400)); const g = 64 + (128 * y) / canvas.height + 64 * Math.cos(t / 1400);
const b = 128; const b = 128;
imageData.data[p + 0] = r; imageData.data[p + 0] = r;
@ -30,7 +30,7 @@
} }
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
}()); })();
return () => { return () => {
cancelAnimationFrame(frame); cancelAnimationFrame(frame);
@ -38,11 +38,7 @@
}); });
</script> </script>
<canvas <canvas bind:this={canvas} width={32} height={32} />
bind:this={canvas}
width={32}
height={32}
></canvas>
<style> <style>
canvas { canvas {

@ -11,4 +11,4 @@
<h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1> <h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1>
<Keypad bind:value={pin} on:submit={handleSubmit}/> <Keypad bind:value={pin} on:submit={handleSubmit} />

@ -5,8 +5,8 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const select = num => () => value += num; const select = (num) => () => (value += num);
const clear = () => value = ''; const clear = () => (value = '');
const submit = () => dispatch('submit'); const submit = () => dispatch('submit');
</script> </script>
@ -31,10 +31,10 @@
display: grid; display: grid;
grid-template-columns: repeat(3, 5em); grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em); grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em grid-gap: 0.5em;
} }
button { button {
margin: 0 margin: 0;
} }
</style> </style>

@ -14,7 +14,7 @@
<div class="photos"> <div class="photos">
{#each photos as photo} {#each photos as photo}
<figure> <figure>
<img src={photo.thumbnailUrl} alt={photo.title}> <img src={photo.thumbnailUrl} alt={photo.title} />
<figcaption>{photo.title}</figcaption> <figcaption>{photo.title}</figcaption>
</figure> </figure>
{:else} {:else}
@ -31,7 +31,8 @@
grid-gap: 8px; grid-gap: 8px;
} }
figure, img { figure,
img {
width: 100%; width: 100%;
margin: 0; margin: 0;
} }

@ -2,10 +2,11 @@
import { onInterval } from './utils.js'; import { onInterval } from './utils.js';
let seconds = 0; let seconds = 0;
onInterval(() => seconds += 1, 1000); onInterval(() => (seconds += 1), 1000);
</script> </script>
<p> <p>
The page has been open for The page has been open for
{seconds} {seconds === 1 ? 'second' : 'seconds'} {seconds}
{seconds === 1 ? 'second' : 'seconds'}
</p> </p>

@ -6,7 +6,7 @@
let autoscroll; let autoscroll;
beforeUpdate(() => { beforeUpdate(() => {
autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20); autoscroll = div && div.offsetHeight + div.scrollTop > div.scrollHeight - 20;
}); });
afterUpdate(() => { afterUpdate(() => {
@ -15,9 +15,7 @@
const eliza = new Eliza(); const eliza = new Eliza();
let comments = [ let comments = [{ author: 'eliza', text: eliza.getInitial() }];
{ author: 'eliza', text: eliza.getInitial() }
];
function handleKeydown(event) { function handleKeydown(event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -41,7 +39,9 @@
}); });
setTimeout(() => { setTimeout(() => {
comments = comments.filter(comment => !comment.placeholder).concat({ comments = comments
.filter((comment) => !comment.placeholder)
.concat({
author: 'eliza', author: 'eliza',
text: reply text: reply
}); });
@ -62,7 +62,7 @@
{/each} {/each}
</div> </div>
<input on:keydown={handleKeydown}> <input on:keydown={handleKeydown} />
</div> </div>
<style> <style>
@ -99,7 +99,7 @@
} }
.user span { .user span {
background-color: #0074D9; background-color: #0074d9;
color: white; color: white;
border-radius: 1em 1em 0 1em; border-radius: 1em 1em 0 1em;
} }

@ -11,15 +11,9 @@
const { selectionStart, selectionEnd, value } = this; const { selectionStart, selectionEnd, value } = this;
const selection = value.slice(selectionStart, selectionEnd); const selection = value.slice(selectionStart, selectionEnd);
const replacement = /[a-z]/.test(selection) const replacement = /[a-z]/.test(selection) ? selection.toUpperCase() : selection.toLowerCase();
? selection.toUpperCase()
: selection.toLowerCase();
text = ( text = value.slice(0, selectionStart) + replacement + value.slice(selectionEnd);
value.slice(0, selectionStart) +
replacement +
value.slice(selectionEnd)
);
await tick(); await tick();
this.selectionStart = selectionStart; this.selectionStart = selectionStart;
@ -27,7 +21,7 @@
} }
</script> </script>
<textarea value={text} on:keydown={handleKeydown}></textarea> <textarea value={text} on:keydown={handleKeydown} />
<style> <style>
textarea { textarea {

@ -6,13 +6,13 @@
let countValue; let countValue;
const unsubscribe = count.subscribe(value => { const unsubscribe = count.subscribe((value) => {
countValue = value; countValue = value;
}); });
</script> </script>
<h1>The count is {countValue}</h1> <h1>The count is {countValue}</h1>
<Incrementer/> <Incrementer />
<Decrementer/> <Decrementer />
<Resetter/> <Resetter />

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function decrement() { function decrement() {
count.update(n => n - 1); count.update((n) => n - 1);
} }
</script> </script>
<button on:click={decrement}> <button on:click={decrement}> - </button>
-
</button>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function increment() { function increment() {
count.update(n => n + 1); count.update((n) => n + 1);
} }
</script> </script>
<button on:click={increment}> <button on:click={increment}> + </button>
+
</button>

@ -6,6 +6,4 @@
} }
</script> </script>
<button on:click={reset}> <button on:click={reset}> reset </button>
reset
</button>

@ -7,6 +7,6 @@
<h1>The count is {$count}</h1> <h1>The count is {$count}</h1>
<Incrementer/> <Incrementer />
<Decrementer/> <Decrementer />
<Resetter/> <Resetter />

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function decrement() { function decrement() {
count.update(n => n - 1); count.update((n) => n - 1);
} }
</script> </script>
<button on:click={decrement}> <button on:click={decrement}> - </button>
-
</button>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function increment() { function increment() {
count.update(n => n + 1); count.update((n) => n + 1);
} }
</script> </script>
<button on:click={increment}> <button on:click={increment}> + </button>
+
</button>

@ -6,6 +6,4 @@
} }
</script> </script>
<button on:click={reset}> <button on:click={reset}> reset </button>
reset
</button>

@ -13,5 +13,6 @@
<p> <p>
This page has been open for This page has been open for
{$elapsed} {$elapsed === 1 ? 'second' : 'seconds'} {$elapsed}
{$elapsed === 1 ? 'second' : 'seconds'}
</p> </p>

@ -8,27 +8,17 @@
}); });
</script> </script>
<progress value={$progress}></progress> <progress value={$progress} />
<button on:click="{() => progress.set(0)}"> <button on:click={() => progress.set(0)}> 0% </button>
0%
</button>
<button on:click="{() => progress.set(0.25)}"> <button on:click={() => progress.set(0.25)}> 25% </button>
25%
</button>
<button on:click="{() => progress.set(0.5)}"> <button on:click={() => progress.set(0.5)}> 50% </button>
50%
</button>
<button on:click="{() => progress.set(0.75)}"> <button on:click={() => progress.set(0.75)}> 75% </button>
75%
</button>
<button on:click="{() => progress.set(1)}"> <button on:click={() => progress.set(1)}> 100% </button>
100%
</button>
<style> <style>
progress { progress {

@ -1,10 +1,13 @@
<script> <script>
import { spring } from 'svelte/motion'; import { spring } from 'svelte/motion';
let coords = spring({ x: 50, y: 50 }, { let coords = spring(
{ x: 50, y: 50 },
{
stiffness: 0.1, stiffness: 0.1,
damping: 0.25 damping: 0.25
}); }
);
let size = spring(10); let size = spring(10);
</script> </script>
@ -12,24 +15,30 @@
<div style="position: absolute; right: 1em;"> <div style="position: absolute; right: 1em;">
<label> <label>
<h3>stiffness ({coords.stiffness})</h3> <h3>stiffness ({coords.stiffness})</h3>
<input bind:value={coords.stiffness} type="range" min="0" max="1" step="0.01"> <input bind:value={coords.stiffness} type="range" min="0" max="1" step="0.01" />
</label> </label>
<label> <label>
<h3>damping ({coords.damping})</h3> <h3>damping ({coords.damping})</h3>
<input bind:value={coords.damping} type="range" min="0" max="1" step="0.01"> <input bind:value={coords.damping} type="range" min="0" max="1" step="0.01" />
</label> </label>
</div> </div>
<svg <svg
on:mousemove="{e => coords.set({ x: e.clientX, y: e.clientY })}" on:mousemove={(e) => coords.set({ x: e.clientX, y: e.clientY })}
on:mousedown="{() => size.set(30)}" on:mousedown={() => size.set(30)}
on:mouseup="{() => size.set(10)}" on:mouseup={() => size.set(10)}
> >
<circle cx={$coords.x} cy={$coords.y} r={$size}/> <circle cx={$coords.x} cy={$coords.y} r={$size} />
</svg> </svg>
<style> <style>
svg { width: 100%; height: 100%; margin: -8px } svg {
circle { fill: #ff3e00 } width: 100%;
height: 100%;
margin: -8px;
}
circle {
fill: #ff3e00;
}
</style> </style>

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:fade> <p transition:fade>Fades in and out</p>
Fades in and out
</p>
{/if} {/if}

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:fly="{{ y: 200, duration: 2000 }}"> <p transition:fly={{ y: 200, duration: 2000 }}>Flies in and out</p>
Flies in and out
</p>
{/if} {/if}

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p in:fly="{{ y: 200, duration: 2000 }}" out:fade> <p in:fly={{ y: 200, duration: 2000 }} out:fade>Flies in, fades out</p>
Flies in, fades out
</p>
{/if} {/if}

@ -7,7 +7,7 @@
function spin(node, { duration }) { function spin(node, { duration }) {
return { return {
duration, duration,
css: t => { css: (t) => {
const eased = elasticOut(t); const eased = elasticOut(t);
return ` return `
@ -16,19 +16,19 @@
${~~(t * 360)}, ${~~(t * 360)},
${Math.min(100, 1000 - 1000 * t)}%, ${Math.min(100, 1000 - 1000 * t)}%,
${Math.min(50, 500 - 500 * t)}% ${Math.min(50, 500 - 500 * t)}%
);` );`;
} }
}; };
} }
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<div class="centered" in:spin="{{duration: 8000}}" out:fade> <div class="centered" in:spin={{ duration: 8000 }} out:fade>
<span>transitions!</span> <span>transitions!</span>
</div> </div>
{/if} {/if}
@ -38,12 +38,12 @@
position: absolute; position: absolute;
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translate(-50%,-50%); transform: translate(-50%, -50%);
} }
span { span {
position: absolute; position: absolute;
transform: translate(-50%,-50%); transform: translate(-50%, -50%);
font-size: 4em; font-size: 4em;
} }
</style> </style>

@ -2,10 +2,7 @@
let visible = false; let visible = false;
function typewriter(node, { speed = 1 }) { function typewriter(node, { speed = 1 }) {
const valid = ( const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) { if (!valid) {
throw new Error(`This transition only works on elements with a single text node child`); throw new Error(`This transition only works on elements with a single text node child`);
@ -16,7 +13,7 @@
return { return {
duration, duration,
tick: t => { tick: (t) => {
const i = ~~(text.length * t); const i = ~~(text.length * t);
node.textContent = text.slice(0, i); node.textContent = text.slice(0, i);
} }
@ -25,12 +22,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:typewriter> <p transition:typewriter>The quick brown fox jumps over the lazy dog</p>
The quick brown fox jumps over the lazy dog
</p>
{/if} {/if}

@ -8,17 +8,17 @@
<p>status: {status}</p> <p>status: {status}</p>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p <p
transition:fly="{{ y: 200, duration: 2000 }}" transition:fly={{ y: 200, duration: 2000 }}
on:introstart="{() => status = 'intro started'}" on:introstart={() => (status = 'intro started')}
on:outrostart="{() => status = 'outro started'}" on:outrostart={() => (status = 'outro started')}
on:introend="{() => status = 'intro ended'}" on:introend={() => (status = 'intro ended')}
on:outroend="{() => status = 'outro ended'}" on:outroend={() => (status = 'outro ended')}
> >
Flies in and out Flies in and out
</p> </p>

@ -12,8 +12,8 @@
const ASSETS = `https://sveltejs.github.io/assets/crossfade`; const ASSETS = `https://sveltejs.github.io/assets/crossfade`;
const load = image => { const load = (image) => {
const timeout = setTimeout(() => loading = image, 100); const timeout = setTimeout(() => (loading = image), 100);
const img = new Image(); const img = new Image();
@ -37,10 +37,10 @@
{#if selected !== image} {#if selected !== image}
<button <button
style="background-color: {image.color};" style="background-color: {image.color};"
on:click="{() => load(image)}" on:click={() => load(image)}
in:receive={{key:image.id}} in:receive={{ key: image.id }}
out:send={{key:image.id}} out:send={{ key: image.id }}>{loading === image ? '...' : image.id}</button
>{loading === image ? '...' : image.id}</button> >
{/if} {/if}
</div> </div>
{/each} {/each}
@ -48,15 +48,14 @@
{#if selected} {#if selected}
{#await selected then d} {#await selected then d}
<div class="photo" in:receive={{key:d.id}} out:send={{key:d.id}}> <div class="photo" in:receive={{ key: d.id }} out:send={{ key: d.id }}>
<img <img alt={d.alt} src="{ASSETS}/{d.id}.jpg" on:click={() => (selected = null)} />
alt={d.alt}
src="{ASSETS}/{d.id}.jpg"
on:click="{() => selected = null}"
>
<p class='credit'> <p class="credit">
<a target="_blank" rel="noreferrer" href="https://www.flickr.com/photos/{d.path}">via Flickr</a> &ndash; <a target="_blank" rel="noreferrer" href="https://www.flickr.com/photos/{d.path}"
>via Flickr</a
>
&ndash;
<a target="_blank" rel="noreferrer" href={d.license.url}>{d.license.name}</a> <a target="_blank" rel="noreferrer" href={d.license.url}>{d.license.name}</a>
</p> </p>
</div> </div>
@ -114,7 +113,8 @@
will-change: transform; will-change: transform;
} }
.photo, img { .photo,
img {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@ -144,10 +144,11 @@
color: white; color: white;
font-weight: bold; font-weight: bold;
opacity: 0.6; opacity: 0.6;
background: rgba(0,0,0,0.4); background: rgba(0, 0, 0, 0.4);
} }
.credit a, .credit a:visited { .credit a,
.credit a:visited {
color: white; color: white;
} }
</style> </style>

@ -11,7 +11,7 @@
return { return {
duration: 600, duration: 600,
easing: quintOut, easing: quintOut,
css: t => ` css: (t) => `
transform: ${transform} scale(${t}); transform: ${transform} scale(${t});
opacity: ${t} opacity: ${t}
` `
@ -25,7 +25,7 @@
{ id: 3, done: true, description: 'buy some milk' }, { id: 3, done: true, description: 'buy some milk' },
{ id: 4, done: false, description: 'mow the lawn' }, { id: 4, done: false, description: 'mow the lawn' },
{ id: 5, done: false, description: 'feed the turtle' }, { id: 5, done: false, description: 'feed the turtle' },
{ id: 6, done: false, description: 'fix some bugs' }, { id: 6, done: false, description: 'fix some bugs' }
]; ];
let uid = todos.length + 1; let uid = todos.length + 1;
@ -42,43 +42,35 @@
} }
function remove(todo) { function remove(todo) {
todos = todos.filter(t => t !== todo); todos = todos.filter((t) => t !== todo);
} }
</script> </script>
<div class='board'> <div class="board">
<input <input
class="new-todo" class="new-todo"
placeholder="what needs to be done?" placeholder="what needs to be done?"
on:keydown="{event => event.key === 'Enter' && add(event.target)}" on:keydown={(event) => event.key === 'Enter' && add(event.target)}
> />
<div class='left'> <div class="left">
<h2>todo</h2> <h2>todo</h2>
{#each todos.filter(t => !t.done) as todo (todo.id)} {#each todos.filter((t) => !t.done) as todo (todo.id)}
<label <label in:receive={{ key: todo.id }} out:send={{ key: todo.id }} animate:flip>
in:receive="{{key: todo.id}}" <input type="checkbox" bind:checked={todo.done} />
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description} {todo.description}
<button on:click="{() => remove(todo)}">x</button> <button on:click={() => remove(todo)}>x</button>
</label> </label>
{/each} {/each}
</div> </div>
<div class='right'> <div class="right">
<h2>done</h2> <h2>done</h2>
{#each todos.filter(t => t.done) as todo (todo.id)} {#each todos.filter((t) => t.done) as todo (todo.id)}
<label <label in:receive={{ key: todo.id }} out:send={{ key: todo.id }} animate:flip>
in:receive="{{key: todo.id}}" <input type="checkbox" bind:checked={todo.done} />
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description} {todo.description}
<button on:click="{() => remove(todo)}">x</button> <button on:click={() => remove(todo)}>x</button>
</label> </label>
{/each} {/each}
</div> </div>
@ -96,7 +88,8 @@
margin: 0 auto; margin: 0 auto;
} }
.left, .right { .left,
.right {
float: left; float: left;
width: 50%; width: 50%;
padding: 0 1em 0 0; padding: 0 1em 0 0;
@ -122,10 +115,12 @@
user-select: none; user-select: none;
} }
input { margin: 0 } input {
margin: 0;
}
.right label { .right label {
background-color: rgb(180,240,100); background-color: rgb(180, 240, 100);
} }
button { button {
@ -136,7 +131,7 @@
line-height: 1; line-height: 1;
background-color: transparent; background-color: transparent;
border: none; border: none;
color: rgb(170,30,30); color: rgb(170, 30, 30);
opacity: 0; opacity: 0;
transition: opacity 0.2s; transition: opacity 0.2s;
} }

@ -21,13 +21,13 @@
async function runAnimations() { async function runAnimations() {
playing = true; playing = true;
value.set(1000, {duration: 0}); value.set(1000, { duration: 0 });
time.set(0, {duration: 0}); time.set(0, { duration: 0 });
await ease_path.set(current.shape); await ease_path.set(current.shape);
await Promise.all([ await Promise.all([
time.set(1000, {duration, easing: x => x}), time.set(1000, { duration, easing: (x) => x }),
value.set(0, {duration, easing: current.fn}) value.set(0, { duration, easing: current.fn })
]); ]);
playing = false; playing = false;
@ -40,26 +40,17 @@
<div bind:offsetWidth={width} class="easing-vis"> <div bind:offsetWidth={width} class="easing-vis">
<svg viewBox="0 0 1400 1802"> <svg viewBox="0 0 1400 1802">
<g class="canvas"> <g class="canvas">
<Grid x={$time} y={$value}/> <Grid x={$time} y={$value} />
<g class="graph"> <g class="graph">
<path <path d={$ease_path} stroke="#333" stroke-width="2" fill="none" />
d={$ease_path}
stroke="#333"
stroke-width="2"
fill="none"
/>
<path d="M0,23.647C0,22.41 27.014,0.407 28.496,0.025C29.978,-0.357 69.188,3.744 70.104,4.744C71.02,5.745 71.02,41.499 70.104,42.5C69.188,43.501 29.978,47.601 28.496,47.219C27.014,46.837 0,24.884 0,23.647Z" <path
d="M0,23.647C0,22.41 27.014,0.407 28.496,0.025C29.978,-0.357 69.188,3.744 70.104,4.744C71.02,5.745 71.02,41.499 70.104,42.5C69.188,43.501 29.978,47.601 28.496,47.219C27.014,46.837 0,24.884 0,23.647Z"
fill="#ff3e00" fill="#ff3e00"
style="transform: translate(1060px, {($value - 24)}px)" style="transform: translate(1060px, {$value - 24}px)"
/> />
<circle <circle cx={$time} cy={$value} r="15" fill="#ff3e00" />
cx="{$time}"
cy="{$value}"
r="15"
fill="#ff3e00"
/>
</g> </g>
</g> </g>
</svg> </svg>
@ -93,10 +84,10 @@
} }
.graph { .graph {
transform: translate(200px,400px) transform: translate(200px, 400px);
} }
@media (max-width:600px) { @media (max-width: 600px) {
.easing-vis { .easing-vis {
flex-direction: column; flex-direction: column;
max-height: calc(100% - 3rem); max-height: calc(100% - 3rem);

@ -20,10 +20,7 @@
{#if mobile} {#if mobile}
<select bind:value={current_ease}> <select bind:value={current_ease}>
{#each [...eases] as [name]} {#each [...eases] as [name]}
<option <option value={name} class:selected={name === current_ease}>
value={name}
class:selected={name === current_ease}
>
{name} {name}
</option> </option>
{/each} {/each}
@ -31,22 +28,17 @@
{:else} {:else}
<ul> <ul>
{#each [...eases] as [name]} {#each [...eases] as [name]}
<li <li class:selected={name === current_ease} on:click={() => (current_ease = name)}>
class:selected={name === current_ease}
on:click={() => current_ease = name}
>
{name} {name}
</li> </li>
{/each} {/each}
</ul> </ul>
{/if} {/if}
<h3>Type</h3> <h3>Type</h3>
{#if mobile } {#if mobile}
<select bind:value={current_type}> <select bind:value={current_type}>
{#each types as [name, type]} {#each types as [name, type]}
<option <option value={type}>
value={type}
>
{name} {name}
</option> </option>
{/each} {/each}
@ -54,31 +46,25 @@
{:else} {:else}
<ul> <ul>
{#each types as [name, type]} {#each types as [name, type]}
<li <li class:selected={type === current_type} on:click={() => (current_type = type)}>
class:selected={type === current_type}
on:click={() => current_type = type}
>
{name} {name}
</li> </li>
{/each} {/each}
</ul> </ul>
{/if} {/if}
</div> </div>
<h4> <h4>Duration</h4>
Duration
</h4>
<div class="duration"> <div class="duration">
<span> <span>
<input type="number" bind:value={duration} min="0" step="100"/> <input type="number" bind:value={duration} min="0" step="100" />
<button class="number" on:click={() => duration -= 100}>-</button> <button class="number" on:click={() => (duration -= 100)}>-</button>
<button class="number" on:click={() => duration += 100}>+</button> <button class="number" on:click={() => (duration += 100)}>+</button>
</span> </span>
<button class="play" on:click={() => dispatch('play')}> <button class="play" on:click={() => dispatch('play')}>
{playing ? 'Restart' : 'Play'} {playing ? 'Restart' : 'Play'}
</button> </button>
</div> </div>
</div> </div>
<style> <style>
.easing-sidebar { .easing-sidebar {
@ -99,7 +85,7 @@
background: #eee; background: #eee;
border-radius: 2px; border-radius: 2px;
margin: 3px 0; margin: 3px 0;
cursor:pointer; cursor: pointer;
} }
li:hover { li:hover {
@ -139,7 +125,7 @@
.duration input { .duration input {
width: 80px; width: 80px;
margin: 10px 10px 10px 0 ; margin: 10px 10px 10px 0;
} }
.duration button { .duration button {
@ -155,7 +141,7 @@
width: 100%; width: 100%;
} }
@media (max-width:600px) { @media (max-width: 600px) {
.easing-types { .easing-types {
display: flex; display: flex;
align-items: center; align-items: center;

@ -1,56 +1,34 @@
<svelte:options namespace="svg" />
<script> <script>
export let x, y; export let x, y;
</script> </script>
<svelte:options namespace="svg" />
<rect <rect
x=0 x="0"
y=0 y="0"
width=1400 width="1400"
height=1800 height="1800"
stroke=#ccc stroke="#ccc"
style="opacity: 0.5" style="opacity: 0.5"
fill=none fill="none"
stroke-width=2 stroke-width="2"
/> />
{#each { length: 8 } as _, i} {#each { length: 8 } as _, i}
{#if i < 6} {#if i < 6}
<path <path d="M{(i + 1) * 200} 0 L{(i + 1) * 200} 1802" class="grid-line" />
d="M{(i+1) * 200} 0 L{(i+1)*200} 1802"
class="grid-line"
/>
{/if} {/if}
<path <path d="M0 {(i + 1) * 200} L1400 {(i + 1) * 200} " class="grid-line" />
d="M0 {(i+1) * 200} L1400 {(i+1)*200} "
class="grid-line"
/>
{/each} {/each}
<path <path style="transform: translateX({x + 200}px)" d="M0 0 L0 1800" class="grid-line-xy" />
style="transform: translateX({x+200}px)" <path style="transform: translateY({y}px)" d="M0 400 L1400 400" class="grid-line-xy" />
d="M0 0 L0 1800" <rect x="200" y="400" width="1000" height="1000" stroke="#999" fill="none" stroke-width="2" />
class="grid-line-xy"
/>
<path
style="transform: translateY({y}px)"
d="M0 400 L1400 400"
class="grid-line-xy"
/>
<rect
x=200
y=400
width=1000
height=1000
stroke=#999
fill=none
stroke-width=2
/>
<style> <style>
.grid-line { .grid-line {
stroke:#ccc; stroke: #ccc;
opacity: 0.5; opacity: 0.5;
stroke-width: 2; stroke-width: 2;
} }

@ -20,48 +20,28 @@
}); });
</script> </script>
<svg viewBox='-50 -50 100 100'> <svg viewBox="-50 -50 100 100">
<circle class='clock-face' r='48'/> <circle class="clock-face" r="48" />
<!-- markers --> <!-- markers -->
{#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute} {#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute}
<line <line class="major" y1="35" y2="45" transform="rotate({30 * minute})" />
class='major'
y1='35'
y2='45'
transform='rotate({30 * minute})'
/>
{#each [1, 2, 3, 4] as offset} {#each [1, 2, 3, 4] as offset}
<line <line class="minor" y1="42" y2="45" transform="rotate({6 * (minute + offset)})" />
class='minor'
y1='42'
y2='45'
transform='rotate({6 * (minute + offset)})'
/>
{/each} {/each}
{/each} {/each}
<!-- hour hand --> <!-- hour hand -->
<line <line class="hour" y1="2" y2="-20" transform="rotate({30 * hours + minutes / 2})" />
class='hour'
y1='2'
y2='-20'
transform='rotate({30 * hours + minutes / 2})'
/>
<!-- minute hand --> <!-- minute hand -->
<line <line class="minute" y1="4" y2="-30" transform="rotate({6 * minutes + seconds / 10})" />
class='minute'
y1='4'
y2='-30'
transform='rotate({6 * minutes + seconds / 10})'
/>
<!-- second hand --> <!-- second hand -->
<g transform='rotate({6 * seconds})'> <g transform="rotate({6 * seconds})">
<line class='second' y1='10' y2='-38'/> <line class="second" y1="10" y2="-38" />
<line class='second-counterweight' y1='10' y2='2'/> <line class="second-counterweight" y1="10" y2="2" />
</g> </g>
</svg> </svg>
@ -94,8 +74,9 @@
stroke: #666; stroke: #666;
} }
.second, .second-counterweight { .second,
stroke: rgb(180,0,0); .second-counterweight {
stroke: rgb(180, 0, 0);
} }
.second-counterweight { .second-counterweight {

@ -41,7 +41,7 @@
<g class="axis y-axis"> <g class="axis y-axis">
{#each yTicks as tick} {#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})"> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x2="100%"></line> <line x2="100%" />
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text> <text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g> </g>
{/each} {/each}
@ -51,19 +51,19 @@
<g class="axis x-axis"> <g class="axis x-axis">
{#each points as point, i} {#each points as point, i}
<g class="tick" transform="translate({xScale(i)},{height})"> <g class="tick" transform="translate({xScale(i)},{height})">
<text x="{barWidth/2}" y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text> <text x={barWidth / 2} y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text>
</g> </g>
{/each} {/each}
</g> </g>
<g class='bars'> <g class="bars">
{#each points as point, i} {#each points as point, i}
<rect <rect
x="{xScale(i) + 2}" x={xScale(i) + 2}
y="{yScale(point.birthrate)}" y={yScale(point.birthrate)}
width="{barWidth - 4}" width={barWidth - 4}
height="{yScale(0) - yScale(point.birthrate)}" height={yScale(0) - yScale(point.birthrate)}
></rect> />
{/each} {/each}
</g> </g>
</svg> </svg>
@ -88,7 +88,7 @@
.tick { .tick {
font-family: Helvetica, Arial; font-family: Helvetica, Arial;
font-size: .725em; font-size: 0.725em;
font-weight: 200; font-weight: 200;
} }

@ -19,10 +19,10 @@
$: minX = points[0].x; $: minX = points[0].x;
$: maxX = points[points.length - 1].x; $: maxX = points[points.length - 1].x;
$: path = `M${points.map(p => `${xScale(p.x)},${yScale(p.y)}`).join('L')}`; $: path = `M${points.map((p) => `${xScale(p.x)},${yScale(p.y)}`).join('L')}`;
$: area = `${path}L${xScale(maxX)},${yScale(0)}L${xScale(minX)},${yScale(0)}Z`; $: area = `${path}L${xScale(maxX)},${yScale(0)}L${xScale(minX)},${yScale(0)}Z`;
function formatMobile (tick) { function formatMobile(tick) {
return "'" + tick.toString().slice(-2); return "'" + tick.toString().slice(-2);
} }
</script> </script>
@ -35,7 +35,7 @@
<g class="axis y-axis" transform="translate(0, {padding.top})"> <g class="axis y-axis" transform="translate(0, {padding.top})">
{#each yTicks as tick} {#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})"> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})">
<line x2="100%"></line> <line x2="100%" />
<text y="-4">{tick} {tick === 8 ? ' million sq km' : ''}</text> <text y="-4">{tick} {tick === 8 ? ' million sq km' : ''}</text>
</g> </g>
{/each} {/each}
@ -44,23 +44,29 @@
<!-- x axis --> <!-- x axis -->
<g class="axis x-axis"> <g class="axis x-axis">
{#each xTicks as tick} {#each xTicks as tick}
<g class="tick tick-{ tick }" transform="translate({xScale(tick)},{height})"> <g class="tick tick-{tick}" transform="translate({xScale(tick)},{height})">
<line y1="-{height}" y2="-{padding.bottom}" x1="0" x2="0"></line> <line y1="-{height}" y2="-{padding.bottom}" x1="0" x2="0" />
<text y="-2">{width > 380 ? tick : formatMobile(tick)}</text> <text y="-2">{width > 380 ? tick : formatMobile(tick)}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- data --> <!-- data -->
<path class="path-area" d={area}></path> <path class="path-area" d={area} />
<path class="path-line" d={path}></path> <path class="path-line" d={path} />
</svg> </svg>
</div> </div>
<p>Average September extent. Source: <a href='https://climate.nasa.gov/vital-signs/arctic-sea-ice/'>NSIDC/NASA</a></p> <p>
Average September extent. Source: <a href="https://climate.nasa.gov/vital-signs/arctic-sea-ice/"
>NSIDC/NASA</a
>
</p>
<style> <style>
.chart, h2, p { .chart,
h2,
p {
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
margin-left: auto; margin-left: auto;
@ -75,7 +81,7 @@
} }
.tick { .tick {
font-size: .725em; font-size: 0.725em;
font-weight: 200; font-weight: 200;
} }
@ -99,13 +105,13 @@
.path-line { .path-line {
fill: none; fill: none;
stroke: rgb(0,100,100); stroke: rgb(0, 100, 100);
stroke-linejoin: round; stroke-linejoin: round;
stroke-linecap: round; stroke-linecap: round;
stroke-width: 2; stroke-width: 2;
} }
.path-area { .path-area {
fill: rgba(0,100,100,0.2); fill: rgba(0, 100, 100, 0.2);
} }
</style> </style>

@ -6,10 +6,10 @@
<div class="chart"> <div class="chart">
<h2>Anscombe's quartet</h2> <h2>Anscombe's quartet</h2>
<Scatterplot points={data.a}/> <Scatterplot points={data.a} />
<Scatterplot points={data.b}/> <Scatterplot points={data.b} />
<Scatterplot points={data.c}/> <Scatterplot points={data.c} />
<Scatterplot points={data.d}/> <Scatterplot points={data.d} />
</div> </div>
<style> <style>

@ -18,13 +18,9 @@
.domain([0, 12]) .domain([0, 12])
.range([height - padding.bottom, padding.top]); .range([height - padding.bottom, padding.top]);
$: xTicks = width > 180 ? $: xTicks = width > 180 ? [0, 4, 8, 12, 16, 20] : [0, 10, 20];
[0, 4, 8, 12, 16, 20] :
[0, 10, 20];
$: yTicks = height > 180 ? $: yTicks = height > 180 ? [0, 2, 4, 6, 8, 10, 12] : [0, 4, 8, 12];
[0, 2, 4, 6, 8, 10, 12] :
[0, 4, 8, 12];
onMount(resize); onMount(resize);
@ -33,32 +29,32 @@
} }
</script> </script>
<svelte:window on:resize='{resize}'/> <svelte:window on:resize={resize} />
<svg bind:this={svg}> <svg bind:this={svg}>
<!-- y axis --> <!-- y axis -->
<g class='axis y-axis'> <g class="axis y-axis">
{#each yTicks as tick} {#each yTicks as tick}
<g class='tick tick-{tick}' transform='translate(0, {yScale(tick)})'> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x1='{padding.left}' x2='{xScale(22)}'/> <line x1={padding.left} x2={xScale(22)} />
<text x='{padding.left - 8}' y='+4'>{tick}</text> <text x={padding.left - 8} y="+4">{tick}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- x axis --> <!-- x axis -->
<g class='axis x-axis'> <g class="axis x-axis">
{#each xTicks as tick} {#each xTicks as tick}
<g class='tick' transform='translate({xScale(tick)},0)'> <g class="tick" transform="translate({xScale(tick)},0)">
<line y1='{yScale(0)}' y2='{yScale(13)}'/> <line y1={yScale(0)} y2={yScale(13)} />
<text y='{height - padding.bottom + 16}'>{tick}</text> <text y={height - padding.bottom + 16}>{tick}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- data --> <!-- data -->
{#each points as point} {#each points as point}
<circle cx='{xScale(point.x)}' cy='{yScale(point.y)}' r='5'/> <circle cx={xScale(point.x)} cy={yScale(point.y)} r="5" />
{/each} {/each}
</svg> </svg>
@ -72,7 +68,7 @@
circle { circle {
fill: orange; fill: orange;
fill-opacity: 0.6; fill-opacity: 0.6;
stroke: rgba(0,0,0,0.5); stroke: rgba(0, 0, 0, 0.5);
} }
.tick line { .tick line {

@ -9,35 +9,29 @@
{#if visible} {#if visible}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
<g out:fade="{{duration: 200}}" opacity=0.2> <g out:fade={{ duration: 200 }} opacity="0.2">
<path <path
in:expand="{{duration: 400, delay: 1000, easing: quintOut}}" in:expand={{ duration: 400, delay: 1000, easing: quintOut }}
style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;" style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;"
d={outer} d={outer}
/> />
<path <path in:draw={{ duration: 1000 }} style="stroke:#ff3e00; stroke-width: 1.5" d={inner} />
in:draw="{{duration: 1000}}"
style="stroke:#ff3e00; stroke-width: 1.5"
d={inner}
/>
</g> </g>
</svg> </svg>
<div class="centered" out:fly="{{y: -20, duration: 800}}"> <div class="centered" out:fly={{ y: -20, duration: 800 }}>
{#each 'SVELTE' as char, i} {#each 'SVELTE' as char, i}
<span <span in:fade={{ delay: 1000 + i * 150, duration: 800 }}>{char}</span>
in:fade="{{delay: 1000 + i * 150, duration: 800}}"
>{char}</span>
{/each} {/each}
</div> </div>
{/if} {/if}
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
toggle me toggle me
</label> </label>
<link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet" />
<style> <style>
svg { svg {
@ -61,7 +55,7 @@
position: absolute; position: absolute;
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translate(-50%,-50%); transform: translate(-50%, -50%);
font-family: 'Overpass'; font-family: 'Overpass';
letter-spacing: 0.12em; letter-spacing: 0.12em;
color: #676778; color: #676778;

@ -1,14 +1,12 @@
<script> <script>
import { clickOutside } from "./click_outside.js"; import { clickOutside } from './click_outside.js';
let showModal = true; let showModal = true;
</script> </script>
<button on:click={() => (showModal = true)}>Show Modal</button> <button on:click={() => (showModal = true)}>Show Modal</button>
{#if showModal} {#if showModal}
<div class="box" use:clickOutside on:outclick={() => (showModal = false)}> <div class="box" use:clickOutside on:outclick={() => (showModal = false)}>Click outside me!</div>
Click outside me!
</div>
{/if} {/if}
<style> <style>

@ -6,14 +6,15 @@
</script> </script>
<label> <label>
<input type=range bind:value={duration} max={2000} step={100}> <input type="range" bind:value={duration} max={2000} step={100} />
{duration}ms {duration}ms
</label> </label>
<button use:longpress={duration} <button
on:longpress="{() => pressed = true}" use:longpress={duration}
on:mouseenter="{() => pressed = false}" on:longpress={() => (pressed = true)}
>press and hold</button> on:mouseenter={() => (pressed = false)}>press and hold</button
>
{#if pressed} {#if pressed}
<p>congratulations, you pressed and held for {duration}ms</p> <p>congratulations, you pressed and held for {duration}ms</p>

@ -2,17 +2,20 @@
import { spring } from 'svelte/motion'; import { spring } from 'svelte/motion';
import { pannable } from './pannable.js'; import { pannable } from './pannable.js';
const coords = spring({ x: 0, y: 0 }, { const coords = spring(
{ x: 0, y: 0 },
{
stiffness: 0.2, stiffness: 0.2,
damping: 0.4 damping: 0.4
}); }
);
function handlePanStart() { function handlePanStart() {
coords.stiffness = coords.damping = 1; coords.stiffness = coords.damping = 1;
} }
function handlePanMove(event) { function handlePanMove(event) {
coords.update($coords => ({ coords.update(($coords) => ({
x: $coords.x + event.detail.dx, x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy y: $coords.y + event.detail.dy
})); }));
@ -25,7 +28,8 @@
} }
</script> </script>
<div class="box" <div
class="box"
use:pannable use:pannable
on:panstart={handlePanStart} on:panstart={handlePanStart}
on:panmove={handlePanMove} on:panmove={handlePanMove}
@ -33,7 +37,7 @@
style="transform: style="transform:
translate({$coords.x}px,{$coords.y}px) translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)" rotate({$coords.x * 0.2}deg)"
></div> />
<style> <style>
.box { .box {

@ -2,20 +2,11 @@
let current = 'foo'; let current = 'foo';
</script> </script>
<button <button class:active={current === 'foo'} on:click={() => (current = 'foo')}>foo</button>
class:active="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
<button <button class:active={current === 'bar'} on:click={() => (current = 'bar')}>bar</button>
class:active="{current === 'bar'}"
on:click="{() => current = 'bar'}"
>bar</button>
<button <button class:active={current === 'baz'} on:click={() => (current = 'baz')}>baz</button>
class:active="{current === 'baz'}"
on:click="{() => current = 'baz'}"
>baz</button>
<style> <style>
button { button {

@ -3,7 +3,7 @@
</script> </script>
<label> <label>
<input type=checkbox bind:checked={big}> <input type="checkbox" bind:checked={big} />
big big
</label> </label>

@ -1,5 +1,5 @@
<div class="box"> <div class="box">
<slot></slot> <slot />
</div> </div>
<style> <style>
@ -7,7 +7,7 @@
width: 300px; width: 300px;
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 2px; border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1); box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1);
padding: 1em; padding: 1em;
margin: 0 0 1em 0; margin: 0 0 1em 0;
} }

@ -7,4 +7,4 @@
<p>This is a box. It can contain anything.</p> <p>This is a box. It can contain anything.</p>
</Box> </Box>
<Box/> <Box />

@ -9,7 +9,7 @@
width: 300px; width: 300px;
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 2px; border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1); box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1);
padding: 1em; padding: 1em;
margin: 0 0 1em 0; margin: 0 0 1em 0;
} }

@ -3,12 +3,10 @@
</script> </script>
<ContactCard> <ContactCard>
<span slot="name"> <span slot="name"> P. Sherman </span>
P. Sherman
</span>
<span slot="address"> <span slot="address">
42 Wallaby Way<br> 42 Wallaby Way<br />
Sydney Sydney
</span> </span>
</ContactCard> </ContactCard>

@ -23,17 +23,18 @@
width: 300px; width: 300px;
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 2px; border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1); box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1);
padding: 1em; padding: 1em;
} }
h2 { h2 {
padding: 0 0 0.2em 0; padding: 0 0 0.2em 0;
margin: 0 0 1em 0; margin: 0 0 1em 0;
border-bottom: 1px solid #ff3e00 border-bottom: 1px solid #ff3e00;
} }
.address, .email { .address,
.email {
padding: 0 0 0 1.5em; padding: 0 0 0 1.5em;
background: 0 0 no-repeat; background: 0 0 no-repeat;
background-size: 20px 20px; background-size: 20px 20px;
@ -41,7 +42,13 @@
line-height: 1.2; line-height: 1.2;
} }
.address { background-image: url(/tutorial/icons/map-marker.svg) } .address {
.email { background-image: url(/tutorial/icons/email.svg) } background-image: url(/tutorial/icons/map-marker.svg);
.missing { color: #999 } }
.email {
background-image: url(/tutorial/icons/email.svg);
}
.missing {
color: #999;
}
</style> </style>

@ -11,5 +11,5 @@
</script> </script>
<div on:mouseenter={enter} on:mouseleave={leave}> <div on:mouseenter={enter} on:mouseleave={leave}>
<slot hovering={hovering}></slot> <slot {hovering} />
</div> </div>

@ -1,5 +1,5 @@
<script> <script>
import Profile from "./Profile.svelte"; import Profile from './Profile.svelte';
</script> </script>
<Profile> <Profile>

@ -4,9 +4,7 @@
let showModal = false; let showModal = false;
</script> </script>
<button on:click={() => (showModal = true)}> <button on:click={() => (showModal = true)}> show modal </button>
show modal
</button>
<Modal bind:showModal> <Modal bind:showModal>
<h2 slot="header"> <h2 slot="header">
@ -17,11 +15,15 @@
<ol class="definition-list"> <ol class="definition-list">
<li>of or relating to modality in logic</li> <li>of or relating to modality in logic</li>
<li> <li>
containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy containing provisions as to the mode of procedure or the manner of taking effect —used of a
contract or legacy
</li> </li>
<li>of or relating to a musical mode</li> <li>of or relating to a musical mode</li>
<li>of or relating to structure as opposed to substance</li> <li>of or relating to structure as opposed to substance</li>
<li>of, relating to, or constituting a grammatical form or category characteristically indicating predication</li> <li>
of, relating to, or constituting a grammatical form or category characteristically indicating
predication
</li>
<li>of or relating to a statistical mode</li> <li>of or relating to a statistical mode</li>
</ol> </ol>

@ -4,10 +4,10 @@
</script> </script>
<Map lat={35} lon={-84} zoom={3.5}> <Map lat={35} lon={-84} zoom={3.5}>
<MapMarker lat={37.8225} lon={-122.0024} label="Svelte Body Shaping"/> <MapMarker lat={37.8225} lon={-122.0024} label="Svelte Body Shaping" />
<MapMarker lat={33.8981} lon={-118.4169} label="Svelte Barbershop & Essentials"/> <MapMarker lat={33.8981} lon={-118.4169} label="Svelte Barbershop & Essentials" />
<MapMarker lat={29.7230} lon={-95.4189} label="Svelte Waxing Studio"/> <MapMarker lat={29.723} lon={-95.4189} label="Svelte Waxing Studio" />
<MapMarker lat={28.3378} lon={-81.3966} label="Svelte 30 Nutritional Consultants"/> <MapMarker lat={28.3378} lon={-81.3966} label="Svelte 30 Nutritional Consultants" />
<MapMarker lat={40.6483} lon={-74.0237} label="Svelte Brands LLC"/> <MapMarker lat={40.6483} lon={-74.0237} label="Svelte Brands LLC" />
<MapMarker lat={40.6986} lon={-74.4100} label="Svelte Medical Systems"/> <MapMarker lat={40.6986} lon={-74.41} label="Svelte Medical Systems" />
</Map> </Map>

@ -3,7 +3,7 @@
import { mapbox, key } from './mapbox.js'; import { mapbox, key } from './mapbox.js';
setContext(key, { setContext(key, {
getMap: () => map, getMap: () => map
}); });
export let lat; export let lat;
@ -18,7 +18,7 @@
container, container,
style: 'mapbox://styles/mapbox/streets-v9', style: 'mapbox://styles/mapbox/streets-v9',
center: [lon, lat], center: [lon, lat],
zoom, zoom
}); });
} }
@ -28,11 +28,7 @@
</script> </script>
<svelte:head> <svelte:head>
<link <link rel="stylesheet" href="https://unpkg.com/mapbox-gl/dist/mapbox-gl.css" on:load={load} />
rel="stylesheet"
href="https://unpkg.com/mapbox-gl/dist/mapbox-gl.css"
on:load={load}
/>
</svelte:head> </svelte:head>
<div bind:this={container}> <div bind:this={container}>

@ -9,11 +9,7 @@
export let lon; export let lon;
export let label; export let label;
const popup = new mapbox.Popup({ offset: 25 }) const popup = new mapbox.Popup({ offset: 25 }).setText(label);
.setText(label);
const marker = new mapbox.Marker() const marker = new mapbox.Marker().setLngLat([lon, lat]).setPopup(popup).addTo(map);
.setLngLat([lon, lat])
.setPopup(popup)
.addTo(map);
</script> </script>

@ -5,9 +5,7 @@
{ {
type: 'folder', type: 'folder',
name: 'Important work stuff', name: 'Important work stuff',
files: [ files: [{ type: 'file', name: 'quarterly-results.xlsx' }]
{ type: 'file', name: 'quarterly-results.xlsx' }
]
}, },
{ {
type: 'folder', type: 'folder',
@ -38,4 +36,4 @@
]; ];
</script> </script>
<Folder name="Home" files={root} expanded/> <Folder name="Home" files={root} expanded />

@ -1,6 +1,6 @@
<script> <script>
import File from './File.svelte'; import File from './File.svelte';
import {slide} from 'svelte/transition' import { slide } from 'svelte/transition';
export let expanded = false; export let expanded = false;
export let name; export let name;
@ -14,13 +14,13 @@
<span class:expanded on:click={toggle}>{name}</span> <span class:expanded on:click={toggle}>{name}</span>
{#if expanded} {#if expanded}
<ul transition:slide={{duration:300}}> <ul transition:slide={{ duration: 300 }}>
{#each files as file} {#each files as file}
<li> <li>
{#if file.type === 'folder'} {#if file.type === 'folder'}
<svelte:self {...file}/> <svelte:self {...file} />
{:else} {:else}
<File {...file}/> <File {...file} />
{/if} {/if}
</li> </li>
{/each} {/each}

@ -6,7 +6,7 @@
const options = [ const options = [
{ color: 'red', component: RedThing }, { color: 'red', component: RedThing },
{ color: 'green', component: GreenThing }, { color: 'green', component: GreenThing },
{ color: 'blue', component: BlueThing }, { color: 'blue', component: BlueThing }
]; ];
let selected = options[0]; let selected = options[0];
@ -18,4 +18,4 @@
{/each} {/each}
</select> </select>
<svelte:component this={selected.component}/> <svelte:component this={selected.component} />

@ -8,7 +8,7 @@
} }
</script> </script>
<svelte:window on:keydown={handleKeydown}/> <svelte:window on:keydown={handleKeydown} />
<div style="text-align: center"> <div style="text-align: center">
{#if key} {#if key}
@ -33,10 +33,10 @@
border-radius: 4px; border-radius: 4px;
font-size: 6em; font-size: 6em;
padding: 0.2em 0.5em; padding: 0.2em 0.5em;
border-top: 5px solid rgba(255,255,255,0.5); border-top: 5px solid rgba(255, 255, 255, 0.5);
border-left: 5px solid rgba(255,255,255,0.5); border-left: 5px solid rgba(255, 255, 255, 0.5);
border-right: 5px solid rgba(0,0,0,0.2); border-right: 5px solid rgba(0, 0, 0, 0.2);
border-bottom: 5px solid rgba(0,0,0,0.2); border-bottom: 5px solid rgba(0, 0, 0, 0.2);
color: #555; color: #555;
} }
</style> </style>

@ -4,22 +4,20 @@
let y; let y;
</script> </script>
<svelte:window bind:scrollY={y}/> <svelte:window bind:scrollY={y} />
<a class="parallax-container" href="https://www.firewatchgame.com"> <a class="parallax-container" href="https://www.firewatchgame.com">
{#each layers as layer} {#each layers as layer}
<img <img
style="transform: translate(0,{-y * layer / (layers.length - 1)}px)" style="transform: translate(0,{(-y * layer) / (layers.length - 1)}px)"
src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png" src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png"
alt="parallax layer {layer}" alt="parallax layer {layer}"
> />
{/each} {/each}
</a> </a>
<div class="text"> <div class="text">
<span style="opacity: {1 - Math.max(0, y / 40)}"> <span style="opacity: {1 - Math.max(0, y / 40)}"> scroll down </span>
scroll down
</span>
<div class="foreground"> <div class="foreground">
You have scrolled {y} pixels You have scrolled {y} pixels
@ -32,7 +30,7 @@
width: 2400px; width: 2400px;
height: 712px; height: 712px;
left: 50%; left: 50%;
transform: translate(-50%,0); transform: translate(-50%, 0);
} }
.parallax-container img { .parallax-container img {
@ -48,14 +46,14 @@
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgb(45,10,13); background: rgb(45, 10, 13);
} }
.text { .text {
position: relative; position: relative;
width: 100%; width: 100%;
height: 300vh; height: 300vh;
color: rgb(220,113,43); color: rgb(220, 113, 43);
text-align: center; text-align: center;
padding: 4em 0.5em 0.5em 0.5em; padding: 4em 0.5em 0.5em 0.5em;
box-sizing: border-box; box-sizing: border-box;
@ -75,7 +73,7 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: calc(100% - 712px); height: calc(100% - 712px);
background-color: rgb(32,0,1); background-color: rgb(32, 0, 1);
color: white; color: white;
padding: 50vh 0 0 0; padding: 50vh 0 0 0;
} }

@ -1,7 +1,7 @@
<script> <script>
let selection = ''; let selection = '';
const handleSelectionChange = (e) => selection = document.getSelection(); const handleSelectionChange = (e) => (selection = document.getSelection());
</script> </script>
<svelte:document on:selectionchange={handleSelectionChange} /> <svelte:document on:selectionchange={handleSelectionChange} />

@ -1,21 +1,18 @@
<script> <script>
let hereKitty = false; let hereKitty = false;
const handleMouseenter = () => hereKitty = true; const handleMouseenter = () => (hereKitty = true);
const handleMouseleave = () => hereKitty = false; const handleMouseleave = () => (hereKitty = false);
</script> </script>
<svelte:body <svelte:body on:mouseenter={handleMouseenter} on:mouseleave={handleMouseleave} />
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 --> <!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img <img
class:curious={hereKitty} class:curious={hereKitty}
alt="Kitten wants to know what's going on" alt="Kitten wants to know what's going on"
src="/tutorial/kitten.png" src="/tutorial/kitten.png"
> />
<style> <style>
img { img {

@ -1,5 +1,5 @@
<svelte:head> <svelte:head>
<link rel="stylesheet" href="/tutorial/dark-theme.css"> <link rel="stylesheet" href="/tutorial/dark-theme.css" />
</svelte:head> </svelte:head>
<h1>Hello world!</h1> <h1>Hello world!</h1>

@ -2,9 +2,7 @@
import AudioPlayer, { stopAll } from './AudioPlayer.svelte'; import AudioPlayer, { stopAll } from './AudioPlayer.svelte';
</script> </script>
<button on:click={stopAll}> <button on:click={stopAll}> stop all audio </button>
stop all audio
</button>
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ --> <!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer <AudioPlayer

@ -2,7 +2,7 @@
const elements = new Set(); const elements = new Set();
export function stopAll() { export function stopAll() {
elements.forEach(element => { elements.forEach((element) => {
element.pause(); element.pause();
}); });
} }
@ -25,7 +25,7 @@
}); });
function stopOthers() { function stopOthers() {
elements.forEach(element => { elements.forEach((element) => {
if (element !== audio) element.pause(); if (element !== audio) element.pause();
}); });
} }
@ -35,18 +35,23 @@
<h2>{title}</h2> <h2>{title}</h2>
<p><strong>{composer}</strong> / performed by {performer}</p> <p><strong>{composer}</strong> / performed by {performer}</p>
<audio <audio bind:this={audio} bind:paused on:play={stopOthers} controls {src} />
bind:this={audio}
bind:paused
on:play={stopOthers}
controls
{src}
></audio>
</article> </article>
<style> <style>
article { margin: 0 0 1em 0; max-width: 800px } article {
h2, p { margin: 0 0 0.3em 0; } margin: 0 0 1em 0;
audio { width: 100%; margin: 0.5em 0 1em 0; } max-width: 800px;
.playing { color: #ff3e00; } }
h2,
p {
margin: 0 0 0.3em 0;
}
audio {
width: 100%;
margin: 0.5em 0 1em 0;
}
.playing {
color: #ff3e00;
}
</style> </style>

@ -5,8 +5,8 @@
}; };
</script> </script>
<input bind:value={user.firstname}> <input bind:value={user.firstname} />
<input bind:value={user.lastname}> <input bind:value={user.lastname} />
{@debug user} {@debug user}

@ -3,5 +3,5 @@
let count = 0; let count = 0;
</script> </script>
<input type=number bind:value={count}> <input type="number" bind:value={count} />
<button on:click="{() => count += 1}">count</button> <button on:click={() => (count += 1)}>count</button>

@ -4,18 +4,18 @@
function setBothFromC(value) { function setBothFromC(value) {
c = +value; c = +value;
f = +(32 + (9 / 5 * c)).toFixed(1); f = +(32 + (9 / 5) * c).toFixed(1);
} }
function setBothFromF(value) { function setBothFromF(value) {
f = +value; f = +value;
c =+(5 / 9 * (f - 32)).toFixed(1); c = +((5 / 9) * (f - 32)).toFixed(1);
} }
</script> </script>
<!-- https://eugenkiss.github.io/7guis/tasks/#temp --> <!-- https://eugenkiss.github.io/7guis/tasks/#temp -->
<input value={c} on:input="{e => setBothFromC(e.target.value)}" type=number> °C = <input value={c} on:input={(e) => setBothFromC(e.target.value)} type="number" /> °C =
<input value={f} on:input="{e => setBothFromF(e.target.value)}" type=number> °F <input value={f} on:input={(e) => setBothFromF(e.target.value)} type="number" /> °F
<style> <style>
input { input {

@ -42,16 +42,15 @@
<option value={true}>return flight</option> <option value={true}>return flight</option>
</select> </select>
<input type=date bind:value={start}> <input type="date" bind:value={start} />
<input type=date bind:value={end} disabled={!isReturn}> <input type="date" bind:value={end} disabled={!isReturn} />
<button <button on:click={bookFlight} disabled={isReturn && startDate >= endDate}>book</button>
on:click={bookFlight}
disabled="{isReturn && (startDate >= endDate)}"
>book</button>
<style> <style>
select, input, button { select,
input,
button {
display: block; display: block;
margin: 0.5em 0; margin: 0.5em 0;
font-size: inherit; font-size: inherit;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save