Skip to content

Commit f7b3fe2

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

File tree

3 files changed

+524
-19
lines changed

3 files changed

+524
-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: 81 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",
@@ -131,12 +136,63 @@ export default () => {
131136
const [index, setIndex] = useState(0);
132137

133138
const onChanged = (e) => {
139+
const cameraPos = e.currentTarget.camera.position;
134140
setIndex(e.index);
141+
setOpacity(1);
142+
setSelectedWidth(`${tabRef.current[e.index]?.getBoundingClientRect().width}px`);
143+
setPanelCount(groups[e.index].panels.length);
144+
};
145+
146+
const onSideChanged = (e) => {
147+
setPage(page.map((prev, i) => {
148+
if (i < e.mainIndex) {
149+
e.index = e.index - groups[i].panels.length;
150+
} else if (i === e.mainIndex) {
151+
return e.index;
152+
}
153+
return prev;
154+
}));
135155
};
136156

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

142198
const onTabClick = (i: number) => {
@@ -148,18 +204,19 @@ export default () => {
148204

149205
useEffect(() => {
150206
flicking.current?.moveTo(0, 0);
207+
setSelectedWidth(`${tabRef.current[0]?.getBoundingClientRect().width}px`);
151208
}, []);
152209

153210
return (
154211
<div className="demo">
155212
<div className="labels">
156-
<a
213+
{selectedWidth && <a
157214
className="area selected"
158-
style={{transform: `translate(${transform}px)`}}
215+
style={{ width: selectedWidth, transform: `translate(${transform}px)` }}
159216
>
160-
</a>
217+
</a>}
161218
{groups.map((item, i) => (
162-
<div className="tab" key={i}>
219+
<div className="tab" ref={el => tabRef.current[i] = el} key={i}>
163220
<a
164221
className={"label " + (index === i ? "" : "")}
165222
onClick={() => onTabClick(i)}
@@ -172,14 +229,17 @@ export default () => {
172229
<CrossFlicking
173230
className="main"
174231
ref={flicking}
175-
bounce={1}
232+
bounce={0.1}
176233
preventDefaultOnDrag={true}
177234
moveType={"strict"}
178235
sideOptions={{
236+
bounce: 0.1,
179237
moveType: "strict",
180238
}}
181239
onMove={onMove}
240+
onSideMove={onSideMove}
182241
onChanged={onChanged}
242+
onSideChanged={onSideChanged}
183243
>
184244
{groups.map((item, i) => {
185245
return (
@@ -188,21 +248,26 @@ export default () => {
188248
return (
189249
<div className="item" key={j}>
190250
<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>
199251
</div>
200252
);
201253
})}
202254
</CrossGroup>
203255
);
204256
})}
205257
</CrossFlicking>
258+
<div className="info" style={{ opacity: opacity }}>
259+
<div className="name">
260+
<span className="source">
261+
{groups[index].name} Wallpaper
262+
</span>
263+
</div>
264+
<strong className="headline">{groups[index].panels[page[index]].title}</strong>
265+
</div>
266+
<div className="page">
267+
{Array.from({ length: panelCount }).map((_, i) => {
268+
return <span key={i} className={`dot ${i === page[index] ? "on" : ""}`}>{i + 1}</span>;
269+
})}
270+
</div>
206271
</div>
207272
);
208273
};

0 commit comments

Comments
 (0)