Skip to content

Commit 77736df

Browse files
committed
docs: update CrossFlicking demo features
1 parent 3056e55 commit 77736df

File tree

3 files changed

+520
-19
lines changed

3 files changed

+520
-19
lines changed

docs/src/css/demo/crossflicking.css

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@
3838
}
3939

4040
.label {
41-
display: block;
41+
display: flex;
42+
justify-content: center;
4243
cursor: pointer;
43-
padding: 0 12px;
44+
width: 80px;
4445
line-height: 36px;
4546
font-size: 16px;
4647
color: rgba(255, 255, 255, 0.6);
@@ -63,11 +64,13 @@
6364

6465
.info {
6566
position: absolute;
67+
z-index: 3;
6668
bottom: 36px;
6769
left: 0;
6870
right: 0;
6971
max-height: 72px;
7072
margin: auto 20px;
73+
transition: all .25s ease-in-out;
7174
}
7275

7376
.name {
@@ -98,8 +101,40 @@
98101

99102
.area {
100103
position: absolute;
101-
width: 85px;
104+
left: 0px;
102105
height: 40px;
103106
-webkit-border-radius: 100px;
104107
border-radius: 100px;
108+
transition: width .5s;
109+
}
110+
111+
.page {
112+
position: absolute;
113+
top: 50%;
114+
right: 0;
115+
margin-right: 12px;
116+
transform: translateY(-50%);
117+
display: flex;
118+
flex-direction: column;
119+
z-index: 1;
105120
}
121+
122+
.dot {
123+
overflow: hidden;
124+
width: 5px;
125+
height: 5px;
126+
-webkit-box-flex: 0;
127+
-webkit-flex: 0 0 auto;
128+
flex: 0 0 auto;
129+
-webkit-border-radius: 50%;
130+
border-radius: 50%;
131+
background-color: rgba(255, 255, 255, 0.4);
132+
}
133+
134+
.dot.on {
135+
background-color: rgba(255, 255, 255, 0.8);
136+
}
137+
138+
.dot + .dot {
139+
margin-top: 5px;
140+
}

docs/src/demo/presets/CrossFlicking.tsx

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
/* eslint-disable @typescript-eslint/no-var-requires */
22
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
33
import React, { useEffect, useRef, useState } from "react";
4-
import { CrossFlicking, CrossGroup } from "@egjs/react-flicking";
4+
import { CrossFlicking, CrossGroup, DIRECTION } from "@egjs/react-flicking";
55
import "../../css/demo/crossflicking.css";
66

77
export default () => {
88
const flicking = useRef<CrossFlicking>();
9+
const tabRef = useRef<null[] | HTMLDivElement[]>([]);
10+
const [opacity, setOpacity] = useState(1);
11+
const [page, setPage] = useState([0, 0, 0, 0]);
12+
const [panelCount, setPanelCount] = useState(4);
913
const [transform, setTransform] = useState(0);
14+
const [selectedWidth, setSelectedWidth] = useState("");
1015
const groups = [
1116
{
1217
name: "Spring",
@@ -132,11 +137,59 @@ export default () => {
132137

133138
const onChanged = (e) => {
134139
setIndex(e.index);
140+
setSelectedWidth(`${tabRef.current[e.index]?.getBoundingClientRect().width}px`);
141+
console.log(tabRef.current[e.index]?.getBoundingClientRect());
142+
setPanelCount(groups[e.index].panels.length);
143+
};
144+
145+
const onSideChanged = (e) => {
146+
setPage(page.map((prev, index) => {
147+
if (index < e.mainIndex) {
148+
e.index = e.index - groups[index].panels.length;
149+
} else if (index === e.mainIndex) {
150+
return e.index;
151+
}
152+
return prev;
153+
}));
135154
};
136155

137156
const onMove = (e) => {
138-
const pos = e.currentTarget.camera._position;
139-
setTransform(pos / 4.9 - 46);
157+
const start = tabRef.current[e.currentTarget.index]!.getBoundingClientRect().x - tabRef.current[0]!.getBoundingClientRect().x;
158+
const next = e.currentTarget.index + (e.currentTarget.visiblePanels[0].index === e.currentTarget.index ? 1 : -1);
159+
if (next >= 0 && next <= groups.length - 1) {
160+
const cameraPos = e.currentTarget.camera.position;
161+
const visibleLists = e.currentTarget.visiblePanels.map(p => {
162+
return {
163+
panelIndex: p.index,
164+
diff: p.position - cameraPos,
165+
};
166+
});
167+
const size = e.currentTarget.currentPanel.size;
168+
const half = size / 2;
169+
const end = (tabRef.current[next]!.getBoundingClientRect().x - tabRef.current[e.currentTarget.index]!.getBoundingClientRect().x);
170+
171+
const { diff = 0 } = visibleLists.find(item => item.panelIndex === index) ?? {};
172+
const ratio = Math.max(-1, Math.min(1, Math.abs(diff / size))) || 1;
173+
174+
setOpacity(Math.max(0, Math.min(1, 1 - Math.abs(diff / half))));
175+
setTransform(cameraPos / 4);
176+
}
177+
};
178+
179+
const onSideMove = (e) => {
180+
const cameraPos = e.currentTarget.camera.position;
181+
const visibleLists = e.currentTarget.visiblePanels.map(p => {
182+
return {
183+
panelIndex: p.index,
184+
diff: p.position - cameraPos,
185+
};
186+
});
187+
const size = e.currentTarget.currentPanel.size;
188+
const half = size / 2;
189+
190+
const { diff = 0 } = visibleLists.find(item => item.panelIndex === index) ?? {};;
191+
192+
setOpacity(Math.max(0, Math.min(1, 1 - Math.abs(diff / half))));
140193
};
141194

142195
const onTabClick = (i: number) => {
@@ -148,18 +201,19 @@ export default () => {
148201

149202
useEffect(() => {
150203
flicking.current?.moveTo(0, 0);
204+
setSelectedWidth(`${tabRef.current[0]?.getBoundingClientRect().width}px`);
151205
}, []);
152206

153207
return (
154208
<div className="demo">
155209
<div className="labels">
156-
<a
210+
{selectedWidth && <a
157211
className="area selected"
158-
style={{transform: `translate(${transform}px)`}}
212+
style={{ width: selectedWidth, transform: `translate(${transform}px)` }}
159213
>
160-
</a>
214+
</a>}
161215
{groups.map((item, i) => (
162-
<div className="tab" key={i}>
216+
<div className="tab" ref={el => tabRef.current[i] = el} key={i}>
163217
<a
164218
className={"label " + (index === i ? "" : "")}
165219
onClick={() => onTabClick(i)}
@@ -172,14 +226,16 @@ export default () => {
172226
<CrossFlicking
173227
className="main"
174228
ref={flicking}
175-
bounce={1}
229+
bounce={0.1}
176230
preventDefaultOnDrag={true}
177231
moveType={"strict"}
178232
sideOptions={{
179233
moveType: "strict",
180234
}}
181235
onMove={onMove}
236+
onSideMove={onSideMove}
182237
onChanged={onChanged}
238+
onSideChanged={onSideChanged}
183239
>
184240
{groups.map((item, i) => {
185241
return (
@@ -188,21 +244,26 @@ export default () => {
188244
return (
189245
<div className="item" key={j}>
190246
<img className="img scaleup" src={panel.image} />
191-
<div className="info">
192-
<div className="name">
193-
<span className="source">
194-
{item.name} Wallpaper ({j + 1}/{item.panels.length})
195-
</span>
196-
</div>
197-
<strong className="headline">{panel.title}</strong>
198-
</div>
199247
</div>
200248
);
201249
})}
202250
</CrossGroup>
203251
);
204252
})}
205253
</CrossFlicking>
254+
<div className="info" style={{ opacity: opacity }}>
255+
<div className="name">
256+
<span className="source">
257+
{groups[index].name} Wallpaper ({page[index] + 1}/{groups[index].panels.length})
258+
</span>
259+
</div>
260+
<strong className="headline">{groups[index].panels[page[index]].title}</strong>
261+
</div>
262+
<div className="page">
263+
{Array.from({ length: panelCount }).map((_, i) => {
264+
return <span key={i} className={`dot ${i === page[index] ? "on" : ""}`}>{i + 1}</span>;
265+
})}
266+
</div>
206267
</div>
207268
);
208269
};

0 commit comments

Comments
 (0)