Skip to content

Commit 4f26363

Browse files
committed
update deferred transitions example
1 parent 8669c76 commit 4f26363

File tree

4 files changed

+228
-178
lines changed

4 files changed

+228
-178
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,153 @@
11
<script>
2-
import { quintOut } from 'svelte/easing';
3-
import crossfade from './crossfade.js'; // TODO put this in svelte/transition!
4-
5-
const { send, receive } = crossfade({
6-
fallback(node, params) {
7-
const style = getComputedStyle(node);
8-
const transform = style.transform === 'none' ? '' : style.transform;
9-
10-
return {
11-
duration: 600,
12-
easing: quintOut,
13-
css: t => `
14-
transform: ${transform} scale(${t});
15-
opacity: ${t}
16-
`
17-
};
18-
}
2+
import { crossfade, scale } from 'svelte/transition';
3+
import images from './images.js';
4+
5+
const [send, receive] = crossfade({
6+
duration: 200,
7+
fallback: scale
198
});
209
21-
let todos = [
22-
{ id: 1, done: false, description: 'write some docs' },
23-
{ id: 2, done: false, description: 'start writing JSConf talk' },
24-
{ id: 3, done: true, description: 'buy some milk' },
25-
{ id: 4, done: false, description: 'mow the lawn' },
26-
{ id: 5, done: false, description: 'feed the turtle' },
27-
{ id: 6, done: false, description: 'fix some bugs' },
28-
];
29-
30-
let uid = todos.length + 1;
31-
32-
function add(input) {
33-
const todo = {
34-
id: uid++,
35-
done: false,
36-
description: input.value
37-
};
10+
let selected = null;
11+
let loading = null;
3812
39-
todos = [todo, ...todos];
40-
input.value = '';
41-
}
13+
const ASSETS = `https://svelte-assets.surge.sh/crossfade`;
4214
43-
function remove(todo) {
44-
todos = todos.filter(t => t !== todo);
45-
}
15+
const load = image => {
16+
const timeout = setTimeout(() => loading = image, 100);
17+
18+
const img = new Image();
19+
20+
img.onload = () => {
21+
selected = image;
22+
clearTimeout(timeout);
23+
loading = null;
24+
};
25+
26+
img.src = `${ASSETS}/${image.id}.jpg`;
27+
};
4628
</script>
4729

30+
<div class="container">
31+
<div class="phone">
32+
<h1>Photo gallery</h1>
33+
34+
<div class="grid">
35+
{#each images as image}
36+
<div class="square">
37+
{#if selected !== image}
38+
<button
39+
style="background-color: {image.color};"
40+
on:click="{() => load(image)}"
41+
in:receive={{key:image.id}}
42+
out:send={{key:image.id}}
43+
>{loading === image ? '...' : image.id}</button>
44+
{/if}
45+
</div>
46+
{/each}
47+
</div>
48+
49+
{#if selected}
50+
{#await selected then d}
51+
<div class="photo" in:receive={{key:d.id}} out:send={{key:d.id}}>
52+
<img
53+
alt={d.alt}
54+
src="{ASSETS}/{d.id}.jpg"
55+
on:click="{() => selected = null}"
56+
>
57+
58+
<p class='credit'>
59+
<a target="_blank" href="https://www.flickr.com/photos/{d.path}">via Flickr</a> &ndash;
60+
<a target="_blank" href={d.license.url}>{d.license.name}</a>
61+
</p>
62+
</div>
63+
{/await}
64+
{/if}
65+
</div>
66+
</div>
67+
4868
<style>
49-
.new-todo {
50-
font-size: 1.4em;
69+
.container {
70+
position: absolute;
71+
display: flex;
72+
align-items: center;
73+
justify-content: center;
5174
width: 100%;
52-
margin: 2em 0 1em 0;
75+
height: 100%;
76+
top: 0;
77+
left: 0;
5378
}
5479
55-
.board {
56-
max-width: 36em;
57-
margin: 0 auto;
80+
.phone {
81+
position: relative;
82+
display: flex;
83+
flex-direction: column;
84+
width: 52vmin;
85+
height: 76vmin;
86+
border: 2vmin solid #ccc;
87+
border-bottom-width: 10vmin;
88+
padding: 3vmin;
89+
border-radius: 2vmin;
5890
}
5991
60-
.left, .right {
61-
float: left;
62-
width: 50%;
63-
padding: 0 1em 0 0;
64-
box-sizing: border-box;
92+
h1 {
93+
font-weight: 300;
94+
text-transform: uppercase;
95+
font-size: 5vmin;
96+
margin: 0.2em 0 0.5em 0;
6597
}
6698
67-
h2 {
68-
font-size: 2em;
69-
font-weight: 200;
70-
user-select: none;
99+
.grid {
100+
display: grid;
101+
flex: 1;
102+
grid-template-columns: repeat(3, 1fr);
103+
grid-template-rows: repeat(4, 1fr);
104+
grid-gap: 2vmin;
71105
}
72106
73-
label {
107+
button {
108+
width: 100%;
109+
height: 100%;
110+
color: white;
111+
font-size: 5vmin;
112+
border: none;
113+
margin: 0;
114+
will-change: transform;
115+
}
116+
117+
.photo, img {
118+
position: absolute;
74119
top: 0;
75120
left: 0;
76-
display: block;
77-
font-size: 1em;
78-
line-height: 1;
79-
padding: 0.5em;
80-
margin: 0 auto 0.5em auto;
81-
border-radius: 2px;
82-
background-color: #eee;
83-
user-select: none;
121+
width: 100%;
122+
height: 100%;
123+
overflow: hidden;
84124
}
85125
86-
input { margin: 0 }
87-
88-
.right label {
89-
background-color: rgb(180,240,100);
126+
.photo {
127+
display: flex;
128+
align-items: stretch;
129+
justify-content: flex-end;
130+
flex-direction: column;
131+
will-change: transform;
90132
}
91133
92-
button {
93-
float: right;
94-
height: 1em;
95-
box-sizing: border-box;
96-
padding: 0 0.5em;
97-
line-height: 1;
98-
background-color: transparent;
99-
border: none;
100-
color: rgb(170,30,30);
101-
opacity: 0;
102-
transition: opacity 0.2s;
134+
img {
135+
object-fit: cover;
136+
cursor: pointer;
103137
}
104138
105-
label:hover button {
106-
opacity: 1;
139+
.credit {
140+
text-align: right;
141+
font-size: 2.5vmin;
142+
padding: 1em;
143+
margin: 0;
144+
color: white;
145+
font-weight: bold;
146+
opacity: 0.6;
147+
background: rgba(0,0,0,0.4);
107148
}
108-
</style>
109-
110-
<div class='board'>
111-
<input class="new-todo" placeholder="what needs to be done?" on:keydown="{event => event.which === 13 && add(event.target)}">
112-
113-
<div class='left'>
114-
<h2>todo</h2>
115-
{#each todos.filter(t => !t.done) as todo (todo.id)}
116-
<label
117-
in:receive="{{key: todo.id}}"
118-
out:send="{{key: todo.id}}"
119-
>
120-
<input type=checkbox bind:checked={todo.done}>
121-
{todo.description}
122-
<button on:click="{() => remove(todo)}">x</button>
123-
</label>
124-
{/each}
125-
</div>
126149
127-
<div class='right'>
128-
<h2>done</h2>
129-
{#each todos.filter(t => t.done) as todo (todo.id)}
130-
<label
131-
in:receive="{{key: todo.id}}"
132-
out:send="{{key: todo.id}}"
133-
>
134-
<input type=checkbox bind:checked={todo.done}>
135-
{todo.description}
136-
<button on:click="{() => remove(todo)}">x</button>
137-
</label>
138-
{/each}
139-
</div>
140-
</div>
150+
.credit a, .credit a:visited {
151+
color: white;
152+
}
153+
</style>

site/content/examples/09-transitions/06-deferred-transitions/crossfade.js

-65
This file was deleted.

0 commit comments

Comments
 (0)