Fix changing items
This commit is contained in:
@@ -1,31 +1,42 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
|
import { custom } from './transition'
|
||||||
|
|
||||||
import { generateId } from './utils/id'
|
import { generateId } from './utils/id'
|
||||||
import { store } from './store'
|
import { store } from './store'
|
||||||
|
|
||||||
|
let container
|
||||||
const id = generateId()
|
const id = generateId()
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
store.setItem(id)
|
store.setItem(id)
|
||||||
|
// console.log(container)
|
||||||
return () => {
|
return () => {
|
||||||
store.removeItem(id)
|
store.removeItem(id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let isActive = false
|
||||||
|
$: {
|
||||||
|
isActive = id === $store.currentItemId
|
||||||
|
// console.log(container && container.clientWidth)
|
||||||
|
// if (container) container.style.left = `${-container.clientWidth + 50}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
const getW = () => {
|
||||||
|
return container && container.clientWidth || 0
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if id === $store.currentItemId}
|
|
||||||
<div
|
<div
|
||||||
|
bind:this={container}
|
||||||
class="main-container"
|
class="main-container"
|
||||||
in:fly="{{ x: 200, duration: 200, delay: 200 }}"
|
|
||||||
out:fly="{{ x: -200, duration: 200 }}"
|
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
{/if }
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.main-container {
|
.main-container {
|
||||||
width: 100%;
|
background-color: darkgrey;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,16 +14,28 @@
|
|||||||
export let infinite = true;
|
export let infinite = true;
|
||||||
|
|
||||||
let contentContainerElement
|
let contentContainerElement
|
||||||
|
let innerContentContainerElement
|
||||||
let children
|
let children
|
||||||
|
let w = 0
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
children = contentContainerElement.children
|
children = innerContentContainerElement.children
|
||||||
|
console.log('children', children.length)
|
||||||
|
w = contentContainerElement.clientWidth
|
||||||
|
for (let i=0; i<children.length; i++) {
|
||||||
|
store.setItem()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let offset
|
||||||
function handlePrevClick() {
|
function handlePrevClick() {
|
||||||
store.prev({ infinite })
|
store.prev({ infinite })
|
||||||
|
offset = -$store.currentItemIndex * children[$store.currentItemIndex].clientWidth
|
||||||
}
|
}
|
||||||
function handleNextClick() {
|
function handleNextClick() {
|
||||||
store.next({ infinite })
|
store.next({ infinite })
|
||||||
|
console.log('currentItemId', $store.currentItemId)
|
||||||
|
offset = -$store.currentItemIndex * children[$store.currentItemIndex].clientWidth
|
||||||
|
console.log('offset', offset, children[$store.currentItemIndex].clientWidth)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -36,9 +48,17 @@
|
|||||||
><</span>
|
><</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="content-container" bind:this={contentContainerElement}>
|
<div
|
||||||
|
class="content-container"
|
||||||
|
bind:this={contentContainerElement}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="transform: translateX({offset}px);"
|
||||||
|
bind:this={innerContentContainerElement}
|
||||||
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{#if arrows}
|
{#if arrows}
|
||||||
<div class="side-container">
|
<div class="side-container">
|
||||||
<span
|
<span
|
||||||
@@ -57,6 +77,12 @@
|
|||||||
.content-container {
|
.content-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content-container > div {
|
||||||
|
display: flex;
|
||||||
|
transition: transform 1s ease-in-out;
|
||||||
|
background-color: chocolate;
|
||||||
}
|
}
|
||||||
.side-container {
|
.side-container {
|
||||||
background-color: cornflowerblue;
|
background-color: cornflowerblue;
|
||||||
|
|||||||
21
src/store.js
21
src/store.js
@@ -1,16 +1,21 @@
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
import { v4 as uuid } from 'uuid'
|
||||||
import { getNextItemIndexFn, getPrevItemIndexFn } from './utils/item-index'
|
import { getNextItemIndexFn, getPrevItemIndexFn } from './utils/item-index'
|
||||||
|
|
||||||
|
|
||||||
function createStore() {
|
function createStore() {
|
||||||
const { subscribe, set, update } = writable({
|
const { subscribe, set, update } = writable({
|
||||||
items: [],
|
items: [],
|
||||||
currentItemId: null
|
currentItemId: null,
|
||||||
|
currentItemIndex: null,
|
||||||
|
action: 'next'
|
||||||
});
|
});
|
||||||
|
|
||||||
function setItem(id) {
|
function setItem(id = uuid()) {
|
||||||
update(store => ({
|
update(store => ({
|
||||||
...store,
|
...store,
|
||||||
currentItemId: id,
|
currentItemId: id,
|
||||||
|
currentItemIndex: 0, // store.items.length - 1, TODO: use as a param
|
||||||
items: [
|
items: [
|
||||||
...store.items,
|
...store.items,
|
||||||
id
|
id
|
||||||
@@ -27,22 +32,26 @@ function createStore() {
|
|||||||
|
|
||||||
function next({ infinite }) {
|
function next({ infinite }) {
|
||||||
update(store => {
|
update(store => {
|
||||||
const currentItemIndex = store.items.findIndex(item => item === store.currentItemId)
|
const currentItemIndex = store.currentItemIndex // store.items.findIndex(item => item === store.currentItemId)
|
||||||
const newCurrentItemIndex = getNextItemIndexFn(infinite)(currentItemIndex, store.items)
|
const newCurrentItemIndex = getNextItemIndexFn(infinite)(currentItemIndex, store.items)
|
||||||
return {
|
return {
|
||||||
...store,
|
...store,
|
||||||
currentItemId: store.items[newCurrentItemIndex]
|
currentItemId: store.items[newCurrentItemIndex],
|
||||||
|
currentItemIndex: newCurrentItemIndex,
|
||||||
|
action: 'next'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function prev({ infinite }) {
|
function prev({ infinite }) {
|
||||||
update(store => {
|
update(store => {
|
||||||
const currentItemIndex = store.items.findIndex(item => item === store.currentItemId)
|
const currentItemIndex = store.currentItemIndex // store.items.findIndex(item => item === store.currentItemId)
|
||||||
const newCurrentItemIndex = getPrevItemIndexFn(infinite)(currentItemIndex, store.items)
|
const newCurrentItemIndex = getPrevItemIndexFn(infinite)(currentItemIndex, store.items)
|
||||||
return {
|
return {
|
||||||
...store,
|
...store,
|
||||||
currentItemId: store.items[newCurrentItemIndex]
|
currentItemId: store.items[newCurrentItemIndex],
|
||||||
|
currentItemIndex: newCurrentItemIndex,
|
||||||
|
action: 'prev'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,16 +18,28 @@
|
|||||||
{arrows}
|
{arrows}
|
||||||
{infinite}
|
{infinite}
|
||||||
>
|
>
|
||||||
<CarouselChild>
|
|
||||||
<div class="child-content-container">
|
<div
|
||||||
|
class="child-content-container"
|
||||||
|
style="background-color: green;"
|
||||||
|
>
|
||||||
<h1>Element 1</h1>
|
<h1>Element 1</h1>
|
||||||
</div>
|
</div>
|
||||||
</CarouselChild>
|
|
||||||
<CarouselChild>
|
<div
|
||||||
<div class="child-content-container">
|
class="child-content-container"
|
||||||
|
style="background-color: yellow;"
|
||||||
|
>
|
||||||
<h1>Element 2</h1>
|
<h1>Element 2</h1>
|
||||||
</div>
|
</div>
|
||||||
</CarouselChild>
|
|
||||||
|
<div
|
||||||
|
class="child-content-container"
|
||||||
|
style="background-color: blue;"
|
||||||
|
>
|
||||||
|
<h1>Element 3</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
</ImageCarousel>
|
</ImageCarousel>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -37,8 +49,8 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.child-content-container {
|
.child-content-container {
|
||||||
width: 100%;
|
width: 500px;
|
||||||
display: flex;
|
height: 100px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/transition.js
Normal file
16
src/transition.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { cubicIn } from 'svelte/easing';
|
||||||
|
|
||||||
|
export function custom(node, { duration, offset }) {
|
||||||
|
console.log(node.style.left)
|
||||||
|
return {
|
||||||
|
duration,
|
||||||
|
css: t => {
|
||||||
|
const eased = cubicIn(t);
|
||||||
|
// console.log(Math.round(offset/t))
|
||||||
|
// transform: translate(${Math.round(offset/t)}px);
|
||||||
|
return `
|
||||||
|
transform: translate(${Math.round(offset/t)}px);
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user