@douyinfe/semi-foundation 2.49.0-beta.0 → 2.49.0

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.
@@ -1,7 +1,4 @@
1
- import _isUndefined from "lodash/isUndefined";
2
- import _throttle from "lodash/throttle";
3
1
  import BaseFoundation from "../base/foundation";
4
- import { handlePrevent } from "../utils/a11y";
5
2
  const DefaultDOMRect = {
6
3
  bottom: 0,
7
4
  height: 0,
@@ -16,6 +13,12 @@ const DefaultDOMRect = {
16
13
  export default class PreviewImageFoundation extends BaseFoundation {
17
14
  constructor(adapter) {
18
15
  super(Object.assign({}, adapter));
16
+ this.startMouseOffset = {
17
+ x: 0,
18
+ y: 0
19
+ };
20
+ this.originImageWidth = null;
21
+ this.originImageHeight = null;
19
22
  this._isImageVertical = () => this.getProp("rotation") % 180 !== 0;
20
23
  this._getImageBounds = () => {
21
24
  const imageDOM = this._adapter.getImage();
@@ -45,32 +48,18 @@ export default class PreviewImageFoundation extends BaseFoundation {
45
48
  this._adapter.setLoading(loading);
46
49
  };
47
50
  this.handleWindowResize = () => {
48
- const {
49
- ratio,
50
- setRatio
51
- } = this.getProps();
52
- const {
53
- originImageWidth,
54
- originImageHeight
55
- } = this._adapter.getOriginImageSize();
56
- if (originImageWidth && originImageHeight) {
57
- if (ratio !== "adaptation") {
58
- setRatio("adaptation");
59
- } else {
60
- this.handleResizeImage();
61
- }
51
+ if (this.originImageWidth && this.originImageHeight) {
52
+ this.handleResizeImage();
62
53
  }
63
54
  };
64
55
  this.handleLoad = e => {
65
56
  if (e.target) {
66
57
  const {
67
- width: w,
68
- height: h
58
+ naturalWidth: w,
59
+ naturalHeight: h
69
60
  } = e.target;
70
- this._adapter.setOriginImageSize({
71
- originImageWidth: w,
72
- originImageHeight: h
73
- });
61
+ this.originImageHeight = h;
62
+ this.originImageWidth = w;
74
63
  this.setState({
75
64
  loading: false
76
65
  });
@@ -95,13 +84,14 @@ export default class PreviewImageFoundation extends BaseFoundation {
95
84
  this.handleResizeImage = () => {
96
85
  const horizontal = !this._isImageVertical();
97
86
  const {
98
- originImageWidth,
99
- originImageHeight
100
- } = this._adapter.getOriginImageSize();
101
- const imgWidth = horizontal ? originImageWidth : originImageHeight;
102
- const imgHeight = horizontal ? originImageHeight : originImageWidth;
87
+ currZoom
88
+ } = this.getStates();
89
+ const imgWidth = horizontal ? this.originImageWidth : this.originImageHeight;
90
+ const imgHeight = horizontal ? this.originImageHeight : this.originImageWidth;
103
91
  const {
104
- onZoom
92
+ onZoom,
93
+ setRatio,
94
+ ratio
105
95
  } = this.getProps();
106
96
  const containerDOM = this._adapter.getContainer();
107
97
  if (containerDOM) {
@@ -111,8 +101,44 @@ export default class PreviewImageFoundation extends BaseFoundation {
111
101
  } = this._getContainerBounds();
112
102
  const reservedWidth = containerWidth - 80;
113
103
  const reservedHeight = containerHeight - 80;
114
- const _zoom = Number(Math.min(reservedWidth / imgWidth, reservedHeight / imgHeight).toFixed(2));
115
- onZoom(_zoom);
104
+ let _zoom = 1;
105
+ if (imgWidth > reservedWidth || imgHeight > reservedHeight) {
106
+ _zoom = Number(Math.min(reservedWidth / imgWidth, reservedHeight / imgHeight).toFixed(2));
107
+ }
108
+ if (currZoom === _zoom) {
109
+ this.calculatePreviewImage(_zoom, null);
110
+ } else {
111
+ onZoom(_zoom);
112
+ }
113
+ }
114
+ };
115
+ this.handleRatioChange = () => {
116
+ if (this.originImageWidth && this.originImageHeight) {
117
+ const {
118
+ currZoom
119
+ } = this.getStates();
120
+ const {
121
+ ratio,
122
+ onZoom
123
+ } = this.getProps();
124
+ let _zoom;
125
+ if (ratio === 'adaptation') {
126
+ const horizontal = !this._isImageVertical();
127
+ const imgWidth = horizontal ? this.originImageWidth : this.originImageHeight;
128
+ const imgHeight = horizontal ? this.originImageHeight : this.originImageWidth;
129
+ const {
130
+ width: containerWidth,
131
+ height: containerHeight
132
+ } = this._getContainerBounds();
133
+ const reservedWidth = containerWidth - 80;
134
+ const reservedHeight = containerHeight - 80;
135
+ _zoom = Number(Math.min(reservedWidth / imgWidth, reservedHeight / imgHeight).toFixed(2));
136
+ } else {
137
+ _zoom = 1;
138
+ }
139
+ if (currZoom !== _zoom) {
140
+ onZoom(_zoom);
141
+ }
116
142
  }
117
143
  };
118
144
  this.handleRightClickImage = e => {
@@ -127,38 +153,6 @@ export default class PreviewImageFoundation extends BaseFoundation {
127
153
  return true;
128
154
  }
129
155
  };
130
- // e: WheelEvent<HTMLImageElement>
131
- this.handleWheel = e => {
132
- this.onWheel(e);
133
- handlePrevent(e);
134
- };
135
- // e: WheelEvent<HTMLImageElement>
136
- this.onWheel = _throttle(e => {
137
- const {
138
- onZoom,
139
- zoomStep,
140
- maxZoom,
141
- minZoom
142
- } = this.getProps();
143
- const {
144
- currZoom
145
- } = this.getStates();
146
- let _zoom;
147
- if (e.deltaY < 0) {
148
- /* zoom in */
149
- if (currZoom + zoomStep <= maxZoom) {
150
- _zoom = Number((currZoom + zoomStep).toFixed(2));
151
- }
152
- } else if (e.deltaY > 0) {
153
- /* zoom out */
154
- if (currZoom - zoomStep >= minZoom) {
155
- _zoom = Number((currZoom - zoomStep).toFixed(2));
156
- }
157
- }
158
- if (!_isUndefined(_zoom)) {
159
- onZoom(_zoom);
160
- }
161
- }, 50);
162
156
  this.calcCanDragDirection = () => {
163
157
  const {
164
158
  width,
@@ -182,12 +176,8 @@ export default class PreviewImageFoundation extends BaseFoundation {
182
176
  canDragHorizontal
183
177
  };
184
178
  };
185
- this.handleZoomChange = (newZoom, e) => {
179
+ this.calculatePreviewImage = (newZoom, e) => {
186
180
  const imageDOM = this._adapter.getImage();
187
- const {
188
- originImageWidth,
189
- originImageHeight
190
- } = this._adapter.getOriginImageSize();
191
181
  const {
192
182
  canDragVertical,
193
183
  canDragHorizontal
@@ -197,8 +187,8 @@ export default class PreviewImageFoundation extends BaseFoundation {
197
187
  width: containerWidth,
198
188
  height: containerHeight
199
189
  } = this._getContainerBounds();
200
- const newWidth = Math.floor(originImageWidth * newZoom);
201
- const newHeight = Math.floor(originImageHeight * newZoom);
190
+ const newWidth = Math.floor(this.originImageWidth * newZoom);
191
+ const newHeight = Math.floor(this.originImageHeight * newZoom);
202
192
  // debugger;
203
193
  let _offset;
204
194
  const horizontal = !this._isImageVertical();
@@ -257,13 +247,13 @@ export default class PreviewImageFoundation extends BaseFoundation {
257
247
  width,
258
248
  height
259
249
  } = this.getStates();
260
- const startMouseMove = this._adapter.getMouseMove();
261
- const startMouseOffset = this._adapter.getMouseOffset();
262
250
  const {
263
251
  canDragVertical,
264
252
  canDragHorizontal
265
253
  } = this.calcCanDragDirection();
266
- if (startMouseMove && (canDragVertical || canDragHorizontal)) {
254
+ // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
255
+ const mouseLeftPress = e.buttons === 1;
256
+ if (mouseLeftPress && (canDragVertical || canDragHorizontal)) {
267
257
  const {
268
258
  clientX,
269
259
  clientY
@@ -276,8 +266,8 @@ export default class PreviewImageFoundation extends BaseFoundation {
276
266
  left: extremeLeft,
277
267
  top: extremeTop
278
268
  } = this.calcExtremeBounds();
279
- let newX = canDragHorizontal ? clientX - containerLeft - startMouseOffset.x : offset.x;
280
- let newY = canDragVertical ? clientY - containerTop - startMouseOffset.y : offset.y;
269
+ let newX = canDragHorizontal ? clientX - containerLeft - this.startMouseOffset.x : offset.x;
270
+ let newY = canDragVertical ? clientY - containerTop - this.startMouseOffset.y : offset.y;
281
271
  if (canDragHorizontal) {
282
272
  newX = newX > 0 ? 0 : newX < extremeLeft ? extremeLeft : newX;
283
273
  }
@@ -296,11 +286,7 @@ export default class PreviewImageFoundation extends BaseFoundation {
296
286
  }
297
287
  };
298
288
  this.handleImageMouseDown = e => {
299
- this._adapter.setStartMouseOffset(this._getOffset(e));
300
- this._adapter.setStartMouseMove(true);
301
- };
302
- this.handleImageMouseUp = () => {
303
- this._adapter.setStartMouseMove(false);
289
+ this.startMouseOffset = this._getOffset(e);
304
290
  };
305
291
  }
306
292
  }
@@ -1,3 +1,4 @@
1
+ /// <reference types="lodash" />
1
2
  import BaseFoundation, { DefaultAdapter } from "../base/foundation";
2
3
  export type RatioType = "adaptation" | "realSize";
3
4
  export interface PreviewInnerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
@@ -11,26 +12,27 @@ export interface PreviewInnerAdapter<P = Record<string, any>, S = Record<string,
11
12
  notifyDownload: (src: string, index: number) => void;
12
13
  registerKeyDownListener: () => void;
13
14
  unregisterKeyDownListener: () => void;
14
- getMouseActiveTime: () => number;
15
- getStopTiming: () => boolean;
16
- setStopTiming: (value: boolean) => void;
17
- getStartMouseDown: () => {
18
- x: number;
19
- y: number;
20
- };
21
- setStartMouseDown: (x: number, y: number) => void;
22
- setMouseActiveTime: (time: number) => void;
23
15
  disabledBodyScroll: () => void;
24
16
  enabledBodyScroll: () => void;
25
17
  getSetDownloadFunc: () => (src: string) => string;
18
+ isValidTarget: (e: any) => boolean;
26
19
  }
27
20
  export default class PreviewInnerFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<PreviewInnerAdapter<P, S>, P, S> {
28
21
  constructor(adapter: PreviewInnerAdapter<P, S>);
22
+ _timer: any;
23
+ _startMouseDown: {
24
+ x: number;
25
+ y: number;
26
+ };
29
27
  beforeShow(): void;
30
28
  afterHide(): void;
31
29
  handleViewVisibleChange: () => void;
32
- handleMouseMoveEvent: (e: any, event: string) => void;
33
30
  handleMouseMove: (e: any) => void;
31
+ mouseMoveHandler: import("lodash").DebouncedFunc<(e: any) => void>;
32
+ updateTimer: () => void;
33
+ clearTimer: () => void;
34
+ handleWheel: (e: any) => void;
35
+ onWheel: (e: any) => void;
34
36
  handleMouseUp: (e: any) => void;
35
37
  handleMouseDown: (e: any) => void;
36
38
  handleKeyDown: (e: any) => void;
@@ -1,3 +1,6 @@
1
+ import _throttle from "lodash/throttle";
2
+ import _isUndefined from "lodash/isUndefined";
3
+ import { handlePrevent } from "../utils/a11y";
1
4
  import BaseFoundation from "../base/foundation";
2
5
  import KeyCode from "../utils/keyCode";
3
6
  import { getPreloadImagArr, downloadImage, isTargetEmit } from "./utils";
@@ -6,35 +9,83 @@ const STOP_CLOSE_TARGET = ["icon", "footer", "header"];
6
9
  export default class PreviewInnerFoundation extends BaseFoundation {
7
10
  constructor(adapter) {
8
11
  super(Object.assign({}, adapter));
12
+ this._timer = null;
13
+ this._startMouseDown = {
14
+ x: 0,
15
+ y: 0
16
+ };
9
17
  this.handleViewVisibleChange = () => {
10
- const nowTime = new Date().getTime();
11
- const mouseActiveTime = this._adapter.getMouseActiveTime();
12
- const stopTiming = this._adapter.getStopTiming();
13
- const {
14
- viewerVisibleDelay
15
- } = this.getProps();
16
18
  const {
17
19
  viewerVisible
18
20
  } = this.getStates();
19
- if (nowTime - mouseActiveTime > viewerVisibleDelay && !stopTiming) {
20
- viewerVisible && this.setState({
21
+ if (viewerVisible) {
22
+ this.setState({
21
23
  viewerVisible: false
22
24
  });
25
+ this.clearTimer();
23
26
  }
24
27
  };
25
- this.handleMouseMoveEvent = (e, event) => {
26
- const isTarget = isTargetEmit(e, STOP_CLOSE_TARGET);
27
- if (isTarget && event === "over") {
28
- this._adapter.setStopTiming(true);
29
- } else if (isTarget && event === "out") {
30
- this._adapter.setStopTiming(false);
28
+ this.handleMouseMove = e => {
29
+ this._persistEvent(e);
30
+ this.mouseMoveHandler(e);
31
+ };
32
+ this.mouseMoveHandler = _throttle(e => {
33
+ const {
34
+ viewerVisible
35
+ } = this.getStates();
36
+ const isValidTarget = this._adapter.isValidTarget(e);
37
+ if (isValidTarget) {
38
+ if (!viewerVisible) {
39
+ this.setState({
40
+ viewerVisible: true
41
+ });
42
+ }
43
+ this.updateTimer();
44
+ } else {
45
+ this.clearTimer();
31
46
  }
47
+ }, 50);
48
+ this.updateTimer = () => {
49
+ const {
50
+ viewerVisibleDelay
51
+ } = this.getProps();
52
+ this.clearTimer();
53
+ this._timer = setTimeout(this.handleViewVisibleChange, viewerVisibleDelay);
32
54
  };
33
- this.handleMouseMove = e => {
34
- this._adapter.setMouseActiveTime(new Date().getTime());
35
- this.setState({
36
- viewerVisible: true
37
- });
55
+ this.clearTimer = () => {
56
+ if (this._timer) {
57
+ clearTimeout(this._timer);
58
+ this._timer = null;
59
+ }
60
+ };
61
+ this.handleWheel = e => {
62
+ this.onWheel(e);
63
+ handlePrevent(e);
64
+ };
65
+ this.onWheel = e => {
66
+ const {
67
+ zoomStep,
68
+ maxZoom,
69
+ minZoom
70
+ } = this.getProps();
71
+ const {
72
+ zoom: currZoom
73
+ } = this.getStates();
74
+ let _zoom;
75
+ if (e.deltaY < 0) {
76
+ /* zoom in */
77
+ if (currZoom + zoomStep <= maxZoom) {
78
+ _zoom = Number((currZoom + zoomStep).toFixed(2));
79
+ }
80
+ } else if (e.deltaY > 0) {
81
+ /* zoom out */
82
+ if (currZoom - zoomStep >= minZoom) {
83
+ _zoom = Number((currZoom - zoomStep).toFixed(2));
84
+ }
85
+ }
86
+ if (!_isUndefined(_zoom)) {
87
+ this.handleZoomImage(_zoom);
88
+ }
38
89
  };
39
90
  this.handleMouseUp = e => {
40
91
  const {
@@ -48,7 +99,7 @@ export default class PreviewInnerFoundation extends BaseFoundation {
48
99
  const {
49
100
  x,
50
101
  y
51
- } = this._adapter.getStartMouseDown();
102
+ } = this._startMouseDown;
52
103
  // 对鼠标移动做容错处理,当 x 和 y 方向在 mouseUp 的时候移动距离都小于等于 5px 时候就可以关闭预览
53
104
  // Error-tolerant processing of mouse movement, when the movement distance in the x and y directions is less than or equal to 5px in mouseUp, the preview can be closed
54
105
  // 不做容错处理的话,直接用 clientX !== x || y !== clientY 做判断,鼠标在用户点击时候无意识的轻微移动无法关闭预览,不符合用户预期
@@ -65,7 +116,10 @@ export default class PreviewInnerFoundation extends BaseFoundation {
65
116
  clientX,
66
117
  clientY
67
118
  } = e;
68
- this._adapter.setStartMouseDown(clientX, clientY);
119
+ this._startMouseDown = {
120
+ x: clientX,
121
+ y: clientY
122
+ };
69
123
  };
70
124
  this.handleKeyDown = e => {
71
125
  const {
@@ -138,10 +192,12 @@ export default class PreviewInnerFoundation extends BaseFoundation {
138
192
  const {
139
193
  zoom
140
194
  } = this.getStates();
141
- this._adapter.notifyZoom(newZoom, newZoom > zoom);
142
- this.setState({
143
- zoom: newZoom
144
- });
195
+ if (zoom !== newZoom) {
196
+ this._adapter.notifyZoom(newZoom, newZoom > zoom);
197
+ this.setState({
198
+ zoom: newZoom
199
+ });
200
+ }
145
201
  };
146
202
  // 当 visible 改变之后,预览组件完成首张图片加载后,启动预加载
147
203
  // 如: 1,2,3,4,5,6,7,8张图片, 点击第 4 张图片,preLoadGap 为 2
@@ -259,9 +315,11 @@ export default class PreviewInnerFoundation extends BaseFoundation {
259
315
  beforeShow() {
260
316
  this._adapter.registerKeyDownListener();
261
317
  this._adapter.disabledBodyScroll();
318
+ this.updateTimer();
262
319
  }
263
320
  afterHide() {
264
321
  this._adapter.unregisterKeyDownListener();
265
322
  this._adapter.enabledBodyScroll();
323
+ this.clearTimer();
266
324
  }
267
325
  }
@@ -328,6 +328,7 @@ export default class SelectFoundation extends BaseFoundation {
328
328
  this.close(e);
329
329
  this._notifyBlur(e);
330
330
  this._adapter.updateFocusState(false);
331
+ this._adapter.unregisterClickOutsideHandler();
331
332
  });
332
333
  }
333
334
  toggle2SearchInput(isShow) {
@@ -345,7 +346,6 @@ export default class SelectFoundation extends BaseFoundation {
345
346
  this._adapter.setIsFocusInContainer(false);
346
347
  // this.unBindKeyBoardEvent();
347
348
  // this._notifyBlur(e);
348
- this._adapter.unregisterClickOutsideHandler();
349
349
  // this._adapter.updateFocusState(false);
350
350
  const isFilterable = this._isFilterable();
351
351
  if (isFilterable) {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-foundation",
3
- "version": "2.49.0-beta.0",
3
+ "version": "2.49.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "build:lib": "node ./scripts/compileLib.js",
7
7
  "prepublishOnly": "npm run build:lib"
8
8
  },
9
9
  "dependencies": {
10
- "@douyinfe/semi-animation": "2.49.0-beta.0",
10
+ "@douyinfe/semi-animation": "2.49.0",
11
11
  "async-validator": "^3.5.0",
12
12
  "classnames": "^2.2.6",
13
13
  "date-fns": "^2.29.3",
@@ -23,7 +23,7 @@
23
23
  "*.scss",
24
24
  "*.css"
25
25
  ],
26
- "gitHead": "aa959f0cd22894b27c019eb78254ba9b991f80b3",
26
+ "gitHead": "3ae380197586cc24c67bc2e6fb067533638206b2",
27
27
  "devDependencies": {
28
28
  "@babel/plugin-transform-runtime": "^7.15.8",
29
29
  "@babel/preset-env": "^7.15.8",
@@ -363,6 +363,7 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
363
363
  this.close(e);
364
364
  this._notifyBlur(e);
365
365
  this._adapter.updateFocusState(false);
366
+ this._adapter.unregisterClickOutsideHandler();
366
367
  });
367
368
  }
368
369
 
@@ -383,7 +384,6 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
383
384
  this._adapter.setIsFocusInContainer(false);
384
385
  // this.unBindKeyBoardEvent();
385
386
  // this._notifyBlur(e);
386
- this._adapter.unregisterClickOutsideHandler();
387
387
  // this._adapter.updateFocusState(false);
388
388
 
389
389
  const isFilterable = this._isFilterable();