pixuireactcomponents 1.3.54 → 1.3.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -10,5 +10,7 @@ export { OutlineText } from "./src/components/react/base/outlinetext/OutlineText
10
10
  export { FrameAnimation } from "./src/components/react/app/frameAnimation/FrameAnimation";
11
11
  export { AsyncTaskProcessor } from "./src/components/tools/AsyncTaskProcessor";
12
12
  export { assetCache } from "./src/components/tools/assetCache";
13
+ export { frameAnimationJs } from "./src/components/js/frameAnimationJs/frameAnimationJs";
14
+ export { ScrollBar } from "./src/components/react/app/scrollBar/ScrollBar";
13
15
  export { Slider, SliderProps } from "./src/components/react/app/slider/Slider";
14
16
  export { ImgPreLoader, PreLoadPic } from "./src/components/tools/ImgPreLoader";
package/index.js CHANGED
@@ -13,3 +13,5 @@ export { FrameAnimation } from './src/components/react/app/frameAnimation/FrameA
13
13
  export { ImgPreLoader, PreLoadPic } from './src/components/tools/ImgPreLoader';
14
14
  export { AsyncTaskProcessor } from './src/components/tools/AsyncTaskProcessor';
15
15
  export { assetCache } from './src/components/tools/assetCache';
16
+ export { frameAnimationJs } from './src/components/js/frameAnimationJs/frameAnimationJs';
17
+ export { ScrollBar } from './src/components/react/app/scrollBar/ScrollBar';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixuireactcomponents",
3
- "version": "1.3.54",
3
+ "version": "1.3.56",
4
4
  "description": "pixui react components",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,46 @@
1
+ /**
2
+ * FrameAnimation的js版本
3
+ * @param rootId 根节点id
4
+ * @param rootClassName 根节点className
5
+ * @param totalTime 动画总时长
6
+ * @param width 组件宽度
7
+ * @param height 组件高度
8
+ * @param srcArr 图片url数组
9
+ * @param onShow 每一帧显示时的回调
10
+ * @param onFinish 动画结束时的回调
11
+ * @param preloadCount 预加载节点的数量
12
+ * @param loop 是否循环播放
13
+ * @param showLastFrame 播放结束后是否显示最后一帧
14
+ */
15
+ export class frameAnimationJs {
16
+ constructor({ rootId, rootClassName, totalTime, width, height, srcArr, onShow, onFinish, preloadCount, loop, showLastFrame, }: {
17
+ rootId?: string | undefined;
18
+ rootClassName?: string | undefined;
19
+ totalTime: any;
20
+ width: any;
21
+ height: any;
22
+ srcArr: any;
23
+ onShow: any;
24
+ onFinish: any;
25
+ preloadCount?: number | undefined;
26
+ loop?: boolean | undefined;
27
+ showLastFrame?: boolean | undefined;
28
+ });
29
+ rootId: string;
30
+ rootClassName: string;
31
+ totalTime: any;
32
+ width: any;
33
+ height: any;
34
+ srcArr: any;
35
+ onShow: any;
36
+ onFinish: any;
37
+ preloadCount: number;
38
+ loop: boolean;
39
+ showLastFrame: boolean;
40
+ cRefArr: HTMLImageElement[];
41
+ imgEleArr: HTMLImageElement[];
42
+ nextFrame(startTime: any, oneFrameTime: any, showedFrame: any): void;
43
+ rootEle: HTMLDivElement;
44
+ init(): void;
45
+ getRootEle(): HTMLDivElement;
46
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * FrameAnimation的js版本
3
+ * @param rootId 根节点id
4
+ * @param rootClassName 根节点className
5
+ * @param totalTime 动画总时长
6
+ * @param width 组件宽度
7
+ * @param height 组件高度
8
+ * @param srcArr 图片url数组
9
+ * @param onShow 每一帧显示时的回调
10
+ * @param onFinish 动画结束时的回调
11
+ * @param preloadCount 预加载节点的数量
12
+ * @param loop 是否循环播放
13
+ * @param showLastFrame 播放结束后是否显示最后一帧
14
+ */
15
+ var frameAnimationJs = /** @class */ (function () {
16
+ function frameAnimationJs(_a) {
17
+ var _b = _a.rootId, rootId = _b === void 0 ? '' : _b, _c = _a.rootClassName, rootClassName = _c === void 0 ? '' : _c, totalTime = _a.totalTime, width = _a.width, height = _a.height, srcArr = _a.srcArr, onShow = _a.onShow, onFinish = _a.onFinish, _d = _a.preloadCount, preloadCount = _d === void 0 ? 5 : _d, _e = _a.loop, loop = _e === void 0 ? false : _e, _f = _a.showLastFrame, showLastFrame = _f === void 0 ? true : _f;
18
+ var _this = this;
19
+ this.rootId = rootId;
20
+ this.rootClassName = rootClassName;
21
+ this.totalTime = totalTime;
22
+ this.width = width;
23
+ this.height = height;
24
+ this.srcArr = srcArr;
25
+ this.onShow = onShow;
26
+ this.onFinish = onFinish;
27
+ this.preloadCount = preloadCount;
28
+ this.loop = loop;
29
+ this.showLastFrame = showLastFrame;
30
+ this.cRefArr = Array.from({ length: preloadCount }, function () { return document.createElement('img'); });
31
+ this.imgEleArr = Array.from({ length: preloadCount }, function (v, i) {
32
+ _this.cRefArr[i].src = _this.srcArr[i];
33
+ _this.cRefArr[i].style.position = 'absolute';
34
+ _this.cRefArr[i].style.visibility = 'hidden';
35
+ _this.cRefArr[i].style.width = _this.width;
36
+ _this.cRefArr[i].style.height = _this.height;
37
+ return _this.cRefArr[i];
38
+ });
39
+ this.nextFrame = this.nextFrame.bind(this);
40
+ this.rootEle = document.createElement('div');
41
+ console.log('ccc');
42
+ this.init();
43
+ }
44
+ frameAnimationJs.prototype.init = function () {
45
+ var _this = this;
46
+ this.rootEle.style.width = this.width;
47
+ this.rootEle.style.height = this.height;
48
+ this.rootEle.id = this.rootId;
49
+ this.rootEle.className = this.rootClassName;
50
+ this.imgEleArr.forEach(function (ele) {
51
+ _this.rootEle.appendChild(ele);
52
+ });
53
+ var startTime = Date.now();
54
+ var oneFrameTime = this.totalTime / this.srcArr.length;
55
+ //设置第一帧
56
+ this.cRefArr[0].style.visibility = 'visible';
57
+ this.nextFrame(startTime, oneFrameTime, 0);
58
+ };
59
+ //循环修改imgEleArr的src和visibility实现帧动画,,记录上一帧的序号防止跳帧
60
+ frameAnimationJs.prototype.nextFrame = function (startTime, oneFrameTime, showedFrame) {
61
+ var _this = this;
62
+ var nowTime = Date.now();
63
+ //该显示第几帧
64
+ var nowFrame = Math.floor((nowTime - startTime) / oneFrameTime);
65
+ //使用第几个img元素
66
+ var nowArrIndex = nowFrame % this.preloadCount;
67
+ var showedArrIndex = showedFrame % this.preloadCount;
68
+ // console.log('nextFrame', nowFrame, 'nowArrIndex', nowArrIndex, 'nowFrame', nowFrame);
69
+ if (!this.cRefArr[0]) {
70
+ //组件已经被卸载
71
+ this.onFinish && this.onFinish();
72
+ return;
73
+ }
74
+ if (nowFrame >= this.srcArr.length) {
75
+ this.onFinish && this.onFinish();
76
+ if (!this.loop) {
77
+ this.cRefArr.forEach(function (ref, i) {
78
+ ref.style.visibility = 'hidden';
79
+ });
80
+ if (this.showLastFrame) {
81
+ //跳帧的话,最后一帧可能不是最后一张图片,设为最后一张图片
82
+ this.cRefArr[0].src = this.srcArr[this.srcArr.length - 1];
83
+ this.cRefArr[0].style.visibility = 'visible';
84
+ }
85
+ return;
86
+ }
87
+ //重置img标签的 src 和 visibility
88
+ this.cRefArr.forEach(function (ref, i) {
89
+ ref.style.visibility = 'hidden';
90
+ ref.src = _this.srcArr[i];
91
+ });
92
+ startTime = Date.now();
93
+ this.cRefArr[0].style.visibility = 'visible';
94
+ requestAnimationFrame(function () {
95
+ _this.nextFrame(startTime, oneFrameTime, 0);
96
+ });
97
+ return;
98
+ }
99
+ if (nowFrame !== showedFrame) {
100
+ this.cRefArr[nowArrIndex].style.visibility = 'visible';
101
+ //隐藏上一帧
102
+ this.cRefArr[showedArrIndex].style.visibility = 'hidden';
103
+ //可能跳帧,在所有其他的元素上预加载
104
+ this.cRefArr.forEach(function (ref, i) {
105
+ if (i !== nowArrIndex) {
106
+ var offset = (i + _this.cRefArr.length - nowArrIndex) % _this.cRefArr.length;
107
+ var offsetFrame = (nowFrame + offset) % _this.srcArr.length;
108
+ if (ref.src !== _this.srcArr[offsetFrame]) {
109
+ ref.src = _this.srcArr[offsetFrame];
110
+ }
111
+ }
112
+ });
113
+ showedFrame = nowFrame;
114
+ this.onShow && this.onShow(nowFrame);
115
+ }
116
+ requestAnimationFrame(function () {
117
+ _this.nextFrame(startTime, oneFrameTime, showedFrame);
118
+ });
119
+ };
120
+ frameAnimationJs.prototype.getRootEle = function () {
121
+ return this.rootEle;
122
+ };
123
+ return frameAnimationJs;
124
+ }());
125
+ export { frameAnimationJs };
@@ -105,7 +105,7 @@ export function Carousel(props) {
105
105
  var safePrevHandle = useRef();
106
106
  var nextInterval = useRef();
107
107
  var _q = useState(true), showTransition = _q[0], setShowTransition = _q[1];
108
- var _r = useState([0, 0]), gesteroffset = _r[0], setGesteroffset = _r[1];
108
+ var _r = useState([0, 0]), gestureoffset = _r[0], setGestureoffset = _r[1];
109
109
  var offset = useMemo(function () { return -(isVertical ? compHeight : compWidth) * showIndex; }, [showIndex]);
110
110
  var itemBoxStyle = {
111
111
  minWidth: compWidth + 'px',
@@ -156,6 +156,7 @@ export function Carousel(props) {
156
156
  safePrevHandle.current && clearTimeout(safePrevHandle.current);
157
157
  });
158
158
  return function () {
159
+ console.log('Carousel useEffect close');
159
160
  nextInterval.current && clearInterval(nextInterval.current);
160
161
  safeNextHandle.current && clearTimeout(safeNextHandle.current);
161
162
  safePrevHandle.current && clearTimeout(safePrevHandle.current);
@@ -210,22 +211,22 @@ export function Carousel(props) {
210
211
  isMouseDown.current = false;
211
212
  //拖动大于1/3的时候跳转
212
213
  if (isVertical) {
213
- if (gesteroffset[1] > compHeight / 3) {
214
+ if (gestureoffset[1] > compHeight / 3) {
214
215
  handlePrev();
215
216
  }
216
- else if (gesteroffset[1] < -compHeight / 3) {
217
+ else if (gestureoffset[1] < -compHeight / 3) {
217
218
  handleNext();
218
219
  }
219
220
  }
220
221
  else {
221
- if (gesteroffset[0] > compWidth / 3) {
222
+ if (gestureoffset[0] > compWidth / 3) {
222
223
  handlePrev();
223
224
  }
224
- else if (gesteroffset[0] < -compWidth / 3) {
225
+ else if (gestureoffset[0] < -compWidth / 3) {
225
226
  handleNext();
226
227
  }
227
228
  }
228
- setGesteroffset([0, 0]);
229
+ setGestureoffset([0, 0]);
229
230
  setNextInterval();
230
231
  };
231
232
  var gestureMove = function (e) {
@@ -240,7 +241,7 @@ export function Carousel(props) {
240
241
  var b = rect.bottom;
241
242
  var x = e.clientX;
242
243
  var y = e.clientY;
243
- setGesteroffset([e.clientX - mouseDownX.current, e.clientY - mouseDownY.current]);
244
+ setGestureoffset([e.clientX - mouseDownX.current, e.clientY - mouseDownY.current]);
244
245
  //计算滑动超出元素范围
245
246
  if (x < l || x > r || y > b || y < t) {
246
247
  gestureUp();
@@ -289,7 +290,9 @@ export function Carousel(props) {
289
290
  width: isVertical ? compWidth : compWidth * carouselItems.length + 'px',
290
291
  height: isVertical ? compHeight * carouselItems.length : compHeight + 'px',
291
292
  transition: "transform ".concat(showTransition ? '0.5s' : '0s', " ease 0s"),
292
- transform: isVertical ? "translate(0px, ".concat(offset + gesteroffset[1], "px)") : "translate(".concat(offset + gesteroffset[0], "px, 0px)"),
293
+ transform: isVertical
294
+ ? "translate(0px, ".concat(offset + gestureoffset[1], "px)")
295
+ : "translate(".concat(offset + gestureoffset[0], "px, 0px)"),
293
296
  flexDirection: isVertical ? 'column' : 'row',
294
297
  flexShrink: 0,
295
298
  }, class: "wrapper", onTransitionEnd: handleTransitionEnd }, carouselItems.map(function (child) { return child; }))))));
@@ -0,0 +1,17 @@
1
+ import { h } from 'preact';
2
+ export declare let CarouselMulti: (props: {
3
+ rootId?: string | undefined;
4
+ rootClassName?: string | undefined;
5
+ extShowCount: number;
6
+ extShowDist: {
7
+ num: number;
8
+ unit: 'px' | '%' | 'rem';
9
+ };
10
+ animationTime?: number | undefined;
11
+ maxScale?: number | undefined;
12
+ minOpacity?: number | undefined;
13
+ onClick?: ((index: number) => void) | undefined;
14
+ onIndexChange?: ((index: number) => void) | undefined;
15
+ cRef?: any;
16
+ children: h.JSX.Element[];
17
+ }) => h.JSX.Element | null;
@@ -0,0 +1,172 @@
1
+ import { h } from 'preact';
2
+ import { useImperativeHandle, useState, useRef, useEffect } from 'preact/hooks';
3
+ export var CarouselMulti = function (props) {
4
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
5
+ var extShowCount = props.extShowCount, extShowDist = props.extShowDist, rootId = (_a = props.rootId, _a === void 0 ? '' : _a), rootClassName = (_b = props.rootClassName, _b === void 0 ? '' : _b), animationTime = (_c = props.animationTime, _c === void 0 ? 500 : _c), maxScale = (_d = props.maxScale, _d === void 0 ? 1.5 : _d), minOpacity = (_e = props.minOpacity, _e === void 0 ? 0.5 : _e), onClick = props.onClick,
6
+ // fillAndLoop = true,
7
+ onIndexChange = props.onIndexChange;
8
+ //元素不足extShowCount*2+3时,复制原数组到可以播放动画的长度
9
+ var children = (function () {
10
+ var preChildren = props.children;
11
+ // if (fillAndLoop) {
12
+ if (preChildren.length == 0) {
13
+ return [];
14
+ }
15
+ while (preChildren.length < extShowCount * 2 + 3) {
16
+ preChildren = preChildren.concat(props.children);
17
+ }
18
+ // }
19
+ return preChildren;
20
+ })();
21
+ var onload = (_f = useState(false), _f[0]), setOnload = _f[1];
22
+ var zIndexArr = (_g = useState(Array.from({ length: children.length }).map(function () { return 0; })), _g[0]), setZIndexArr = _g[1];
23
+ var opacitiyArr = (_h = useState(Array.from({ length: children.length }).map(function () { return 0; })), _h[0]), setOpacitiyArr = _h[1];
24
+ var showIndex = (_j = useState(Math.floor((props.children.length - 1) / 2)), _j[0]), setShowIndex = _j[1];
25
+ //用于填入 style 的距离
26
+ var getDist = function (num) {
27
+ return num + extShowDist.unit;
28
+ };
29
+ var dragX = useRef(0);
30
+ var isDraging = useRef(false);
31
+ var getMinDist = function (_index, _showindex) { return Math.min(Math.abs(_index - _showindex), children.length - Math.abs(_index - _showindex)); };
32
+ var getLeft = function (index) {
33
+ //计算元素的left,间隔为extShowDist.num,以showIndex为中心,左右两边各显示extShowCount个元素,余下的元素按数组首尾相接的顺序计算 zindex
34
+ var left = -1;
35
+ var minDist = getMinDist(index, showIndex);
36
+ if (index == showIndex) {
37
+ left = extShowCount;
38
+ }
39
+ else if (minDist <= extShowCount) {
40
+ //需要展示
41
+ if (index < showIndex) {
42
+ if (Math.abs(index - showIndex) <= extShowCount) {
43
+ //没跨边界
44
+ left = extShowCount - minDist;
45
+ }
46
+ else {
47
+ left = extShowCount + minDist;
48
+ }
49
+ }
50
+ else if (index > showIndex) {
51
+ if (Math.abs(index - showIndex) <= extShowCount) {
52
+ //没跨边界
53
+ left = extShowCount + minDist;
54
+ }
55
+ else {
56
+ left = extShowCount - minDist;
57
+ }
58
+ }
59
+ }
60
+ else {
61
+ //盖在下面的元素,计算放到哪边
62
+ if (Math.abs(index - showIndex + children.length) % children.length <= Math.abs(showIndex - index + children.length) % children.length) {
63
+ left = extShowCount * 2;
64
+ }
65
+ else {
66
+ left = 0;
67
+ }
68
+ }
69
+ return left * extShowDist.num;
70
+ };
71
+ var onTransitionEnd = function (ev) { };
72
+ useEffect(function () {
73
+ onIndexChange && onIndexChange(showIndex);
74
+ }, [showIndex]);
75
+ useImperativeHandle(props.cRef, function () { return ({
76
+ switchNext: function () {
77
+ changeShowIndex((showIndex + 1) % children.length);
78
+ },
79
+ switchPre: function () {
80
+ changeShowIndex((showIndex - 1 + children.length) % children.length);
81
+ },
82
+ }); });
83
+ //按离中间元素的距离计算 zindex、scale、opacity
84
+ var getZIndex = function (index, showIndex) {
85
+ var topIndex = 99999;
86
+ var baseIndex = topIndex - getMinDist(index, showIndex);
87
+ return baseIndex;
88
+ };
89
+ var getOpacity = function (index, showIndex) {
90
+ var topOpacity = 1;
91
+ var baseOpacity = minOpacity;
92
+ //getMinDist越大,越靠近中间,透明度越高
93
+ return Math.max(baseOpacity + ((topOpacity - baseOpacity) * (extShowCount - getMinDist(index, showIndex))) / extShowCount, baseOpacity);
94
+ };
95
+ var getScale = function (index) {
96
+ var topScale = maxScale;
97
+ var baseScale = 1;
98
+ return Math.max(baseScale + ((topScale - baseScale) * (extShowCount - getMinDist(index, showIndex))) / extShowCount, baseScale);
99
+ };
100
+ useEffect(function () {
101
+ if (children.length == 0) {
102
+ return;
103
+ }
104
+ //计算修改完元素的属性再显示
105
+ setEleStyle(showIndex);
106
+ setOnload(true);
107
+ }, []);
108
+ var setEleStyle = function (index) {
109
+ //更新元素的zIndex和opacity
110
+ var newZIndexArr = Array.from({ length: children.length }).map(function () { return 0; });
111
+ children.forEach(function (_, _index) {
112
+ newZIndexArr[_index] = getZIndex(index, _index);
113
+ });
114
+ setZIndexArr(newZIndexArr);
115
+ var newOpacityArr = Array.from({ length: children.length }).map(function () { return 1; });
116
+ children.forEach(function (_, _index) {
117
+ newOpacityArr[_index] = getOpacity(index, _index);
118
+ });
119
+ setOpacitiyArr(newOpacityArr);
120
+ };
121
+ var changeShowIndex = function (index) {
122
+ if (index >= 0 && index < children.length) {
123
+ setShowIndex(index);
124
+ setTimeout(function () {
125
+ setEleStyle(index);
126
+ }, animationTime * 0.4);
127
+ }
128
+ };
129
+ return onload ? (h("div", { id: rootId, className: rootClassName, style: { flexDirection: 'column' }, onDrag: function (ev) {
130
+ if (!isDraging.current) {
131
+ return;
132
+ }
133
+ //在外层接受 drag 事件,触发切换动作
134
+ if (ev.clientX - dragX.current > 100) {
135
+ console.log('drag right');
136
+ changeShowIndex((showIndex - 1 + children.length) % children.length);
137
+ isDraging.current = false;
138
+ }
139
+ else if (ev.clientX - dragX.current < -100) {
140
+ console.log('drag left');
141
+ changeShowIndex((showIndex + 1) % children.length);
142
+ isDraging.current = false;
143
+ }
144
+ }, onDragStart: function (ev) {
145
+ isDraging.current = true;
146
+ dragX.current = ev.clientX;
147
+ }, onDragEnd: function (ev) {
148
+ isDraging.current = false;
149
+ }, draggable: true }, children.map(function (child, index) {
150
+ return (h("div", { ref: function (ele) {
151
+ if (ele) {
152
+ //绕过 pixui 初始化设置zIndex 和 opcity 后 transform 错误的问题
153
+ // ele.style.transform = `translate(${getDist(getLeft(index) + 1)},0rem) scale(${getScale(index)})`;
154
+ ele.style.transition = "transform ".concat(animationTime, "ms");
155
+ }
156
+ },
157
+ /**
158
+ * child数组首尾相接,拼成一个环,除了显示的 extShowCount*2+1 个元素,其余元素分别放到最左和最右,按离中间元素的距离计算 zindex 和 scale
159
+ * 用getLeft函数统一计算每个元素当前的left值,pixui 不支持zIndex和opacity动画,直接在播放过程中setstate改变元素的zIndex和opacity值
160
+ */
161
+ style: {
162
+ position: 'absolute',
163
+ transform: "translate(".concat(getDist(getLeft(index)), ",0px) scale(").concat(getScale(index), ")"),
164
+ zIndex: zIndexArr[index] || 0,
165
+ opacity: opacitiyArr[index] || 1,
166
+ }, onClick: function (ev) {
167
+ changeShowIndex(index);
168
+ onClick && onClick(index);
169
+ ev.stopPropagation();
170
+ } }, child));
171
+ }))) : null;
172
+ };
@@ -0,0 +1,9 @@
1
+ import { h } from 'preact';
2
+ export declare let NewsTicker: (props: {
3
+ rootId?: string | undefined;
4
+ rootClassName: string;
5
+ content: string;
6
+ totalTime: number;
7
+ onEnd?: (() => void) | undefined;
8
+ repeatTimes?: number | undefined;
9
+ }) => h.JSX.Element;
@@ -0,0 +1,41 @@
1
+ import { useEffect, useRef, useState } from 'preact/hooks';
2
+ import { h } from 'preact';
3
+ export var NewsTicker = function (props) {
4
+ var _a, _b;
5
+ var rootId = props.rootId, rootClassName = props.rootClassName, content = props.content, totalTime = props.totalTime, onEnd = props.onEnd, repeatTimes = (_a = props.repeatTimes, _a === void 0 ? 1 : _a);
6
+ // const [left, setLeft] = useState(0);
7
+ var moveDistance = (_b = useState(0), _b[0]), setMoveDistance = _b[1];
8
+ var contentRef = useRef(null);
9
+ var frameRef = useRef(null);
10
+ useEffect(function () {
11
+ var contentWidth = contentRef.current.clientWidth || 0;
12
+ var frameWidth = frameRef.current.clientWidth || 0;
13
+ var moveDistance = Math.max(contentWidth - frameWidth, 0);
14
+ setMoveDistance(moveDistance);
15
+ }, []);
16
+ var onTransitionEnd = function () {
17
+ onEnd && onEnd();
18
+ };
19
+ var repeatContent = function () {
20
+ var repeatContent = '';
21
+ for (var i = 0; i < repeatTimes; i++) {
22
+ repeatContent += content;
23
+ }
24
+ console.log('repeatContent', repeatContent);
25
+ return repeatContent;
26
+ };
27
+ return (h("div", { id: rootId, className: rootClassName, style: {
28
+ whiteSpace: 'nowrap',
29
+ overflow: 'hidden',
30
+ textOverflow: 'ellipsis',
31
+ width: '100%',
32
+ position: 'relative',
33
+ }, ref: frameRef },
34
+ h("div", { ref: contentRef, style: {
35
+ position: 'absolute',
36
+ // transition: `left ${totalTime}s linear`,
37
+ transition: "transform ".concat(totalTime, "s linear"),
38
+ // transform: `translate(-100%, 0)`,
39
+ transform: "translateX(-".concat(moveDistance, ")"),
40
+ }, onTransitionEnd: onTransitionEnd }, repeatContent())));
41
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * + [已解决]为什么重新创建 CustomScrollBar()时 isDragingSBlock 会被重置为false? 在外部回调中不能使用state
3
+ *
4
+ */
5
+ import { h } from 'preact';
6
+ export declare function ScrollBar(props: any): h.JSX.Element;
@@ -0,0 +1,134 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ /**
13
+ * + [已解决]为什么重新创建 CustomScrollBar()时 isDragingSBlock 会被重置为false? 在外部回调中不能使用state
14
+ *
15
+ */
16
+ import { h } from 'preact';
17
+ import styles from './ScrollBar.module.less';
18
+ import { useState, useEffect } from 'preact/hooks';
19
+ var sWindow; // 滚动窗口
20
+ var sBlock; // 滚动条
21
+ var sFrame; // 滚动条外框
22
+ var isDragingSBlock = false;
23
+ var clientYtoBlockTop = 0; //鼠标Y坐标距离滑块top, 记录这个值是为了记住拖动位置和滑块的偏移,并在后续滑动时保持这个偏移
24
+ export function ScrollBar(props) {
25
+ var _a = useState(0), sBlockY = _a[0], setSBlockY = _a[1]; // sBlock的Top值, block顶部相对于frames上边的差值
26
+ var _b = useState({}), sBlockStyle = _b[0], setSBlockStyle = _b[1];
27
+ var _c = useState({}), sFrameStyle = _c[0], setSFrameStyle = _c[1];
28
+ setSFrameStyle(props.style);
29
+ useEffect(function () {
30
+ // 初始化的 useEffect,其中只能添加初始化方法
31
+ setTimeout(function () {
32
+ // pixui限制,必须异步获取元素,也可以用userRef, 但效率似乎不如初始化时查找
33
+ if (!props.scrollWindowRef) {
34
+ console.warn('[CustomScrollBar][Error] 未设置 scrollWindowRef!');
35
+ return;
36
+ }
37
+ sWindow = props.scrollWindowRef.current;
38
+ sBlock = document.getElementById('sblock');
39
+ sFrame = document.getElementById('sframe');
40
+ if (!sWindow) {
41
+ console.warn('[CustomScrollBar][Error] 未找到sWindow,请确认设置的scrollWindowRef是否正确!');
42
+ return;
43
+ }
44
+ if (!sBlock || !sFrame) {
45
+ console.warn('[CustomScrollBar][Error] 内部错误,无法找到 sBlock 或 sFrame!');
46
+ return;
47
+ }
48
+ sWindow === null || sWindow === void 0 ? void 0 : sWindow.addEventListener('scroll', sWindowScrolling);
49
+ // 设置背景图
50
+ sBlock.style.backgroundImage = "url(".concat(props.sBlockImgNormal, ")");
51
+ sFrame.style.backgroundImage = "url(".concat(props.sFrameImgNormal, ")");
52
+ sBlock.addEventListener('mousedown', function () {
53
+ sBlock.style.backgroundImage = "url(".concat(props.sBlockImgClick, ")");
54
+ sFrame.style.backgroundImage = "url(".concat(props.sFrameImgClick, ")");
55
+ });
56
+ sBlock.addEventListener('mouseup', function () {
57
+ sBlock.style.backgroundImage = "url(".concat(props.sBlockImgNormal, ")");
58
+ sFrame.style.backgroundImage = "url(".concat(props.sFrameImgNormal, ")");
59
+ });
60
+ }, 1);
61
+ // 释放时删除监听
62
+ return function () {
63
+ sWindow === null || sWindow === void 0 ? void 0 : sWindow.removeEventListener('scroll', sWindowScrolling);
64
+ };
65
+ }, []);
66
+ useEffect(function () {
67
+ setSBlockStyle(function (prevStyle) { return (__assign(__assign({}, props.blockStyle), { marginTop: sBlockY })); });
68
+ }, [sBlockY, props.blockStyle]);
69
+ // 页面滑动时,滑块也跟着移动
70
+ var sWindowScrolling = function (event) {
71
+ if (isDragingSBlock) {
72
+ // 这个事件是处理窗口滚动的。如果是拖动滑块,则不处理事件。否则会造成死循环。
73
+ return;
74
+ }
75
+ // 页面滑动时,同步带动滑块移动
76
+ if (sBlock && sWindow && sFrame) {
77
+ var sblock_height = sBlock.getBoundingClientRect().height; // 滑块高
78
+ var sframe_height = sFrame.getBoundingClientRect().height; // 滑块顶部距离父元素高度
79
+ var swindow_height = sWindow.getBoundingClientRect().height; // 滑动窗口高
80
+ var content_scrollTop = sWindow.scrollTop; // 窗口顶部距离内容顶部的高度
81
+ var content_height = sWindow.scrollHeight;
82
+ var rate = content_scrollTop / (content_height - swindow_height); //当前滑动比例
83
+ var sblock_top_to_sframe = rate * (sframe_height - sblock_height);
84
+ if (sblock_top_to_sframe < 0) {
85
+ setSBlockY(0);
86
+ }
87
+ else if (sblock_top_to_sframe > sframe_height - sblock_height) {
88
+ setSBlockY(sframe_height - sblock_height);
89
+ }
90
+ else {
91
+ setSBlockY(sblock_top_to_sframe);
92
+ }
93
+ }
94
+ };
95
+ // 拖动滑块时,页面跟着移动
96
+ var sBlockScrolling = function (event) {
97
+ if (event.clientY - clientYtoBlockTop < sFrame.getBoundingClientRect().top) {
98
+ // 超出上边界,滑动到顶
99
+ setSBlockY(0);
100
+ }
101
+ else if (event.clientY - clientYtoBlockTop + sBlock.getBoundingClientRect().height > sFrame.getBoundingClientRect().bottom) {
102
+ // 超出下边界,滑动到底
103
+ setSBlockY(sFrame.getBoundingClientRect().height - sBlock.getBoundingClientRect().height);
104
+ }
105
+ else {
106
+ setSBlockY(
107
+ // 滑块顶部距离sframe上边的差值 = 鼠标Y位置 - 鼠标Y距离元素顶部位置 - 滚动框绝对top
108
+ event.clientY - clientYtoBlockTop - sFrame.getBoundingClientRect().top);
109
+ }
110
+ {
111
+ //移动 content
112
+ var sblock_height = sBlock.getBoundingClientRect().height;
113
+ var sframe_height = sFrame.getBoundingClientRect().height;
114
+ var swindow_height = sWindow.getBoundingClientRect().height;
115
+ var content_height = sWindow.scrollHeight;
116
+ var slideMarginTop = sBlock.getBoundingClientRect().top - sFrame.getBoundingClientRect().top;
117
+ var rate = slideMarginTop / (sframe_height - sblock_height);
118
+ var content_scrollTop = (content_height - swindow_height) * rate;
119
+ sWindow.scrollTop = content_scrollTop;
120
+ }
121
+ };
122
+ return (h("div", { id: "sframe", className: styles.main, style: sFrameStyle },
123
+ h("div", { id: "sblock", className: styles.slideBlock, style: sBlockStyle, draggable: true, onDragStart: function (event) {
124
+ sBlock.style.backgroundImage = "url(".concat(props.sBlockImgClick, ")");
125
+ sFrame.style.backgroundImage = "url(".concat(props.sFrameImgClick, ")");
126
+ //@ts-ignore
127
+ clientYtoBlockTop = event.clientY - event.target.getBoundingClientRect().top;
128
+ isDragingSBlock = true;
129
+ }, onDragEnd: function (event) {
130
+ isDragingSBlock = false;
131
+ sBlock.style.backgroundImage = "url(".concat(props.sBlockImgNormal, ")");
132
+ sFrame.style.backgroundImage = "url(".concat(props.sFrameImgNormal, ")");
133
+ }, onDrag: sBlockScrolling })));
134
+ }