update some examples

pull/1890/head
Rich Harris 7 years ago
parent 2aece987c3
commit 1830d57b4c

@ -1,3 +1,70 @@
<script>
// [svelte-upgrade suggestion]
// manually refactor all references to __this
const __this = {
get: () => ({ i, undoStack, circles, selected, adjusting, adjusted })
};
export let i = 0;
export let undoStack = [[]];
export let circles = [];
export let selected;
export let adjusting = false;
export let adjusted = false;
// [svelte-upgrade suggestion]
// review these functions and remove unnecessary 'export' keywords
export function handleClick(event) {
if (__this.get().adjusting) {
adjusting = false;
// if nothing changed, rewind
if (__this.get().adjusted) push();
return;
}
const circle = {
cx: event.clientX,
cy: event.clientY,
r: 50
};
const circles = __this.get().circles;
circles.push(circle);
circles = circles, selected = circle;
push();
}
export function adjust(event) {
event.preventDefault();
if (!__this.get().selected) return;
adjusting = true, adjusted = false;
}
export function select(circle, event) {
if (!__this.get().adjusting) {
event.stopPropagation();
selected = circle;
}
}
export function push() {
undoStack.splice(++i);
undoStack.push(clone(circles));
i = i, undoStack = undoStack;
}
export function travel(d) {
const circles = clone(undoStack[i += d]);
circles = circles, i = i, adjusting = false;
}
function clone(circles) {
return circles.map(({ cx, cy, r }) => ({ cx, cy, r }));
}
</script>
<!-- <!--
https://github.com/eugenkiss/7guis/wiki#circle-drawer https://github.com/eugenkiss/7guis/wiki#circle-drawer
@ -7,14 +74,14 @@ radius of the selected circle.
--> -->
<div class='controls'> <div class='controls'>
<button on:click='travel(-1)' disabled='{i === 0}'>undo</button> <button on:click='{() => travel(-1)}' disabled='{i === 0}'>undo</button>
<button on:click='travel(+1)' disabled='{i === undoStack.length -1}'>redo</button> <button on:click='{() => travel(+1)}' disabled='{i === undoStack.length -1}'>redo</button>
</div> </div>
<svg on:click='handleClick(event)' on:contextmenu='adjust(event)'> <svg on:click='{handleClick}' on:contextmenu='{adjust}'>
{#each circles as circle} {#each circles as circle}
<circle cx='{circle.cx}' cy='{circle.cy}' r='{circle.r}' <circle cx='{circle.cx}' cy='{circle.cy}' r='{circle.r}'
on:click='select(circle, event)' on:click='{event => select(circle, event)}'
fill='{circle === selected ? "#ccc": "white"}' fill='{circle === selected ? "#ccc": "white"}'
/> />
{/each} {/each}
@ -23,7 +90,7 @@ radius of the selected circle.
{#if adjusting} {#if adjusting}
<div class='adjuster'> <div class='adjuster'>
<p>adjust diameter of circle at {selected.cx}, {selected.cy}</p> <p>adjust diameter of circle at {selected.cx}, {selected.cy}</p>
<input type='range' bind:value='selected.r' on:input='set({ adjusted: true })'> <input type='range' bind:value='selected.r' on:input='{() => adjusted = true}'>
</div> </div>
{/if} {/if}
@ -58,73 +125,4 @@ radius of the selected circle.
input[type='range'] { input[type='range'] {
width: 100%; width: 100%;
} }
</style> </style>
<script>
export default {
data() {
return {
i: 0,
undoStack: [[]],
adjusting: false,
adjusted: false,
circles: []
};
},
methods: {
handleClick(event) {
if (this.get().adjusting) {
this.set({ adjusting: false });
// if nothing changed, rewind
if (this.get().adjusted) this.push();
return;
}
const circle = {
cx: event.clientX,
cy: event.clientY,
r: 50
};
const circles = this.get().circles;
circles.push(circle);
this.set({ circles, selected: circle });
this.push();
},
adjust(event) {
event.preventDefault();
if (!this.get().selected) return;
this.set({ adjusting: true, adjusted: false });
},
select(circle, event) {
if (!this.get().adjusting) {
event.stopPropagation();
this.set({ selected: circle });
}
},
// undo stack management
push() {
let { i, undoStack, circles } = this.get();
undoStack.splice(++i);
undoStack.push(clone(circles));
this.set({ i, undoStack });
},
travel(d) {
let { i, undoStack } = this.get();
const circles = clone(undoStack[i += d]);
this.set({ circles, i, adjusting: false });
}
}
};
function clone(circles) {
return circles.map(({ cx, cy, r }) => ({ cx, cy, r }));
}
</script>

@ -1,3 +1,3 @@
<!-- https://github.com/eugenkiss/7guis/wiki#counter --> <!-- https://github.com/eugenkiss/7guis/wiki#counter -->
<input type='number' bind:value='count'> <input type=number bind:value={count}>
<button on:click='set({ count: count + 1 })'>count</button> <button on:click="{() => count += 1}">count</button>

@ -1,19 +1,68 @@
<script>
import { beforeUpdate } from 'svelte';
export let people = [];
let prefix = '';
let first = '';
let last = '';
let i = 0;
const filteredPeople = () => {
if (!prefix) return people;
prefix = prefix.toLowerCase();
return people.filter(person => {
const name = `${person.last}, ${person.first}`;
return name.toLowerCase().startsWith(prefix);
});
};
const selected = () => filteredPeople()[i];
function create() {
people = people.concat({ first, last });
i = people.length - 1;
first = last = '';
}
function update() {
people[i] = { first, last };
}
function remove() {
people.splice(i, 1);
people = people;
first = last = '';
i = Math.min(i, people.length - 1);
}
beforeUpdate(() => {
const person = selected();
if (person) {
first = person.first;
last = person.last;
}
});
</script>
<!-- https://github.com/eugenkiss/7guis/wiki#crud --> <!-- https://github.com/eugenkiss/7guis/wiki#crud -->
<input placeholder='filter prefix' bind:value='prefix'> <input placeholder="filter prefix" bind:value={prefix}>
<select bind:value='i' size='5'> <select bind:value={i} size={5}>
{#each filteredPeople as person, i} {#each filteredPeople as person, i}
<option value='{i}'>{person.last}, {person.first}</option> <option value={i}>{person.last}, {person.first}</option>
{/each} {/each}
</select> </select>
<label><input bind:value='first' placeholder='first'></label> <label><input bind:value={first} placeholder="first"></label>
<label><input bind:value='last' placeholder='last'></label> <label><input bind:value={last} placeholder="last"></label>
<div class='buttons'> <div class='buttons'>
<button on:click='create()' disabled='{!first || !last}'>create</button> <button on:click={create} disabled="{!first || !last}">create</button>
<button on:click='update()' disabled='{!first || !last || !selected}'>update</button> <button on:click={update} disabled="{!first || !last || !selected()}">update</button>
<button on:click='remove()' disabled='{!selected}'>delete</button> <button on:click={remove} disabled="{!selected()}">delete</button>
</div> </div>
<style> <style>
@ -36,77 +85,4 @@
.buttons { .buttons {
clear: both; clear: both;
} }
</style> </style>
<script>
export default {
data() {
return {
prefix: '',
first: '',
last: '',
people: [],
selected: null
};
},
computed: {
selected: ({ filteredPeople, i }) => {
return filteredPeople[i];
},
filteredPeople({ people, prefix }) {
if (!prefix) return people;
prefix = prefix.toLowerCase();
return people.filter(person => {
const name = `${person.last}, ${person.first}`;
return name.toLowerCase().startsWith(prefix);
});
}
},
onstate({ changed, current }) {
if (changed.selected && current.selected) {
this.set(current.selected);
}
},
methods: {
create() {
const { first, last, people } = this.get();
people.push({ first, last });
this.set({
people,
first: '',
last: '',
i: people.length - 1
});
},
update() {
const { first, last, selected, people } = this.get();
selected.first = first;
selected.last = last;
this.set({ people });
},
remove() {
const { people, selected, i } = this.get();
const index = people.indexOf(selected);
people.splice(index, 1);
this.set({
people,
first: '',
last: '',
i: Math.min(i, people.length - 1)
});
}
}
};
</script>

@ -1,62 +1,30 @@
<!-- https://github.com/eugenkiss/7guis/wiki#flight-booker -->
<select bind:value='isReturn'>
<option value='{false}'>one-way flight</option>
<option value='{true}'>return flight</option>
</select>
<input type='date' bind:value='start'>
<input type='date' bind:value='end' disabled='{!isReturn}'>
<button
on:click='bookFlight()'
disabled='{ isReturn && ( startDate >= endDate ) }'
>book</button>
<style>
select, input, button {
display: block;
margin: 0.5em 0;
font-size: inherit;
}
</style>
<script> <script>
export default { const tomorrow = new Date(Date.now() + 86400000);
data() {
const tomorrow = new Date(Date.now() + 86400000);
const tomorrowAsString = [ const tomorrowAsString = [
tomorrow.getFullYear(), tomorrow.getFullYear(),
pad(tomorrow.getMonth() + 1, 2), pad(tomorrow.getMonth() + 1, 2),
pad(tomorrow.getDate(), 2) pad(tomorrow.getDate(), 2)
].join('-'); ].join('-');
return { let start = tomorrowAsString;
start: tomorrowAsString, let end = tomorrowAsString;
end: tomorrowAsString, let isReturn = false;
type: 'oneway'
};
},
computed: { const startDate = () => convertToDate(start);
startDate: ({ start }) => convertToDate(start), const endDate = () => convertToDate(end);
endDate: ({ end }) => convertToDate(end)
},
methods: {
bookFlight() {
const { startDate, endDate, isReturn } = this.get();
const type = isReturn ? 'return' : 'one-way';
let message = `You have booked a ${type} flight, leaving ${startDate.toDateString()}`; function bookFlight() {
if (type === 'return') { const type = isReturn ? 'return' : 'one-way';
message += ` and returning ${endDate.toDateString()}`;
}
alert(message); let message = `You have booked a ${type} flight, leaving ${startDate().toDateString()}`;
} if (type === 'return') {
message += ` and returning ${endDate().toDateString()}`;
} }
};
alert(message);
}
function convertToDate(str) { function convertToDate(str) {
var split = str.split('-'); var split = str.split('-');
@ -68,4 +36,26 @@
while (x.length < len) x = `0${x}`; while (x.length < len) x = `0${x}`;
return x; return x;
} }
</script> </script>
<style>
select, input, button {
display: block;
margin: 0.5em 0;
font-size: inherit;
}
</style>
<!-- https://github.com/eugenkiss/7guis/wiki#flight-booker -->
<select bind:value={isReturn}>
<option value={false}>one-way flight</option>
<option value={true}>return flight</option>
</select>
<input type=date bind:value={start}>
<input type=date bind:value={end} disabled={!isReturn}>
<button
on:click={bookFlight}
disabled="{isReturn && (startDate() >= endDate())}"
>book</button>

@ -1,6 +1,6 @@
<!-- https://github.com/eugenkiss/7guis/wiki#temperature-converter --> <!-- https://github.com/eugenkiss/7guis/wiki#temperature-converter -->
<input bind:value='celsius' type='number'> °c = <input value={c} on:input="{e => setBothFromC(e.target.value)}" type=number> °c =
<input bind:value='fahrenheit' type='number'> °f <input value={f} on:input="{e => setBothFromF(e.target.value)}" type=number> °f
<style> <style>
input { input {
@ -9,18 +9,16 @@
</style> </style>
<script> <script>
export default { let c = 0;
onstate: function ({ changed, current }) { let f = 32;
if (changed.celsius) {
this.set({ function setBothFromC(value) {
fahrenheit: +(32 + (9 / 5 * current.celsius)).toFixed(1) c = +value;
}); f = +(32 + (9 / 5 * c)).toFixed(1);
} }
if (changed.fahrenheit) {
this.set({ function setBothFromF(value) {
celsius: +(5 / 9 * (current.fahrenheit - 32)).toFixed(1) f = +value;
}); c =+(5 / 9 * (f - 32)).toFixed(1);
}
}
} }
</script> </script>

@ -1,3 +1,42 @@
<script>
import { onDestroy, onMount } from 'svelte';
// [svelte-upgrade suggestion]
// manually refactor all references to __this
const __this = {};
export let elapsed = 0;
export let duration = 5000;
export let start;
onMount(() => {
reset();
const update = () => {
__this.frame = requestAnimationFrame(update);
const elapsed = window.performance.now() - start;
if (elapsed > duration) return;
elapsed = elapsed;
};
update();
});
onDestroy(() => {
if (__this.frame) {
cancelAnimationFrame(__this.frame);
}
});
// [svelte-upgrade suggestion]
// review these functions and remove unnecessary 'export' keywords
export function reset() {
start = window.performance.now();
}
</script>
<!-- https://github.com/eugenkiss/7guis/wiki#timer --> <!-- https://github.com/eugenkiss/7guis/wiki#timer -->
<label> <label>
elapsed time: elapsed time:
@ -11,43 +50,4 @@
<input type='range' bind:value='duration' min='1' max='20000'> <input type='range' bind:value='duration' min='1' max='20000'>
</label> </label>
<button on:click='reset()'>reset</button> <button on:click='{reset}'>reset</button>
<script>
export default {
data() {
return { elapsed: 0, duration: 5000 };
},
oncreate() {
this.reset();
const update = () => {
this.frame = requestAnimationFrame(update);
const { start, duration } = this.get();
const elapsed = window.performance.now() - start;
if (elapsed > duration) return;
this.set({ elapsed });
};
update();
},
ondestroy() {
if (this.frame) {
cancelAnimationFrame(this.frame);
}
},
methods: {
reset() {
this.set({
start: window.performance.now()
});
}
}
};
</script>

@ -1,4 +1,17 @@
<button on:click='findAnswer()'>find the answer</button> <script>
export let promise;
// [svelte-upgrade suggestion]
// review these functions and remove unnecessary 'export' keywords
export function findAnswer() {
promise = new Promise(fulfil => {
const delay = 1000 + Math.random() * 3000;
setTimeout(() => fulfil(42), delay);
});
}
</script>
<button on:click='{findAnswer}'>find the answer</button>
{#if promise} {#if promise}
{#await promise} {#await promise}
@ -8,19 +21,4 @@
{:catch error} {:catch error}
<p>well that's odd</p> <p>well that's odd</p>
{/await} {/await}
{/if} {/if}
<script>
export default {
methods: {
findAnswer() {
this.set({
promise: new Promise(fulfil => {
const delay = 1000 + Math.random() * 3000;
setTimeout(() => fulfil(42), delay);
})
});
}
}
};
</script>

@ -1,4 +1,56 @@
<svelte:window on:resize='resize()'/> <script>
import { onMount } from 'svelte';
export let svg;
import { scaleLinear } from 'd3-scale';
var xScale = scaleLinear();
var yScale = scaleLinear();
export let xTicks = [1990, 1995, 2000, 2005, 2010, 2015];
export let width = 500;
export let padding = { top: 20, right: 15, bottom: 20, left: 25 };
export let height = 200;
export let yTicks = [0, 5, 10, 15, 20];
export let points;
export let tick;
function formatMobile(tick) {
return "'" + tick % 100;
}
function barWidth() {
var innerWidth = width - (padding.left + padding.right);
return innerWidth / xTicks.length;
}
function xScale() {
return xScale()
.domain([0, xTicks.length])
.range([padding.left, width - padding.right]);
}
function yScale() {
return yScale()
.domain([0, Math.max.apply(null, yTicks)])
.range([height - padding.bottom, padding.top]);
}
onMount(() => {
resize();
});
// [svelte-upgrade suggestion]
// review these functions and remove unnecessary 'export' keywords
export function resize() {
var bcr = svg.getBoundingClientRect();
width = bcr.right - bcr.left, height = bcr.bottom - bcr.top;
}
</script>
<svelte:window on:resize='{resize}'/>
<div class='chart'> <div class='chart'>
<h2>US birthrate by year</h2> <h2>US birthrate by year</h2>
@ -6,7 +58,7 @@
<!-- y axis --> <!-- y axis -->
<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%'></line>
<text y='-4'>{tick} {tick === 20 ? ' per 1,000 population' : ''}</text> <text y='-4'>{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g> </g>
@ -16,8 +68,8 @@
<!-- x axis --> <!-- x axis -->
<g class='axis x-axis'> <g class='axis x-axis'>
{#each points as point, i} {#each points as point, i}
<g class='tick tick-{tick}' transform='translate({xScale(i)},{height})'> <g class='tick tick-{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>
@ -25,10 +77,10 @@
<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='{ height - padding.bottom - yScale(point.birthrate) }' height='{ height - padding.bottom - yScale()(point.birthrate) }'
></rect> ></rect>
{/each} {/each}
</g> </g>
@ -70,63 +122,4 @@
stroke: none; stroke: none;
opacity: 0.65; opacity: 0.65;
} }
</style> </style>
<script>
import { scaleLinear } from 'd3-scale';
var xScale = scaleLinear();
var yScale = scaleLinear();
export default {
data: function () {
return {
padding: { top: 20, right: 15, bottom: 20, left: 25 },
height: 200,
width: 500,
xTicks: [1990, 1995, 2000, 2005, 2010, 2015],
yTicks: [0, 5, 10, 15, 20]
};
},
helpers: {
formatMobile: function (tick) {
return "'" + tick % 100;
}
},
computed: {
barWidth: function ({ xTicks, width, padding }) {
var innerWidth = width - (padding.left + padding.right);
return innerWidth / xTicks.length;
},
xScale: function ({ padding, width, xTicks }) {
return xScale
.domain([0, xTicks.length])
.range([padding.left, width - padding.right]);
},
yScale: function ({ padding, height, yTicks }) {
return yScale
.domain([0, Math.max.apply(null, yTicks)])
.range([height - padding.bottom, padding.top]);
}
},
oncreate() {
this.resize();
},
methods: {
resize: function () {
var bcr = this.refs.svg.getBoundingClientRect();
this.set({
width: bcr.right - bcr.left,
height: bcr.bottom - bcr.top
});
}
}
};
</script>

@ -1,15 +1,15 @@
<label> <label>
<input type='checkbox' bind:group='selected' value='red'> <input type=checkbox bind:group={selected} value="red">
red red
</label> </label>
<label> <label>
<input type='checkbox' bind:group='selected' value='green'> <input type=checkbox bind:group={selected} value="green">
green green
</label> </label>
<label> <label>
<input type='checkbox' bind:group='selected' value='blue'> <input type=checkbox bind:group={selected} value="blue">
blue blue
</label> </label>

@ -1,7 +1,7 @@
{#each todos as todo} {#each todos as todo}
<div class='todo {todo.done ? "done": ""}'> <div class="todo {todo.done ? 'done': ''}">
<input type='checkbox' bind:checked='todo.done'> <input type=checkbox bind:checked={todo.done}>
<input type='text' bind:value='todo.description'> <input type=text bind:value={todo.description}>
</div> </div>
{/each} {/each}

@ -1,6 +1,6 @@
<!-- number and range inputs are bound to numeric values --> <!-- number and range inputs are bound to numeric values -->
<input bind:value='a' type='number' min='0' max='10'> <input bind:value={a} type=number min=0 max=10>
<input bind:value='b' type='range' min='0' max='10'> <input bind:value={b} type=range min=0 max=10>
<p>{a} * {b} = {a * b}</p> <p>{a} * {b} = {a * b}</p>

@ -1,16 +1,16 @@
<label> <label>
<input type='radio' bind:group='selected' value='red'> <input type=radio bind:group={selected} value="red">
red red
</label> </label>
<label> <label>
<input type='radio' bind:group='selected' value='green'> <input type=radio bind:group={selected} value="green">
green green
</label> </label>
<label> <label>
<input type='radio' bind:group='selected' value='blue'> <input type=radio bind:group={selected} value="blue">
blue blue
</label> </label>
<p style='color: {selected};'>selected {selected}</p> <p style="color: {selected};">selected {selected}</p>

@ -1,2 +1,2 @@
<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>

@ -1,22 +1,59 @@
<svelte:window on:click='seek(event)' on:mousemove='seek(event)'/> <script>
export let paused = true;
export let t = 0;
export let d;
let icon, bg;
<audio bind:currentTime=t bind:duration=d bind:paused> $: icon = `https://icon.now.sh/${paused ? 'play' : 'pause'}_circle_filled`;
<source type='audio/mp3' src='https://deepnote.surge.sh/deepnote.mp3'>
$: {
var p = d ? t / d : 0;
var h = 90 + 90 * p;
var l = 10 + p * 30;
bg = `hsl(${h},50%,${l}%)`;
}
function pad(num) {
return num < 10 ? '0' + num : num;
}
const format = time => {
if (isNaN(time)) return '--:--.-';
var minutes = Math.floor(time / 60);
var seconds = (time % 60).toFixed(1);
return minutes + ':' + pad(seconds)
};
function seek(event) {
if (event.buttons === 1) {
event.preventDefault();
var p = event.clientX / window.innerWidth;
t = p * d;
}
}
</script>
<svelte:window on:click={seek} on:mousemove={seek}/>
<audio bind:currentTime={t} bind:duration={d} bind:paused>
<source type="audio/mp3" src="https://deepnote.surge.sh/deepnote.mp3">
</audio> </audio>
<p>THX Deep Note</p> <p>THX Deep Note</p>
<div class='status' on:click='event.stopPropagation()'> <div class="status" on:click="{event => event.stopPropagation()}">
<img alt='play/pause button' on:click='set({ paused: !paused })' src='{icon}/333333'> <img alt="play/pause button" on:click="{() => paused = !paused}" src="{icon}/333333">
<span class='elapsed'>{format(t)}</span> <span class="elapsed">{format(t)}</span>
<span class='duration'>{format(d)}</span> <span class="duration">{format(d)}</span>
</div> </div>
<div class='progress' style='width: {d ? 100 * t/d : 0}%; background: {bg};'> <div class="progress" style="width: {d ? 100 * t/d : 0}%; background: {bg};">
<p>THX Deep Note</p> <p>THX Deep Note</p>
<div class='status' on:click='event.stopPropagation()'> <div class="status" on:click="{event => event.stopPropagation()}">
<img alt='play/pause button' src='{icon}/ffffff'> <img alt="play/pause button" src="{icon}/ffffff">
<span class='elapsed'>{format(t)}</span> <span class="elapsed">{format(t)}</span>
<span class='duration'>{format(d)}</span> <span class="duration">{format(d)}</span>
</div> </div>
</div> </div>
@ -57,48 +94,3 @@
.elapsed { float: left; } .elapsed { float: left; }
.duration { float: right; } .duration { float: right; }
</style> </style>
<script>
function pad(num) {
return num < 10 ? '0' + num : num;
}
export default {
data() {
return { paused: true, t: 0 };
},
computed: {
icon: ({ paused }) => {
return `https://icon.now.sh/${paused ? 'play' : 'pause'}_circle_filled`;
},
bg: ({ t, d }) => {
var p = d ? t / d : 0;
var h = 90 + 90 * p;
var l = 10 + p * 30;
return `hsl(${h},50%,${l}%)`;
}
},
helpers: {
format: time => {
if (isNaN(time)) return '--:--.-';
var minutes = Math.floor(time / 60);
var seconds = (time % 60).toFixed(1);
return minutes + ':' + pad(seconds)
}
},
methods: {
seek(event) {
if (event.buttons === 1) {
event.preventDefault();
var p = event.clientX / window.innerWidth;
this.set({ t: p * this.get().d });
}
}
}
}
</script>

@ -1,19 +1,15 @@
<textarea bind:value='markdown' resize='none'></textarea> <script>
<div class='output'>{@html marked(markdown)}</div> import marked from 'marked';
export let markdown;
</script>
<textarea bind:value={markdown} resize="none"></textarea>
<div class="output">{@html marked(markdown)}</div>
<style> <style>
textarea { textarea {
width: 100%; width: 100%;
height: 50%; height: 50%;
} }
</style> </style>
<script>
import marked from 'marked';
export default {
helpers: {
marked
}
};
</script>

@ -2,6 +2,6 @@
<ul> <ul>
{#each cats as cat} {#each cats as cat}
<li><a target='_blank' href='{cat.video}'>{cat.name}</a></li> <li><a target="_blank" href={cat.video}>{cat.name}</a></li>
{/each} {/each}
</ul> </ul>

@ -1,4 +1,35 @@
<svelte:window on:hashchange='hashchange()'/> <script>
import { onMount } from 'svelte';
import List from './List.html';
import Item from './Item.html';
export let item;
export let page;
onMount(() => {
hashchange();
});
async function hashchange() {
// the poor man's router!
const path = window.location.hash.slice(1);
if (path.startsWith('/item')) {
const id = path.slice(6);
item = await fetch(`https://node-hnapi.herokuapp.com/item/${id}`).then(r => r.json());
window.scrollTo(0,0);
} else if (path.startsWith('/top')) {
page = +path.slice(5);
item = null;
} else {
window.location.hash = '/top/1';
}
}
</script>
<svelte:window on:hashchange={hashchange}/>
<main> <main>
{#if item} {#if item}
@ -26,41 +57,4 @@
main :global(a) { main :global(a) {
color: rgb(0,0,150); color: rgb(0,0,150);
} }
</style> </style>
<script>
import List from './List.html';
import Item from './Item.html';
export default {
components: { List, Item },
oncreate() {
this.hashchange();
},
methods: {
async hashchange() {
// the poor man's router!
const path = window.location.hash.slice(1);
if (path.startsWith('/item')) {
const id = path.slice(6);
const item = await fetch(`https://node-hnapi.herokuapp.com/item/${id}`).then(r => r.json());
this.set({ item });
window.scrollTo(0,0);
} else if (path.startsWith('/top')) {
const page = +path.slice(5);
this.set({
item: null,
page
});
} else {
window.location.hash = '/top/1';
}
}
}
};
</script>

@ -1,11 +1,11 @@
<article> <article>
<p class='meta'>{comment.user} {comment.time_ago}</p> <p class="meta">{comment.user} {comment.time_ago}</p>
{@html comment.content} {@html comment.content}
<div class='replies'> <div class="replies">
{#each comment.comments as child} {#each comment.comments as child}
<svelte:self comment='{child}'/> <svelte:self comment={child}/>
{/each} {/each}
</div> </div>
</article> </article>

@ -1,15 +1,26 @@
<a href='#/top/1' on:click='back(event)'>&laquo; back</a> <script>
import Comment from "./Comment.html";
export let item;
function back(event) {
event.preventDefault();
window.history.back();
}
</script>
<a href="#/top/1" on:click={back}>&laquo; back</a>
<article> <article>
<a href='{item.url}'> <a href="{item.url}">
<h1>{item.title}</h1> <h1>{item.title}</h1>
<small>{item.domain}</small> <small>{item.domain}</small>
</a> </a>
<p class='meta'>submitted by {item.user} {item.time_ago} <p class="meta">submitted by {item.user} {item.time_ago}
</article> </article>
<div class='comments'> <div class="comments">
{#each item.comments as comment} {#each item.comments as comment}
<Comment {comment}/> <Comment {comment}/>
{/each} {/each}
@ -29,19 +40,4 @@
font-size: 1.4em; font-size: 1.4em;
margin: 0; margin: 0;
} }
</style> </style>
<script>
import Comment from './Comment.html';
export default {
components: { Comment },
methods: {
back(event) {
event.preventDefault();
window.history.back();
}
}
};
</script>

@ -1,11 +1,34 @@
<script>
import { beforeUpdate } from "svelte";
import Summary from "./Summary.html";
const PAGE_SIZE = 20;
export let items;
export let offset;
export let page;
let previous_page;
beforeUpdate(async () => {
if (page !== previous_page) {
previous_page = page;
items = await fetch(`https://node-hnapi.herokuapp.com/news?page=${page}`).then(r => r.json())
offset = PAGE_SIZE * (page - 1);
window.scrollTo(0, 0);
}
});
</script>
{#if items} {#if items}
{#each items as item, i} {#each items as item, i}
<Summary {item} {i} {offset}/> <Summary {item} {i} {offset}/>
{/each} {/each}
<a href='#/top/{page + 1}'>page {page + 1}</a> <a href="#/top/{page + 1}">page {page + 1}</a>
{:else} {:else}
<p class='loading'>loading...</p> <p class="loading">loading...</p>
{/if} {/if}
<style> <style>
@ -23,30 +46,4 @@
from { opacity: 0; } from { opacity: 0; }
to { opacity: 1; } to { opacity: 1; }
} }
</style> </style>
<script>
import Summary from './Summary.html';
const PAGE_SIZE = 20;
export default {
async onstate({ changed, current }) {
if (changed.page) {
const { page } = current;
const items = await fetch(`https://node-hnapi.herokuapp.com/news?page=${page}`).then(r => r.json());
this.set({
items,
offset: PAGE_SIZE * (page - 1)
});
window.scrollTo(0,0);
}
},
components: {
Summary
}
};
</script>

@ -1,7 +1,18 @@
<script>
export let item;
export let i;
export let offset;
function comment_text() {
const c = item.comments_count;
return `${c} ${c === 1 ? 'comment' : 'comments'}`;
}
</script>
<article> <article>
<span>{i + offset + 1}</span> <span>{i + offset + 1}</span>
<h2><a target='_blank' href='{item.url}'>{item.title}</a></h2> <h2><a target="_blank" href={item.url}>{item.title}</a></h2>
<p class='meta'><a href='#/item/{item.id}'>{comment_text}</a> by {item.user} {item.time_ago}</p> <p class="meta"><a href="#/item/{item.id}">{comment_text()}</a> by {item.user} {item.time_ago}</p>
</article> </article>
<style> <style>
@ -24,15 +35,4 @@
a { a {
color: #333; color: #333;
} }
</style> </style>
<script>
export default {
computed: {
comment_text({ item }) {
const c = item.comments_count;
return `${c} ${c === 1 ? 'comment' : 'comments'}`;
}
}
};
</script>

@ -1,6 +1,31 @@
<svelte:meta immutable/>
<script>
import ImmutableTodo from './ImmutableTodo.html';
import MutableTodo from './MutableTodo.html';
export let todos;
function toggle(id) {
todos = todos.map(todo => {
if (todo.id === id) {
// return a new object
return {
id,
done: !todo.done,
text: todo.text
};
}
// return the same object
return todo;
});
}
</script>
<h2>Immutable</h2> <h2>Immutable</h2>
{#each todos as todo} {#each todos as todo}
<label on:click="toggle(todo.id)"> <label on:click="{() => toggle(todo.id)}">
<span>{todo.done ? "😎": "☹️"}</span> <span>{todo.done ? "😎": "☹️"}</span>
<ImmutableTodo {todo}/> <ImmutableTodo {todo}/>
</label> </label>
@ -8,41 +33,8 @@
<h2>Mutable</h2> <h2>Mutable</h2>
{#each todos as todo} {#each todos as todo}
<label on:click="toggle(todo.id)"> <label on:click="{() => toggle(todo.id)}">
<span>{todo.done ? "😎": "☹️"}</span> <span>{todo.done ? "😎": "☹️"}</span>
<MutableTodo {todo}/> <MutableTodo {todo}/>
</label> </label>
{/each} {/each}
<script>
import ImmutableTodo from './ImmutableTodo.html';
import MutableTodo from './MutableTodo.html';
export default {
immutable: true,
methods: {
toggle(id) {
const { todos } = this.get();
this.set({
todos: todos.map(todo => {
if (todo.id === id) {
// return a new object
return {
id,
done: !todo.done,
text: todo.text
};
}
// return the same object
return todo;
})
});
}
},
components: { ImmutableTodo, MutableTodo }
}
</script>

@ -1,17 +1,19 @@
<!-- the text will flash red whenever <svelte:meta immutable/>
the `todo` object changes -->
<span ref:span>{todo.text}</span>
<script> <script>
export default { import { afterRender } from 'svelte';
// try commenting this out
immutable: true, export let todo;
let span;
onupdate({ changed, current, previous }) { afterRender(() => {
this.refs.span.style.color = 'red'; span.style.color = 'red';
setTimeout(() => { setTimeout(() => {
this.refs.span.style.color = 'black'; span.style.color = 'black';
}, 400); }, 400);
} });
};
</script> </script>
<!-- the text will flash red whenever
the `todo` object changes -->
<span ref:span>{todo.text}</span>

@ -1,14 +1,17 @@
<span ref:span>{todo.text}</span>
<script> <script>
export default { import { afterRender } from 'svelte';
immutable: false,
export let todo;
let span;
onupdate({ changed, current, previous }) { afterRender(() => {
this.refs.span.style.color = 'red'; span.style.color = 'red';
setTimeout(() => { setTimeout(() => {
this.refs.span.style.color = 'black'; span.style.color = 'black';
}, 400); }, 400);
} });
};
</script> </script>
<!-- the text will flash red whenever
the `todo` object changes -->
<span ref:span>{todo.text}</span>

@ -1,32 +1,79 @@
<svelte:window on:resize='resize()'/> <script>
import { onMount } from 'svelte';
import { scaleLinear } from 'd3-scale';
export let points;
const yTicks = [0, 2, 4, 6, 8];
const xTicks = [1980, 1990, 2000, 2010];
const padding = { top: 20, right: 15, bottom: 20, left: 25 };
let svg;
let width = 500;
let height = 200;
<div class='chart'> let xScale;
let yScale;
let minX;
let maxX;
let path;
let area;
$: xScale = scaleLinear()
.domain([minX, maxX])
.range([padding.left, width - padding.right]);
$: yScale = scaleLinear
.domain([Math.min.apply(null, yTicks), Math.max.apply(null, yTicks)])
.range([height - padding.bottom, padding.top]);
$: minX = points[0].x;
$: maxX = points[points.length - 1].x;
$: 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`;
function formatMobile (tick) {
return "'" + tick % 100;
}
function resize() {
const bcr = svg.getBoundingClientRect();
width = bcr.width;
height = bcr.height;
}
onMount(resize);
</script>
<svelte:window on:resize='{resize}'/>
<div class="chart">
<h2>Arctic sea ice minimum</h2> <h2>Arctic sea ice minimum</h2>
<svg ref:svg> <svg ref:svg>
<!-- y axis --> <!-- y axis -->
<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%"></line>
<text y='-4'>{tick} {tick === 8 ? ' million sq km' : ''}</text> <text y="-4">{tick} {tick === 8 ? ' million sq km' : ''}</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 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"></line>
<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>
<path class='path-line' d='{path}'></path> <path class="path-line" d={path}></path>
</svg> </svg>
<p>Average September extent. Source: <a href='https://climate.nasa.gov/vital-signs/arctic-sea-ice/'>NSIDC/NASA</a> <p>Average September extent. Source: <a href='https://climate.nasa.gov/vital-signs/arctic-sea-ice/'>NSIDC/NASA</a>
@ -79,75 +126,4 @@
.path-area { .path-area {
fill: rgba(0,100,100,0.2); fill: rgba(0,100,100,0.2);
} }
</style> </style>
<script>
import { scaleLinear } from 'd3-scale';
const xScale = scaleLinear();
const yScale = scaleLinear();
export default {
data() {
return {
padding: { top: 20, right: 15, bottom: 20, left: 25 },
height: 200,
width: 500,
xTicks: [1980, 1990, 2000, 2010],
yTicks: [0, 2, 4, 6, 8],
formatMobile(tick) {
return "'" + tick % 100;
}
};
},
computed: {
minX: ({ points }) => {
return points[0].x;
},
maxX: ({ points }) => {
return points[points.length - 1].x;
},
xScale: ({ padding, width, minX, maxX }) => {
return xScale
.domain([minX, maxX])
.range([padding.left, width - padding.right]);
},
yScale: ({ padding, height, yTicks }) => {
return yScale
.domain([Math.min.apply(null, yTicks), Math.max.apply(null, yTicks)])
.range([height - padding.bottom, padding.top]);
},
path: ({ points, xScale, yScale }) => {
return 'M' + points
.map(function (point, i) {
return xScale(point.x) + ',' + yScale(point.y);
})
.join('L');
},
area: ({ points, xScale, yScale, minX, maxX, path }) => {
return path + (
'L' + xScale(maxX) + ',' + yScale(0) +
'L' + xScale(minX) + ',' + yScale(0) +
'Z'
);
}
},
oncreate() {
this.resize();
},
methods: {
resize: function () {
const { width, height } = this.refs.svg.getBoundingClientRect();
this.set({ width, height });
}
}
};
</script>

@ -1,6 +1,12 @@
<script>
import Modal from './Modal.html';
export let showModal;
</script>
{#if showModal} {#if showModal}
<Modal on:close='set({ showModal: false })'> <Modal on:close="{() => showModal = false}">
<h2 slot='header'> <h2 slot="header">
modal modal
<small><em>adjective</em> mod·al \ˈmō-dəl\</small> <small><em>adjective</em> mod·al \ˈmō-dəl\</small>
</h2> </h2>
@ -14,20 +20,10 @@
<li>of or relating to a statistical mode</li> <li>of or relating to a statistical mode</li>
</ol> </ol>
<a href='https://www.merriam-webster.com/dictionary/modal'>merriam-webster.com</a> <a href="https://www.merriam-webster.com/dictionary/modal">merriam-webster.com</a>
</Modal> </Modal>
{:else} {:else}
<button on:click='set({ showModal: true })'> <button on:click="{() => showModal = true}">
show modal show modal
</button> </button>
{/if} {/if}
<script>
import Modal from './Modal.html';
export default {
components: {
Modal
}
};
</script>

@ -1,4 +1,10 @@
<div class='modal-background' on:click='fire("close")'></div> <script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<div class='modal-background' on:click='{() => dispatch("close")}'></div>
<div class='modal'> <div class='modal'>
<slot name='header'></slot> <slot name='header'></slot>
@ -6,7 +12,7 @@
<slot></slot> <slot></slot>
<hr> <hr>
<button on:click='fire("close")'>close modal</button> <button on:click='{() => dispatch("close")}'>close modal</button>
</div> </div>
<style> <style>

@ -1,12 +1,6 @@
<p>This is a top-level element.</p>
<Nested/>
<script> <script>
import Nested from './Nested.html'; import Nested from './Nested.html';
</script>
export default { <p>This is a top-level element.</p>
components: { <Nested/>
Nested
}
};
</script>

@ -1,21 +1,21 @@
<!-- this binds `sy` to the current value of `window.scrollY` --> <!-- this binds `sy` to the current value of `window.scrollY` -->
<svelte:window bind:scrollY='sy'/> <svelte:window bind:scrollY={sy}/>
<!-- try changing the values that `sy` is multiplied by - <!-- try changing the values that `sy` is multiplied by -
values closer to 0 appear further away --> values closer to 0 appear further away -->
<div class='parallax-container'> <div class="parallax-container">
<img style='transform: translate(0,{-sy * 0.2}px)' src='http://www.firewatchgame.com/images/parallax/parallax0.png'> <img style="transform: translate(0,{-sy * 0.2}px)" src="http://www.firewatchgame.com/images/parallax/parallax0.png">
<img style='transform: translate(0,{-sy * 0.3}px)' src='http://www.firewatchgame.com/images/parallax/parallax1.png'> <img style="transform: translate(0,{-sy * 0.3}px)" src="http://www.firewatchgame.com/images/parallax/parallax1.png">
<img style='transform: translate(0,{-sy * 0.4}px)' src='http://www.firewatchgame.com/images/parallax/parallax3.png'> <img style="transform: translate(0,{-sy * 0.4}px)" src="http://www.firewatchgame.com/images/parallax/parallax3.png">
<img style='transform: translate(0,{-sy * 0.5}px)' src='http://www.firewatchgame.com/images/parallax/parallax5.png'> <img style="transform: translate(0,{-sy * 0.5}px)" src="http://www.firewatchgame.com/images/parallax/parallax5.png">
<img style='transform: translate(0,{-sy * 0.6}px)' src='http://www.firewatchgame.com/images/parallax/parallax7.png'> <img style="transform: translate(0,{-sy * 0.6}px)" src="http://www.firewatchgame.com/images/parallax/parallax7.png">
</div> </div>
<div class='text'> <div class="text">
<small style=' <small style="
transform: translate(0,{-sy * 1.5}px); transform: translate(0,{-sy * 1.5}px);
opacity: {1 - Math.max( 0, sy / 80 )} opacity: {1 - Math.max( 0, sy / 80 )}
'>(scroll down)</small> ">(scroll down)</small>
<span>parallax has never been this easy</span> <span>parallax has never been this easy</span>
</div> </div>

@ -1,10 +1,19 @@
<div class='chart'> <script>
import Scatterplot from './Scatterplot.html';
export let a;
export let b;
export let c;
export let d;
</script>
<div class="chart">
<h2>Anscombe's quartet</h2> <h2>Anscombe's quartet</h2>
<Scatterplot points='{a}'/> <Scatterplot points={a}/>
<Scatterplot points='{b}'/> <Scatterplot points={b}/>
<Scatterplot points='{c}'/> <Scatterplot points={c}/>
<Scatterplot points='{d}'/> <Scatterplot points={d}/>
</div> </div>
<style> <style>
@ -16,14 +25,4 @@
max-height: 480px; max-height: 480px;
margin: 0 auto; margin: 0 auto;
} }
</style> </style>
<script>
import Scatterplot from './Scatterplot.html';
export default {
components: {
Scatterplot
}
};
</script>

@ -1,11 +1,62 @@
<svelte:window on:resize='resize()'/> <script>
// TODO this example needs updating
import { onMount } from 'svelte';
import { scaleLinear } from 'd3-scale';
export let svg;
const xScale = scaleLinear();
const yScale = scaleLinear();
export let width = 500;
export let height = 200;
export let padding = { top: 20, right: 40, bottom: 40, left: 25 };
export let points;
export let xTicks = [0, 4, 8, 12, 16, 20];
export let yTicks = [0, 2, 4, 6, 8, 10, 12];
function xTicks() {
return width > 180 ?
[0, 4, 8, 12, 16, 20] :
[0, 10, 20];
}
function yTicks() {
return height > 180 ?
[0, 2, 4, 6, 8, 10, 12] :
[0, 4, 8, 12];
}
function xScale() {
return xScale()
.domain([0, 20])
.range([padding.left, width - padding.right]);
}
function yScale() {
return yScale()
.domain([0, 12])
.range([height - padding.bottom, padding.top]);
}
onMount(() => {
resize();
});
function resize() {
const { width, height } = svg.getBoundingClientRect();
width = width, height = height;
}
</script>
<svelte:window on:resize='{resize}'/>
<svg ref:svg> <svg ref: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}
@ -14,8 +65,8 @@
<!-- 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}
@ -23,7 +74,7 @@
<!-- 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>
@ -57,60 +108,4 @@
.y-axis text { .y-axis text {
text-anchor: end; text-anchor: end;
} }
</style> </style>
<script>
import { scaleLinear } from 'd3-scale';
const xScale = scaleLinear();
const yScale = scaleLinear();
export default {
data() {
return {
padding: { top: 20, right: 40, bottom: 40, left: 25 },
height: 200,
width: 500,
xTicks: [0, 4, 8, 12, 16, 20],
yTicks: [0, 2, 4, 6, 8, 10, 12]
};
},
computed: {
xTicks: ({ width }) => {
return width > 180 ?
[0, 4, 8, 12, 16, 20] :
[0, 10, 20];
},
yTicks: ({ height }) => {
return height > 180 ?
[0, 2, 4, 6, 8, 10, 12] :
[0, 4, 8, 12];
},
xScale: ({ padding, width }) => {
return xScale
.domain([0, 20])
.range([padding.left, width - padding.right]);
},
yScale: ({ padding, height }) => {
return yScale
.domain([0, 12])
.range([height - padding.bottom, padding.top]);
}
},
oncreate() {
this.resize();
},
methods: {
resize() {
const { width, height } = this.refs.svg.getBoundingClientRect();
this.set({ width, height });
}
}
};
</script>

@ -1,4 +1,4 @@
<div class='foo'> <div class="foo">
Big red Comic Sans Big red Comic Sans
</div> </div>

@ -2,7 +2,7 @@
<li>{node.name} <li>{node.name}
{#if node.children} {#if node.children}
{#each node.children as child} {#each node.children as child}
<svelte:self node='{child}'/> <svelte:self node={child}/>
{/each} {/each}
{/if} {/if}
</li> </li>

@ -1,3 +1,28 @@
<script>
import { onMount } from 'svelte';
export let time = new Date();
let hours, minutes, seconds;
$: {
// this block runs reactively, whenever
// `time` changes
hours = time.getHours();
minutes = time.getMinutes();
seconds = time.getSeconds();
}
onMount(() => {
const interval = setInterval(() => {
time = new Date();
}, 1000);
return () => {
clearInterval(interval);
};
});
</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'/>
@ -72,30 +97,4 @@
.second-counterweight { .second-counterweight {
stroke-width: 3; stroke-width: 3;
} }
</style> </style>
<script>
export default {
data() {
return {
time: new Date()
};
},
computed: {
hours: ({ time }) => time.getHours(),
minutes: ({ time }) => time.getMinutes(),
seconds: ({ time }) => time.getSeconds()
},
oncreate() {
this.interval = setInterval(() => {
this.set({ time: new Date() });
}, 1000);
},
ondestroy() {
clearInterval(this.interval);
}
};
</script>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -1,7 +1,31 @@
<input type='checkbox' bind:checked=visible> visible <script>
import * as eases from 'eases-jsnext';
import { fade } from 'svelte-transitions';
export let visible;
const wheee = (node, params) => {
return {
duration: params.duration,
css: t => {
const eased = eases.elasticOut(t);
return `
transform: scale(${eased}) rotate(${eased * 1080}deg);
color: hsl(
${~~(t * 360)},
${Math.min(100, 1000 - 1000 * t)}%,
${Math.min(50, 500 - 500 * t)}%
);`
}
};
};
</script>
<input type=checkbox bind:checked={visible}> visible
{#if visible} {#if visible}
<div class='centered' in:wheee='{duration: 8000}' out:fade> <div class="centered" in:wheee="{{duration: 8000}}" out:fade>
<span>wheeee!!!!!</span> <span>wheeee!!!!!</span>
</div> </div>
{/if} {/if}
@ -20,31 +44,3 @@
font-size: 4em; font-size: 4em;
} }
</style> </style>
<script>
import * as eases from 'eases-jsnext';
import { fade } from 'svelte-transitions';
export default {
transitions: {
wheee: (node, params) => {
return {
duration: params.duration,
css: t => {
const eased = eases.elasticOut(t);
return `
transform: scale(${eased}) rotate(${eased * 1080}deg);
color: hsl(
${~~(t * 360)},
${Math.min(100, 1000 - 1000 * t)}%,
${Math.min(50, 500 - 500 * t)}%
);`
}
};
},
fade
}
};
</script>

@ -1,13 +1,11 @@
<input type='checkbox' bind:checked=visible> visible
{#if visible}
<p transition:fade>fades in and out</p>
{/if}
<script> <script>
import { fade } from 'svelte-transitions'; import { fade } from 'svelte-transitions';
export default { export let visible;
transitions: { fade } </script>
};
</script> <input type=checkbox bind:checked={visible}> visible
{#if visible}
<p transition:fade>fades in and out</p>
{/if}

@ -1,13 +1,11 @@
<input type='checkbox' bind:checked=visible> visible
{#if visible}
<p transition:fly='{y: 200, duration: 1000}'>flies 200 pixels up, slowly</p>
{/if}
<script> <script>
import { fly } from 'svelte-transitions'; import { fly } from 'svelte-transitions';
export default { export let visible;
transitions: { fly } </script>
};
</script> <input type=checkbox bind:checked={visible}> visible
{#if visible}
<p transition:fly="{{y: 200, duration: 1000}}">flies 200 pixels up, slowly</p>
{/if}

@ -1,13 +1,11 @@
<input type='checkbox' bind:checked=visible> visible
{#if visible}
<p in:fly='{y: 50}' out:fade>flies up, fades out</p>
{/if}
<script> <script>
import { fade, fly } from 'svelte-transitions'; import { fade, fly } from 'svelte-transitions';
export default { export let visible;
transitions: { fade, fly } </script>
};
</script> <input type=checkbox bind:checked={visible}> visible
{#if visible}
<p in:fly="{{y: 50}}" out:fade>flies up, fades out</p>
{/if}
Loading…
Cancel
Save