@mpxjs/webpack-plugin 2.10.14-beta.1 → 2.10.14-beta.3
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/lib/dependencies/ImportDependency.js +102 -0
- package/lib/index.js +9 -9
- package/lib/react/processScript.js +4 -2
- package/lib/react/script-helper.js +3 -3
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +24 -17
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +26 -8
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +44 -39
- package/lib/runtime/components/react/mpx-movable-view.tsx +26 -20
- package/lib/runtime/components/react/mpx-scroll-view.tsx +30 -8
- package/lib/runtime/components/react/mpx-swiper.tsx +44 -37
- package/package.json +1 -1
- package/lib/dependencies/ImportDependencyTemplate.js +0 -50
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const Dependency = require('webpack/lib/Dependency')
|
|
2
|
+
const makeSerializable = require('webpack/lib/util/makeSerializable')
|
|
3
|
+
const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
|
|
4
|
+
const { RetryRuntimeGlobal } = require('../retry-runtime-module')
|
|
5
|
+
|
|
6
|
+
class ImportDependency extends ModuleDependency {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} request the request
|
|
9
|
+
* @param {[number, number]} range expression range
|
|
10
|
+
* @param {string[][]=} referencedExports list of referenced exports
|
|
11
|
+
*/
|
|
12
|
+
constructor (request, range, referencedExports, extraOptions) {
|
|
13
|
+
super(request)
|
|
14
|
+
this.range = range
|
|
15
|
+
this.referencedExports = referencedExports
|
|
16
|
+
this.extraOptions = extraOptions
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get type () {
|
|
20
|
+
return 'import()'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get category () {
|
|
24
|
+
return 'esm'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns list of exports referenced by this dependency
|
|
29
|
+
* @param {ModuleGraph} moduleGraph module graph
|
|
30
|
+
* @param {RuntimeSpec} runtime the runtime for which the module is analysed
|
|
31
|
+
* @returns {(string[] | ReferencedExport)[]} referenced exports
|
|
32
|
+
*/
|
|
33
|
+
getReferencedExports (moduleGraph, runtime) {
|
|
34
|
+
return this.referencedExports
|
|
35
|
+
? this.referencedExports.map((e) => ({
|
|
36
|
+
name: e,
|
|
37
|
+
canMangle: false
|
|
38
|
+
}))
|
|
39
|
+
: Dependency.EXPORTS_OBJECT_REFERENCED
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
serialize (context) {
|
|
43
|
+
context.write(this.range)
|
|
44
|
+
context.write(this.referencedExports)
|
|
45
|
+
context.write(this.extraOptions)
|
|
46
|
+
super.serialize(context)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
deserialize (context) {
|
|
50
|
+
this.range = context.read()
|
|
51
|
+
this.referencedExports = context.read()
|
|
52
|
+
this.extraOptions = context.read()
|
|
53
|
+
super.deserialize(context)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
makeSerializable(ImportDependency, '@mpxjs/webpack-plugin/lib/dependencies/ImportDependency')
|
|
58
|
+
|
|
59
|
+
ImportDependency.Template = class ImportDependencyTemplate extends (
|
|
60
|
+
ModuleDependency.Template
|
|
61
|
+
) {
|
|
62
|
+
/**
|
|
63
|
+
* @param {Dependency} dependency the dependency for which the template should be applied
|
|
64
|
+
* @param {ReplaceSource} source the current replace source which can be modified
|
|
65
|
+
* @param {DependencyTemplateContext} templateContext the context object
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
68
|
+
apply (
|
|
69
|
+
dependency,
|
|
70
|
+
source,
|
|
71
|
+
{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
|
|
72
|
+
) {
|
|
73
|
+
const dep = /** @type {ImportDependency} */ (dependency)
|
|
74
|
+
const block = /** @type {AsyncDependenciesBlock} */ (
|
|
75
|
+
moduleGraph.getParentBlock(dep)
|
|
76
|
+
)
|
|
77
|
+
let content = runtimeTemplate.moduleNamespacePromise({
|
|
78
|
+
chunkGraph,
|
|
79
|
+
block: block,
|
|
80
|
+
module: /** @type {Module} */ (moduleGraph.getModule(dep)),
|
|
81
|
+
request: dep.request,
|
|
82
|
+
strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
|
|
83
|
+
message: 'import()',
|
|
84
|
+
runtimeRequirements
|
|
85
|
+
})
|
|
86
|
+
// replace fakeType by 9 to fix require.async to commonjs2 module like 'module.exports = function(){...}'
|
|
87
|
+
content = content.replace(/(__webpack_require__\.t\.bind\(.+,\s*)(\d+)(\s*\))/, (_, p1, p2, p3) => {
|
|
88
|
+
return p1 + '9' + p3
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// require.async 的场景且配置了重试次数才注入 RetryRuntimeModule
|
|
92
|
+
const extraOptions = dep.extraOptions || {}
|
|
93
|
+
if (extraOptions.isRequireAsync && extraOptions.retryRequireAsync && extraOptions.retryRequireAsync.times > 0) {
|
|
94
|
+
runtimeRequirements.add(RetryRuntimeGlobal)
|
|
95
|
+
content = `${RetryRuntimeGlobal}(function() { return ${content} }, ${extraOptions.retryRequireAsync.times}, ${extraOptions.retryRequireAsync.interval})`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
source.replace(dep.range[0], dep.range[1] - 1, content)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = ImportDependency
|
package/lib/index.js
CHANGED
|
@@ -14,8 +14,7 @@ const EntryPlugin = require('webpack/lib/EntryPlugin')
|
|
|
14
14
|
const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
|
|
15
15
|
const FlagEntryExportAsUsedPlugin = require('webpack/lib/FlagEntryExportAsUsedPlugin')
|
|
16
16
|
const FileSystemInfo = require('webpack/lib/FileSystemInfo')
|
|
17
|
-
const ImportDependency = require('
|
|
18
|
-
const ImportDependencyTemplate = require('./dependencies/ImportDependencyTemplate')
|
|
17
|
+
const ImportDependency = require('./dependencies/ImportDependency')
|
|
19
18
|
const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
|
|
20
19
|
const ProvidePlugin = require('webpack/lib/ProvidePlugin')
|
|
21
20
|
const normalize = require('./utils/normalize')
|
|
@@ -199,6 +198,7 @@ class MpxWebpackPlugin {
|
|
|
199
198
|
}, options.nativeConfig)
|
|
200
199
|
options.webConfig = options.webConfig || {}
|
|
201
200
|
options.rnConfig = options.rnConfig || {}
|
|
201
|
+
options.rnConfig.supportSubpackage = options.rnConfig.supportSubpackage !== undefined ? options.rnConfig.supportSubpackage : true
|
|
202
202
|
options.partialCompileRules = options.partialCompileRules || null
|
|
203
203
|
options.asyncSubpackageRules = options.asyncSubpackageRules || []
|
|
204
204
|
options.optimizeRenderRules = options.optimizeRenderRules ? (Array.isArray(options.optimizeRenderRules) ? options.optimizeRenderRules : [options.optimizeRenderRules]) : []
|
|
@@ -695,7 +695,8 @@ class MpxWebpackPlugin {
|
|
|
695
695
|
compilation.dependencyFactories.set(RequireExternalDependency, new NullFactory())
|
|
696
696
|
compilation.dependencyTemplates.set(RequireExternalDependency, new RequireExternalDependency.Template())
|
|
697
697
|
|
|
698
|
-
compilation.
|
|
698
|
+
compilation.dependencyFactories.set(ImportDependency, normalModuleFactory)
|
|
699
|
+
compilation.dependencyTemplates.set(ImportDependency, new ImportDependency.Template())
|
|
699
700
|
})
|
|
700
701
|
|
|
701
702
|
compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
|
|
@@ -783,7 +784,7 @@ class MpxWebpackPlugin {
|
|
|
783
784
|
removedChunks: [],
|
|
784
785
|
forceProxyEventRules: this.options.forceProxyEventRules,
|
|
785
786
|
// 若配置disableRequireAsync=true, 则全平台构建不支持异步分包
|
|
786
|
-
supportRequireAsync: !this.options.disableRequireAsync && (this.options.mode === 'wx' || this.options.mode === 'ali' || this.options.mode === 'tt' || isWeb(this.options.mode) || isReact(this.options.mode)),
|
|
787
|
+
supportRequireAsync: !this.options.disableRequireAsync && (this.options.mode === 'wx' || this.options.mode === 'ali' || this.options.mode === 'tt' || isWeb(this.options.mode) || (isReact(this.options.mode) && this.options.rnConfig.supportSubpackage)),
|
|
787
788
|
partialCompileRules: this.options.partialCompileRules,
|
|
788
789
|
collectDynamicEntryInfo: ({ resource, packageName, filename, entryType, hasAsync }) => {
|
|
789
790
|
const curInfo = mpx.dynamicEntryInfo[packageName] = mpx.dynamicEntryInfo[packageName] || {
|
|
@@ -1450,10 +1451,6 @@ class MpxWebpackPlugin {
|
|
|
1450
1451
|
if (mpx.supportRequireAsync) {
|
|
1451
1452
|
if (isWeb(mpx.mode) || isReact(mpx.mode)) {
|
|
1452
1453
|
if (isReact(mpx.mode)) tarRoot = transSubpackage(mpx.transSubpackageRules, tarRoot)
|
|
1453
|
-
request = addQuery(request, {
|
|
1454
|
-
isRequireAsync: true,
|
|
1455
|
-
retryRequireAsync: JSON.stringify(this.options.retryRequireAsync)
|
|
1456
|
-
})
|
|
1457
1454
|
const depBlock = new AsyncDependenciesBlock(
|
|
1458
1455
|
{
|
|
1459
1456
|
name: tarRoot + '/index'
|
|
@@ -1461,7 +1458,10 @@ class MpxWebpackPlugin {
|
|
|
1461
1458
|
expr.loc,
|
|
1462
1459
|
request
|
|
1463
1460
|
)
|
|
1464
|
-
const dep = new ImportDependency(request, expr.range
|
|
1461
|
+
const dep = new ImportDependency(request, expr.range, undefined, {
|
|
1462
|
+
isRequireAsync: true,
|
|
1463
|
+
retryRequireAsync: this.options.retryRequireAsync
|
|
1464
|
+
})
|
|
1465
1465
|
dep.loc = expr.loc
|
|
1466
1466
|
depBlock.addDependency(dep)
|
|
1467
1467
|
parser.state.current.addBlock(depBlock)
|
|
@@ -46,7 +46,8 @@ import { getComponent, getAsyncSuspense } from ${stringifyRequest(loaderContext,
|
|
|
46
46
|
const componentsMap = buildComponentsMap({
|
|
47
47
|
localComponentsMap,
|
|
48
48
|
loaderContext,
|
|
49
|
-
jsonConfig
|
|
49
|
+
jsonConfig,
|
|
50
|
+
rnConfig
|
|
50
51
|
})
|
|
51
52
|
output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, pagesMap, firstPage, hasApp })
|
|
52
53
|
output += getRequireScript({ ctorType, script, loaderContext })
|
|
@@ -58,7 +59,8 @@ import { getComponent, getAsyncSuspense } from ${stringifyRequest(loaderContext,
|
|
|
58
59
|
localComponentsMap,
|
|
59
60
|
builtInComponentsMap,
|
|
60
61
|
loaderContext,
|
|
61
|
-
jsonConfig
|
|
62
|
+
jsonConfig,
|
|
63
|
+
rnConfig
|
|
62
64
|
})
|
|
63
65
|
|
|
64
66
|
output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, outputPath, genericsInfo, componentGenerics, hasApp })
|
|
@@ -59,7 +59,7 @@ function buildPagesMap ({ localPagesMap, loaderContext, jsonConfig, rnConfig })
|
|
|
59
59
|
Object.keys(localPagesMap).forEach((pagePath) => {
|
|
60
60
|
const pageCfg = localPagesMap[pagePath]
|
|
61
61
|
const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
|
|
62
|
-
if (pageCfg.async) {
|
|
62
|
+
if (pageCfg.async && rnConfig.supportSubpackage) {
|
|
63
63
|
const moduleId = mpx.getModuleId(pageCfg.resource)
|
|
64
64
|
const getFallback = rnConfig.asyncChunk && rnConfig.asyncChunk.fallback && getComponentGetter(getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.fallback, { isComponent: true })), 'PageFallback'))
|
|
65
65
|
const getLoading = rnConfig.asyncChunk && rnConfig.asyncChunk.loading && getComponentGetter(getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.loading, { isComponent: true })), 'PageLoading'))
|
|
@@ -81,14 +81,14 @@ function buildPagesMap ({ localPagesMap, loaderContext, jsonConfig, rnConfig })
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderContext, jsonConfig }) {
|
|
84
|
+
function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderContext, jsonConfig, rnConfig }) {
|
|
85
85
|
const componentsMap = {}
|
|
86
86
|
const mpx = loaderContext.getMpx()
|
|
87
87
|
if (localComponentsMap) {
|
|
88
88
|
Object.keys(localComponentsMap).forEach((componentName) => {
|
|
89
89
|
const componentCfg = localComponentsMap[componentName]
|
|
90
90
|
const componentRequest = stringifyRequest(loaderContext, componentCfg.resource)
|
|
91
|
-
if (componentCfg.async) {
|
|
91
|
+
if (componentCfg.async && rnConfig.supportSubpackage) {
|
|
92
92
|
const moduleId = mpx.getModuleId(componentCfg.resource)
|
|
93
93
|
const placeholder = jsonConfig.componentPlaceholder && jsonConfig.componentPlaceholder[componentName]
|
|
94
94
|
let getFallback
|
|
@@ -22,7 +22,7 @@ import { StyleSheet } from 'react-native';
|
|
|
22
22
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
23
23
|
import useNodesRef from './useNodesRef';
|
|
24
24
|
import { MovableAreaContext } from './context';
|
|
25
|
-
import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject, omit, useNavigation } from './utils';
|
|
25
|
+
import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, flatGesture, extendObject, omit, useNavigation, useRunOnJSCallback } from './utils';
|
|
26
26
|
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
|
|
27
27
|
import Animated, { useSharedValue, useAnimatedStyle, withDecay, runOnJS, runOnUI, withSpring } from 'react-native-reanimated';
|
|
28
28
|
import { collectDataset, noop } from '@mpxjs/utils';
|
|
@@ -100,15 +100,6 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
100
100
|
layoutRef
|
|
101
101
|
}, propsRef.current));
|
|
102
102
|
}, []);
|
|
103
|
-
// 节流版本的 change 事件触发
|
|
104
|
-
const handleTriggerChangeThrottled = useCallback(({ x, y, type }) => {
|
|
105
|
-
'worklet';
|
|
106
|
-
const now = Date.now();
|
|
107
|
-
if (now - lastChangeTime.value >= changeThrottleTime) {
|
|
108
|
-
lastChangeTime.value = now;
|
|
109
|
-
runOnJS(handleTriggerChange)({ x, y, type });
|
|
110
|
-
}
|
|
111
|
-
}, [changeThrottleTime]);
|
|
112
103
|
useEffect(() => {
|
|
113
104
|
runOnUI(() => {
|
|
114
105
|
if (offsetX.value !== x || offsetY.value !== y) {
|
|
@@ -130,7 +121,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
130
121
|
: newY;
|
|
131
122
|
}
|
|
132
123
|
if (bindchange) {
|
|
133
|
-
runOnJS(
|
|
124
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
134
125
|
x: newX,
|
|
135
126
|
y: newY,
|
|
136
127
|
type: 'setData'
|
|
@@ -295,13 +286,29 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
295
286
|
bindtouchend && bindtouchend(e);
|
|
296
287
|
catchtouchend && catchtouchend(e);
|
|
297
288
|
};
|
|
289
|
+
const runOnJSCallbackRef = useRef({
|
|
290
|
+
handleTriggerChange,
|
|
291
|
+
triggerStartOnJS,
|
|
292
|
+
triggerMoveOnJS,
|
|
293
|
+
triggerEndOnJS
|
|
294
|
+
});
|
|
295
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
|
|
296
|
+
// 节流版本的 change 事件触发
|
|
297
|
+
const handleTriggerChangeThrottled = useCallback(({ x, y, type }) => {
|
|
298
|
+
'worklet';
|
|
299
|
+
const now = Date.now();
|
|
300
|
+
if (now - lastChangeTime.value >= changeThrottleTime) {
|
|
301
|
+
lastChangeTime.value = now;
|
|
302
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', { x, y, type });
|
|
303
|
+
}
|
|
304
|
+
}, [changeThrottleTime]);
|
|
298
305
|
const gesture = useMemo(() => {
|
|
299
306
|
const handleTriggerMove = (e) => {
|
|
300
307
|
'worklet';
|
|
301
308
|
const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove;
|
|
302
309
|
const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove;
|
|
303
310
|
if (hasTouchmove || hasCatchTouchmove) {
|
|
304
|
-
runOnJS(
|
|
311
|
+
runOnJS(runOnJSCallback)('triggerMoveOnJS', {
|
|
305
312
|
e,
|
|
306
313
|
touchEvent: touchEvent.value,
|
|
307
314
|
hasTouchmove,
|
|
@@ -319,7 +326,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
319
326
|
y: changedTouches.y
|
|
320
327
|
};
|
|
321
328
|
if (bindtouchstart || catchtouchstart) {
|
|
322
|
-
runOnJS(
|
|
329
|
+
runOnJS(runOnJSCallback)('triggerStartOnJS', { e });
|
|
323
330
|
}
|
|
324
331
|
})
|
|
325
332
|
.onStart(() => {
|
|
@@ -376,7 +383,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
376
383
|
isFirstTouch.value = true;
|
|
377
384
|
isMoving.value = false;
|
|
378
385
|
if (bindtouchend || catchtouchend) {
|
|
379
|
-
runOnJS(
|
|
386
|
+
runOnJS(runOnJSCallback)('triggerEndOnJS', { e });
|
|
380
387
|
}
|
|
381
388
|
})
|
|
382
389
|
.onEnd((e) => {
|
|
@@ -405,7 +412,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
405
412
|
: y;
|
|
406
413
|
}
|
|
407
414
|
if (bindchange) {
|
|
408
|
-
runOnJS(
|
|
415
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
409
416
|
x,
|
|
410
417
|
y
|
|
411
418
|
});
|
|
@@ -423,7 +430,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
423
430
|
}, () => {
|
|
424
431
|
xInertialMotion.value = false;
|
|
425
432
|
if (bindchange) {
|
|
426
|
-
runOnJS(
|
|
433
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
427
434
|
x: offsetX.value,
|
|
428
435
|
y: offsetY.value
|
|
429
436
|
});
|
|
@@ -439,7 +446,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
439
446
|
}, () => {
|
|
440
447
|
yInertialMotion.value = false;
|
|
441
448
|
if (bindchange) {
|
|
442
|
-
runOnJS(
|
|
449
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
443
450
|
x: offsetX.value,
|
|
444
451
|
y: offsetY.value
|
|
445
452
|
});
|
|
@@ -38,7 +38,7 @@ import Animated, { useSharedValue, withTiming, useAnimatedStyle, runOnJS } from
|
|
|
38
38
|
import { warn, hasOwn } from '@mpxjs/utils';
|
|
39
39
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
40
40
|
import useNodesRef from './useNodesRef';
|
|
41
|
-
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, HIDDEN_STYLE } from './utils';
|
|
41
|
+
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, HIDDEN_STYLE, useRunOnJSCallback } from './utils';
|
|
42
42
|
import { IntersectionObserverContext, ScrollViewContext } from './context';
|
|
43
43
|
import Portal from './mpx-portal';
|
|
44
44
|
const AnimatedScrollView = RNAnimated.createAnimatedComponent(ScrollView);
|
|
@@ -79,6 +79,23 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
79
79
|
const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, hasPositionFixed, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
80
80
|
const { textStyle, innerStyle = {} } = splitStyle(normalStyle);
|
|
81
81
|
const scrollViewRef = useRef(null);
|
|
82
|
+
const propsRef = useRef(props);
|
|
83
|
+
const refresherStateRef = useRef({
|
|
84
|
+
hasRefresher,
|
|
85
|
+
refresherTriggered
|
|
86
|
+
});
|
|
87
|
+
propsRef.current = props;
|
|
88
|
+
refresherStateRef.current = {
|
|
89
|
+
hasRefresher,
|
|
90
|
+
refresherTriggered
|
|
91
|
+
};
|
|
92
|
+
const runOnJSCallbackRef = useRef({
|
|
93
|
+
setEnableScroll,
|
|
94
|
+
setScrollBounces,
|
|
95
|
+
setRefreshing,
|
|
96
|
+
onRefresh
|
|
97
|
+
});
|
|
98
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
|
|
82
99
|
useNodesRef(props, ref, scrollViewRef, {
|
|
83
100
|
style: normalStyle,
|
|
84
101
|
scrollOffset: scrollOptions,
|
|
@@ -343,6 +360,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
343
360
|
}
|
|
344
361
|
// 处理刷新
|
|
345
362
|
function onRefresh() {
|
|
363
|
+
const { hasRefresher, refresherTriggered } = refresherStateRef.current;
|
|
346
364
|
if (hasRefresher && refresherTriggered === undefined) {
|
|
347
365
|
// 处理使用了自定义刷新组件,又没设置 refresherTriggered 的情况
|
|
348
366
|
setRefreshing(true);
|
|
@@ -354,9 +372,9 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
354
372
|
}
|
|
355
373
|
}, 500);
|
|
356
374
|
}
|
|
357
|
-
const { bindrefresherrefresh } =
|
|
375
|
+
const { bindrefresherrefresh } = propsRef.current;
|
|
358
376
|
bindrefresherrefresh &&
|
|
359
|
-
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef },
|
|
377
|
+
bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, propsRef.current));
|
|
360
378
|
}
|
|
361
379
|
function getRefresherContent(children) {
|
|
362
380
|
let refresherContent = null;
|
|
@@ -404,7 +422,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
404
422
|
'worklet';
|
|
405
423
|
if (enableScrollValue.value !== newValue) {
|
|
406
424
|
enableScrollValue.value = newValue;
|
|
407
|
-
runOnJS(
|
|
425
|
+
runOnJS(runOnJSCallback)('setEnableScroll', newValue);
|
|
408
426
|
}
|
|
409
427
|
}
|
|
410
428
|
const resetScrollState = (value) => {
|
|
@@ -415,7 +433,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
415
433
|
'worklet';
|
|
416
434
|
if (bouncesValue.value !== newValue) {
|
|
417
435
|
bouncesValue.value = newValue;
|
|
418
|
-
runOnJS(
|
|
436
|
+
runOnJS(runOnJSCallback)('setScrollBounces', newValue);
|
|
419
437
|
}
|
|
420
438
|
}
|
|
421
439
|
// 处理下拉刷新的手势
|
|
@@ -460,7 +478,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
460
478
|
if ((event.translationY > 0 && translateY.value < refresherThreshold) || event.translationY < 0) {
|
|
461
479
|
translateY.value = withTiming(0);
|
|
462
480
|
updateScrollState(true);
|
|
463
|
-
runOnJS(
|
|
481
|
+
runOnJS(runOnJSCallback)('setRefreshing', false);
|
|
464
482
|
}
|
|
465
483
|
else {
|
|
466
484
|
translateY.value = withTiming(refresherHeight.value);
|
|
@@ -469,13 +487,13 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
|
|
|
469
487
|
else if (event.translationY >= refresherHeight.value) {
|
|
470
488
|
// 触发刷新
|
|
471
489
|
translateY.value = withTiming(refresherHeight.value);
|
|
472
|
-
runOnJS(
|
|
490
|
+
runOnJS(runOnJSCallback)('onRefresh');
|
|
473
491
|
}
|
|
474
492
|
else {
|
|
475
493
|
// 回弹
|
|
476
494
|
translateY.value = withTiming(0);
|
|
477
495
|
updateScrollState(true);
|
|
478
|
-
runOnJS(
|
|
496
|
+
runOnJS(runOnJSCallback)('setRefreshing', false);
|
|
479
497
|
}
|
|
480
498
|
})
|
|
481
499
|
.simultaneousWithExternalGesture(scrollViewRef);
|
|
@@ -4,7 +4,7 @@ import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS
|
|
|
4
4
|
import React, { forwardRef, useRef, useEffect, useMemo, createElement } from 'react';
|
|
5
5
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
6
6
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
7
|
-
import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, flatGesture } from './utils';
|
|
7
|
+
import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, flatGesture, useRunOnJSCallback } from './utils';
|
|
8
8
|
import { SwiperContext } from './context';
|
|
9
9
|
import Portal from './mpx-portal';
|
|
10
10
|
/**
|
|
@@ -71,7 +71,7 @@ const easeMap = {
|
|
|
71
71
|
easeInOutCubic: Easing.inOut(Easing.cubic)
|
|
72
72
|
};
|
|
73
73
|
const SwiperWrapper = forwardRef((props, ref) => {
|
|
74
|
-
const { 'indicator-dots': showPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, autoplay = false, circular = false, disableGesture = false, bindchange } = props;
|
|
74
|
+
const { 'indicator-dots': showPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, 'simultaneous-handlers': originSimultaneousHandlers = [], 'wait-for': waitFor = [], style = {}, autoplay = false, circular = false, disableGesture = false, current: propCurrent = 0, bindchange } = props;
|
|
75
75
|
const easeingFunc = props['easing-function'] || 'default';
|
|
76
76
|
const easeDuration = props.duration || 500;
|
|
77
77
|
const horizontal = props.vertical !== undefined ? !props.vertical : true;
|
|
@@ -112,14 +112,16 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
112
112
|
// 每个元素的宽度 or 高度,有固定值直接初始化无则0
|
|
113
113
|
const step = useSharedValue(initStep);
|
|
114
114
|
// 记录选中元素的索引值
|
|
115
|
-
const currentIndex = useSharedValue(
|
|
115
|
+
const currentIndex = useSharedValue(propCurrent);
|
|
116
116
|
// const initOffset = getOffset(props.current || 0, initStep)
|
|
117
117
|
// 记录元素的偏移量
|
|
118
|
-
const offset = useSharedValue(getOffset(
|
|
118
|
+
const offset = useSharedValue(getOffset(propCurrent, initStep));
|
|
119
119
|
const strAbso = 'absolute' + dir.toUpperCase();
|
|
120
120
|
const strVelocity = 'velocity' + dir.toUpperCase();
|
|
121
121
|
// 标识手指触摸和抬起, 起点在onBegin
|
|
122
122
|
const touchfinish = useSharedValue(true);
|
|
123
|
+
// 记录onUpdate时的方向,用于进行onFinalize中的值修正
|
|
124
|
+
const preUpdateTransDir = useSharedValue(0);
|
|
123
125
|
// 记录上一帧的绝对定位坐标
|
|
124
126
|
const preAbsolutePos = useSharedValue(0);
|
|
125
127
|
// 记录从onBegin 到 onTouchesUp 时移动的距离
|
|
@@ -170,7 +172,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
170
172
|
const iStep = dir === 'x' ? realWidth : realHeight;
|
|
171
173
|
if (iStep !== step.value) {
|
|
172
174
|
step.value = iStep;
|
|
173
|
-
updateCurrent(
|
|
175
|
+
updateCurrent(propCurrent, iStep);
|
|
174
176
|
updateAutoplay();
|
|
175
177
|
}
|
|
176
178
|
}
|
|
@@ -272,7 +274,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
272
274
|
easing: easeMap[easeingFunc]
|
|
273
275
|
}, () => {
|
|
274
276
|
currentIndex.value = nextIndex;
|
|
275
|
-
runOnJS(
|
|
277
|
+
runOnJS(runOnJSCallback)('loop');
|
|
276
278
|
});
|
|
277
279
|
}
|
|
278
280
|
else {
|
|
@@ -288,7 +290,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
288
290
|
// 将开始位置设置为真正的位置
|
|
289
291
|
offset.value = initOffset;
|
|
290
292
|
currentIndex.value = nextIndex;
|
|
291
|
-
runOnJS(
|
|
293
|
+
runOnJS(runOnJSCallback)('loop');
|
|
292
294
|
});
|
|
293
295
|
}
|
|
294
296
|
else {
|
|
@@ -300,7 +302,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
300
302
|
easing: easeMap[easeingFunc]
|
|
301
303
|
}, () => {
|
|
302
304
|
currentIndex.value = nextIndex;
|
|
303
|
-
runOnJS(
|
|
305
|
+
runOnJS(runOnJSCallback)('loop');
|
|
304
306
|
});
|
|
305
307
|
}
|
|
306
308
|
}
|
|
@@ -326,11 +328,16 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
326
328
|
};
|
|
327
329
|
}, []);
|
|
328
330
|
function handleSwiperChange(current) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
bindchange && bindchange(eventData);
|
|
332
|
-
}
|
|
331
|
+
const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
|
|
332
|
+
bindchange && bindchange(eventData);
|
|
333
333
|
}
|
|
334
|
+
const runOnJSCallbackRef = useRef({
|
|
335
|
+
loop,
|
|
336
|
+
pauseLoop,
|
|
337
|
+
resumeLoop,
|
|
338
|
+
handleSwiperChange
|
|
339
|
+
});
|
|
340
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
|
|
334
341
|
function getOffset(index, stepValue) {
|
|
335
342
|
if (!stepValue)
|
|
336
343
|
return 0;
|
|
@@ -348,12 +355,12 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
348
355
|
const targetOffset = getOffset(index || 0, stepValue);
|
|
349
356
|
if (targetOffset !== offset.value) {
|
|
350
357
|
// 内部基于props.current!==currentIndex.value决定是否使用动画及更新currentIndex.value
|
|
351
|
-
if (
|
|
358
|
+
if (propCurrent !== undefined && propCurrent !== currentIndex.value) {
|
|
352
359
|
offset.value = withTiming(targetOffset, {
|
|
353
360
|
duration: easeDuration,
|
|
354
361
|
easing: easeMap[easeingFunc]
|
|
355
362
|
}, () => {
|
|
356
|
-
currentIndex.value =
|
|
363
|
+
currentIndex.value = propCurrent;
|
|
357
364
|
});
|
|
358
365
|
}
|
|
359
366
|
else {
|
|
@@ -372,8 +379,8 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
372
379
|
// 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
|
|
373
380
|
useAnimatedReaction(() => currentIndex.value, (newIndex, preIndex) => {
|
|
374
381
|
// 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
|
|
375
|
-
if (newIndex !== preIndex && bindchange) {
|
|
376
|
-
runOnJS(
|
|
382
|
+
if (newIndex !== preIndex && preIndex !== null && preIndex !== undefined && bindchange) {
|
|
383
|
+
runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent);
|
|
377
384
|
}
|
|
378
385
|
});
|
|
379
386
|
useEffect(() => {
|
|
@@ -404,12 +411,12 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
404
411
|
}
|
|
405
412
|
}, [children.length]);
|
|
406
413
|
useEffect(() => {
|
|
407
|
-
// 1. 如果用户在touch的过程中, 外部更新了current
|
|
414
|
+
// 1. 如果用户在touch的过程中, 外部更新了current以内部为准(小程序表现)
|
|
408
415
|
// 2. 手指滑动过程中更新索引,外部会把current再传入进来,导致offset直接更新,增加判断不同才更新
|
|
409
|
-
if (
|
|
410
|
-
updateCurrent(
|
|
416
|
+
if (propCurrent !== currentIndex.value && touchfinish.value) {
|
|
417
|
+
updateCurrent(propCurrent, step.value);
|
|
411
418
|
}
|
|
412
|
-
}, [
|
|
419
|
+
}, [propCurrent]);
|
|
413
420
|
useEffect(() => {
|
|
414
421
|
autoplayShared.value = autoplay;
|
|
415
422
|
updateAutoplay();
|
|
@@ -502,7 +509,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
502
509
|
if (touchfinish.value !== false) {
|
|
503
510
|
currentIndex.value = selectedIndex;
|
|
504
511
|
offset.value = resetOffset;
|
|
505
|
-
runOnJS(
|
|
512
|
+
runOnJS(runOnJSCallback)('resumeLoop');
|
|
506
513
|
}
|
|
507
514
|
});
|
|
508
515
|
}
|
|
@@ -513,7 +520,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
513
520
|
}, () => {
|
|
514
521
|
if (touchfinish.value !== false) {
|
|
515
522
|
currentIndex.value = selectedIndex;
|
|
516
|
-
runOnJS(
|
|
523
|
+
runOnJS(runOnJSCallback)('resumeLoop');
|
|
517
524
|
}
|
|
518
525
|
});
|
|
519
526
|
}
|
|
@@ -535,7 +542,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
535
542
|
}, () => {
|
|
536
543
|
if (touchfinish.value !== false) {
|
|
537
544
|
currentIndex.value = moveToIndex;
|
|
538
|
-
runOnJS(
|
|
545
|
+
runOnJS(runOnJSCallback)('resumeLoop');
|
|
539
546
|
}
|
|
540
547
|
});
|
|
541
548
|
}
|
|
@@ -562,20 +569,11 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
562
569
|
'worklet';
|
|
563
570
|
const { diffOffset, half, isTriggerUpdateHalf } = computeHalf(eventData);
|
|
564
571
|
if (+diffOffset === 0) {
|
|
565
|
-
runOnJS(
|
|
572
|
+
runOnJS(runOnJSCallback)('resumeLoop');
|
|
566
573
|
}
|
|
567
574
|
else if (isTriggerUpdateHalf) {
|
|
568
|
-
// 如果触发了onUpdate
|
|
569
|
-
|
|
570
|
-
offset.value = withTiming(-targetIndex * step.value, {
|
|
571
|
-
duration: easeDuration,
|
|
572
|
-
easing: easeMap[easeingFunc]
|
|
573
|
-
}, () => {
|
|
574
|
-
if (touchfinish.value !== false) {
|
|
575
|
-
currentIndex.value = targetIndex;
|
|
576
|
-
runOnJS(resumeLoop)();
|
|
577
|
-
}
|
|
578
|
-
});
|
|
575
|
+
// 如果触发了onUpdate时的索引变更
|
|
576
|
+
handleEnd(eventData);
|
|
579
577
|
}
|
|
580
578
|
else if (half) {
|
|
581
579
|
handleEnd(eventData);
|
|
@@ -651,19 +649,20 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
651
649
|
return;
|
|
652
650
|
touchfinish.value = false;
|
|
653
651
|
cancelAnimation(offset);
|
|
654
|
-
runOnJS(
|
|
652
|
+
runOnJS(runOnJSCallback)('pauseLoop');
|
|
655
653
|
preAbsolutePos.value = e[strAbso];
|
|
656
654
|
moveTranstion.value = e[strAbso];
|
|
657
655
|
})
|
|
658
656
|
.onUpdate((e) => {
|
|
659
657
|
'worklet';
|
|
660
|
-
if (touchfinish.value)
|
|
661
|
-
return;
|
|
662
658
|
const moveDistance = e[strAbso] - preAbsolutePos.value;
|
|
659
|
+
if (touchfinish.value || moveDistance === 0)
|
|
660
|
+
return;
|
|
663
661
|
const eventData = {
|
|
664
662
|
translation: moveDistance,
|
|
665
663
|
transdir: moveDistance
|
|
666
664
|
};
|
|
665
|
+
preUpdateTransDir.value = moveDistance;
|
|
667
666
|
// 1. 支持滑动中超出一半更新索引的能力:只更新索引并不会影响onFinalize依据当前offset计算的索引
|
|
668
667
|
const { half } = computeHalf(eventData);
|
|
669
668
|
if (childrenLength.value > 1 && half) {
|
|
@@ -704,11 +703,17 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
704
703
|
if (touchfinish.value)
|
|
705
704
|
return;
|
|
706
705
|
touchfinish.value = true;
|
|
706
|
+
/**
|
|
707
|
+
* 安卓修正
|
|
708
|
+
* 问题:部分安卓机型onFinalize中拿到的absoluteX 有问题
|
|
709
|
+
* 案例:比如手指从右向左滑的时候,onUpdate拿到的是241.64346313476562, 而onFinalize中拿到的是241.81817626953125,理论上onFinalize中应该比onUpdate小才对吧
|
|
710
|
+
* 解决方式:修正
|
|
711
|
+
*/
|
|
707
712
|
// 触发过onUpdate正常情况下e[strAbso] - preAbsolutePos.value=0; 未触发过onUpdate的情况下e[strAbso] - preAbsolutePos.value 不为0
|
|
708
713
|
const moveDistance = e[strAbso] - preAbsolutePos.value;
|
|
709
714
|
const eventData = {
|
|
710
715
|
translation: moveDistance,
|
|
711
|
-
transdir: moveDistance
|
|
716
|
+
transdir: Math.abs(moveDistance) > 1 ? moveDistance : preUpdateTransDir.value
|
|
712
717
|
};
|
|
713
718
|
// 1. 只有一个元素:循环 和 非循环状态,都走回弹效果
|
|
714
719
|
if (childrenLength.value === 1) {
|
|
@@ -22,7 +22,7 @@ import { StyleSheet, View, LayoutChangeEvent } from 'react-native'
|
|
|
22
22
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
23
23
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
24
24
|
import { MovableAreaContext } from './context'
|
|
25
|
-
import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject, omit, useNavigation } from './utils'
|
|
25
|
+
import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject, omit, useNavigation, useRunOnJSCallback } from './utils'
|
|
26
26
|
import { GestureDetector, Gesture, GestureTouchEvent, GestureStateChangeEvent, PanGestureHandlerEventPayload, PanGesture } from 'react-native-gesture-handler'
|
|
27
27
|
import Animated, {
|
|
28
28
|
useSharedValue,
|
|
@@ -30,7 +30,6 @@ import Animated, {
|
|
|
30
30
|
withDecay,
|
|
31
31
|
runOnJS,
|
|
32
32
|
runOnUI,
|
|
33
|
-
useAnimatedReaction,
|
|
34
33
|
withSpring
|
|
35
34
|
} from 'react-native-reanimated'
|
|
36
35
|
import { collectDataset, noop } from '@mpxjs/utils'
|
|
@@ -87,7 +86,6 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
87
86
|
const layoutRef = useRef<any>({})
|
|
88
87
|
const changeSource = useRef<any>('')
|
|
89
88
|
const hasLayoutRef = useRef(false)
|
|
90
|
-
|
|
91
89
|
const propsRef = useRef<any>({})
|
|
92
90
|
propsRef.current = (props || {}) as MovableViewProps
|
|
93
91
|
|
|
@@ -202,16 +200,6 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
202
200
|
)
|
|
203
201
|
}, [])
|
|
204
202
|
|
|
205
|
-
// 节流版本的 change 事件触发
|
|
206
|
-
const handleTriggerChangeThrottled = useCallback(({ x, y, type }: { x: number; y: number; type?: string }) => {
|
|
207
|
-
'worklet'
|
|
208
|
-
const now = Date.now()
|
|
209
|
-
if (now - lastChangeTime.value >= changeThrottleTime) {
|
|
210
|
-
lastChangeTime.value = now
|
|
211
|
-
runOnJS(handleTriggerChange)({ x, y, type })
|
|
212
|
-
}
|
|
213
|
-
}, [changeThrottleTime])
|
|
214
|
-
|
|
215
203
|
useEffect(() => {
|
|
216
204
|
runOnUI(() => {
|
|
217
205
|
if (offsetX.value !== x || offsetY.value !== y) {
|
|
@@ -233,7 +221,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
233
221
|
: newY
|
|
234
222
|
}
|
|
235
223
|
if (bindchange) {
|
|
236
|
-
runOnJS(
|
|
224
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
237
225
|
x: newX,
|
|
238
226
|
y: newY,
|
|
239
227
|
type: 'setData'
|
|
@@ -408,13 +396,31 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
408
396
|
catchtouchend && catchtouchend(e)
|
|
409
397
|
}
|
|
410
398
|
|
|
399
|
+
const runOnJSCallbackRef = useRef({
|
|
400
|
+
handleTriggerChange,
|
|
401
|
+
triggerStartOnJS,
|
|
402
|
+
triggerMoveOnJS,
|
|
403
|
+
triggerEndOnJS
|
|
404
|
+
})
|
|
405
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
|
|
406
|
+
|
|
407
|
+
// 节流版本的 change 事件触发
|
|
408
|
+
const handleTriggerChangeThrottled = useCallback(({ x, y, type }: { x: number; y: number; type?: string }) => {
|
|
409
|
+
'worklet'
|
|
410
|
+
const now = Date.now()
|
|
411
|
+
if (now - lastChangeTime.value >= changeThrottleTime) {
|
|
412
|
+
lastChangeTime.value = now
|
|
413
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', { x, y, type })
|
|
414
|
+
}
|
|
415
|
+
}, [changeThrottleTime])
|
|
416
|
+
|
|
411
417
|
const gesture = useMemo(() => {
|
|
412
418
|
const handleTriggerMove = (e: GestureTouchEvent) => {
|
|
413
419
|
'worklet'
|
|
414
420
|
const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove
|
|
415
421
|
const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove
|
|
416
422
|
if (hasTouchmove || hasCatchTouchmove) {
|
|
417
|
-
runOnJS(
|
|
423
|
+
runOnJS(runOnJSCallback)('triggerMoveOnJS', {
|
|
418
424
|
e,
|
|
419
425
|
touchEvent: touchEvent.value,
|
|
420
426
|
hasTouchmove,
|
|
@@ -433,7 +439,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
433
439
|
y: changedTouches.y
|
|
434
440
|
}
|
|
435
441
|
if (bindtouchstart || catchtouchstart) {
|
|
436
|
-
runOnJS(
|
|
442
|
+
runOnJS(runOnJSCallback)('triggerStartOnJS', { e })
|
|
437
443
|
}
|
|
438
444
|
})
|
|
439
445
|
.onStart(() => {
|
|
@@ -487,7 +493,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
487
493
|
isFirstTouch.value = true
|
|
488
494
|
isMoving.value = false
|
|
489
495
|
if (bindtouchend || catchtouchend) {
|
|
490
|
-
runOnJS(
|
|
496
|
+
runOnJS(runOnJSCallback)('triggerEndOnJS', { e })
|
|
491
497
|
}
|
|
492
498
|
})
|
|
493
499
|
.onEnd((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
@@ -515,7 +521,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
515
521
|
: y
|
|
516
522
|
}
|
|
517
523
|
if (bindchange) {
|
|
518
|
-
runOnJS(
|
|
524
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
519
525
|
x,
|
|
520
526
|
y
|
|
521
527
|
})
|
|
@@ -532,7 +538,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
532
538
|
}, () => {
|
|
533
539
|
xInertialMotion.value = false
|
|
534
540
|
if (bindchange) {
|
|
535
|
-
runOnJS(
|
|
541
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
536
542
|
x: offsetX.value,
|
|
537
543
|
y: offsetY.value
|
|
538
544
|
})
|
|
@@ -548,7 +554,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
548
554
|
}, () => {
|
|
549
555
|
yInertialMotion.value = false
|
|
550
556
|
if (bindchange) {
|
|
551
|
-
runOnJS(
|
|
557
|
+
runOnJS(runOnJSCallback)('handleTriggerChange', {
|
|
552
558
|
x: offsetX.value,
|
|
553
559
|
y: offsetY.value
|
|
554
560
|
})
|
|
@@ -38,7 +38,7 @@ import Animated, { useSharedValue, withTiming, useAnimatedStyle, runOnJS } from
|
|
|
38
38
|
import { warn, hasOwn } from '@mpxjs/utils'
|
|
39
39
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
40
40
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
41
|
-
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, GestureHandler, HIDDEN_STYLE } from './utils'
|
|
41
|
+
import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, GestureHandler, HIDDEN_STYLE, useRunOnJSCallback } from './utils'
|
|
42
42
|
import { IntersectionObserverContext, ScrollViewContext } from './context'
|
|
43
43
|
import Portal from './mpx-portal'
|
|
44
44
|
|
|
@@ -210,6 +210,27 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
210
210
|
const { textStyle, innerStyle = {} } = splitStyle(normalStyle)
|
|
211
211
|
|
|
212
212
|
const scrollViewRef = useRef<ScrollView>(null)
|
|
213
|
+
|
|
214
|
+
const propsRef = useRef(props)
|
|
215
|
+
const refresherStateRef = useRef({
|
|
216
|
+
hasRefresher,
|
|
217
|
+
refresherTriggered
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
propsRef.current = props
|
|
221
|
+
refresherStateRef.current = {
|
|
222
|
+
hasRefresher,
|
|
223
|
+
refresherTriggered
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const runOnJSCallbackRef = useRef({
|
|
227
|
+
setEnableScroll,
|
|
228
|
+
setScrollBounces,
|
|
229
|
+
setRefreshing,
|
|
230
|
+
onRefresh
|
|
231
|
+
})
|
|
232
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
|
|
233
|
+
|
|
213
234
|
useNodesRef(props, ref, scrollViewRef, {
|
|
214
235
|
style: normalStyle,
|
|
215
236
|
scrollOffset: scrollOptions,
|
|
@@ -518,6 +539,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
518
539
|
|
|
519
540
|
// 处理刷新
|
|
520
541
|
function onRefresh () {
|
|
542
|
+
const { hasRefresher, refresherTriggered } = refresherStateRef.current
|
|
521
543
|
if (hasRefresher && refresherTriggered === undefined) {
|
|
522
544
|
// 处理使用了自定义刷新组件,又没设置 refresherTriggered 的情况
|
|
523
545
|
setRefreshing(true)
|
|
@@ -529,10 +551,10 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
529
551
|
}
|
|
530
552
|
}, 500)
|
|
531
553
|
}
|
|
532
|
-
const { bindrefresherrefresh } =
|
|
554
|
+
const { bindrefresherrefresh } = propsRef.current
|
|
533
555
|
bindrefresherrefresh &&
|
|
534
556
|
bindrefresherrefresh(
|
|
535
|
-
getCustomEvent('refresherrefresh', {}, { layoutRef },
|
|
557
|
+
getCustomEvent('refresherrefresh', {}, { layoutRef }, propsRef.current)
|
|
536
558
|
)
|
|
537
559
|
}
|
|
538
560
|
|
|
@@ -587,7 +609,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
587
609
|
'worklet'
|
|
588
610
|
if (enableScrollValue.value !== newValue) {
|
|
589
611
|
enableScrollValue.value = newValue
|
|
590
|
-
runOnJS(
|
|
612
|
+
runOnJS(runOnJSCallback)('setEnableScroll', newValue)
|
|
591
613
|
}
|
|
592
614
|
}
|
|
593
615
|
|
|
@@ -600,7 +622,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
600
622
|
'worklet'
|
|
601
623
|
if (bouncesValue.value !== newValue) {
|
|
602
624
|
bouncesValue.value = newValue
|
|
603
|
-
runOnJS(
|
|
625
|
+
runOnJS(runOnJSCallback)('setScrollBounces', newValue)
|
|
604
626
|
}
|
|
605
627
|
}
|
|
606
628
|
|
|
@@ -649,19 +671,19 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
649
671
|
if ((event.translationY > 0 && translateY.value < refresherThreshold) || event.translationY < 0) {
|
|
650
672
|
translateY.value = withTiming(0)
|
|
651
673
|
updateScrollState(true)
|
|
652
|
-
runOnJS(
|
|
674
|
+
runOnJS(runOnJSCallback)('setRefreshing', false)
|
|
653
675
|
} else {
|
|
654
676
|
translateY.value = withTiming(refresherHeight.value)
|
|
655
677
|
}
|
|
656
678
|
} else if (event.translationY >= refresherHeight.value) {
|
|
657
679
|
// 触发刷新
|
|
658
680
|
translateY.value = withTiming(refresherHeight.value)
|
|
659
|
-
runOnJS(
|
|
681
|
+
runOnJS(runOnJSCallback)('onRefresh')
|
|
660
682
|
} else {
|
|
661
683
|
// 回弹
|
|
662
684
|
translateY.value = withTiming(0)
|
|
663
685
|
updateScrollState(true)
|
|
664
|
-
runOnJS(
|
|
686
|
+
runOnJS(runOnJSCallback)('setRefreshing', false)
|
|
665
687
|
}
|
|
666
688
|
})
|
|
667
689
|
.simultaneousWithExternalGesture(scrollViewRef)
|
|
@@ -5,7 +5,7 @@ import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS
|
|
|
5
5
|
import React, { JSX, forwardRef, useRef, useEffect, ReactNode, ReactElement, useMemo, createElement } from 'react'
|
|
6
6
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
7
7
|
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
|
|
8
|
-
import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, GestureHandler, flatGesture } from './utils'
|
|
8
|
+
import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren, extendObject, GestureHandler, flatGesture, useRunOnJSCallback } from './utils'
|
|
9
9
|
import { SwiperContext } from './context'
|
|
10
10
|
import Portal from './mpx-portal'
|
|
11
11
|
/**
|
|
@@ -148,6 +148,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
148
148
|
autoplay = false,
|
|
149
149
|
circular = false,
|
|
150
150
|
disableGesture = false,
|
|
151
|
+
current: propCurrent = 0,
|
|
151
152
|
bindchange
|
|
152
153
|
} = props
|
|
153
154
|
const easeingFunc = props['easing-function'] || 'default'
|
|
@@ -198,14 +199,16 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
198
199
|
// 每个元素的宽度 or 高度,有固定值直接初始化无则0
|
|
199
200
|
const step = useSharedValue(initStep)
|
|
200
201
|
// 记录选中元素的索引值
|
|
201
|
-
const currentIndex = useSharedValue(
|
|
202
|
+
const currentIndex = useSharedValue(propCurrent)
|
|
202
203
|
// const initOffset = getOffset(props.current || 0, initStep)
|
|
203
204
|
// 记录元素的偏移量
|
|
204
|
-
const offset = useSharedValue(getOffset(
|
|
205
|
+
const offset = useSharedValue(getOffset(propCurrent, initStep))
|
|
205
206
|
const strAbso = 'absolute' + dir.toUpperCase() as StrAbsoType
|
|
206
207
|
const strVelocity = 'velocity' + dir.toUpperCase() as StrVelocityType
|
|
207
208
|
// 标识手指触摸和抬起, 起点在onBegin
|
|
208
209
|
const touchfinish = useSharedValue(true)
|
|
210
|
+
// 记录onUpdate时的方向,用于进行onFinalize中的值修正
|
|
211
|
+
const preUpdateTransDir = useSharedValue(0)
|
|
209
212
|
// 记录上一帧的绝对定位坐标
|
|
210
213
|
const preAbsolutePos = useSharedValue(0)
|
|
211
214
|
// 记录从onBegin 到 onTouchesUp 时移动的距离
|
|
@@ -270,7 +273,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
270
273
|
const iStep = dir === 'x' ? realWidth : realHeight
|
|
271
274
|
if (iStep !== step.value) {
|
|
272
275
|
step.value = iStep
|
|
273
|
-
updateCurrent(
|
|
276
|
+
updateCurrent(propCurrent, iStep)
|
|
274
277
|
updateAutoplay()
|
|
275
278
|
}
|
|
276
279
|
}
|
|
@@ -374,7 +377,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
374
377
|
easing: easeMap[easeingFunc]
|
|
375
378
|
}, () => {
|
|
376
379
|
currentIndex.value = nextIndex
|
|
377
|
-
runOnJS(
|
|
380
|
+
runOnJS(runOnJSCallback)('loop')
|
|
378
381
|
})
|
|
379
382
|
} else {
|
|
380
383
|
// 默认向右, 向下
|
|
@@ -389,7 +392,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
389
392
|
// 将开始位置设置为真正的位置
|
|
390
393
|
offset.value = initOffset
|
|
391
394
|
currentIndex.value = nextIndex
|
|
392
|
-
runOnJS(
|
|
395
|
+
runOnJS(runOnJSCallback)('loop')
|
|
393
396
|
})
|
|
394
397
|
} else {
|
|
395
398
|
nextIndex = currentIndex.value + 1
|
|
@@ -400,7 +403,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
400
403
|
easing: easeMap[easeingFunc]
|
|
401
404
|
}, () => {
|
|
402
405
|
currentIndex.value = nextIndex
|
|
403
|
-
runOnJS(
|
|
406
|
+
runOnJS(runOnJSCallback)('loop')
|
|
404
407
|
})
|
|
405
408
|
}
|
|
406
409
|
}
|
|
@@ -429,12 +432,18 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
429
432
|
}, [])
|
|
430
433
|
|
|
431
434
|
function handleSwiperChange (current: number) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
bindchange && bindchange(eventData)
|
|
435
|
-
}
|
|
435
|
+
const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
|
|
436
|
+
bindchange && bindchange(eventData)
|
|
436
437
|
}
|
|
437
438
|
|
|
439
|
+
const runOnJSCallbackRef = useRef({
|
|
440
|
+
loop,
|
|
441
|
+
pauseLoop,
|
|
442
|
+
resumeLoop,
|
|
443
|
+
handleSwiperChange
|
|
444
|
+
})
|
|
445
|
+
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
|
|
446
|
+
|
|
438
447
|
function getOffset (index: number, stepValue: number) {
|
|
439
448
|
if (!stepValue) return 0
|
|
440
449
|
let targetOffset = 0
|
|
@@ -451,12 +460,12 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
451
460
|
const targetOffset = getOffset(index || 0, stepValue)
|
|
452
461
|
if (targetOffset !== offset.value) {
|
|
453
462
|
// 内部基于props.current!==currentIndex.value决定是否使用动画及更新currentIndex.value
|
|
454
|
-
if (
|
|
463
|
+
if (propCurrent !== undefined && propCurrent !== currentIndex.value) {
|
|
455
464
|
offset.value = withTiming(targetOffset, {
|
|
456
465
|
duration: easeDuration,
|
|
457
466
|
easing: easeMap[easeingFunc]
|
|
458
467
|
}, () => {
|
|
459
|
-
currentIndex.value =
|
|
468
|
+
currentIndex.value = propCurrent
|
|
460
469
|
})
|
|
461
470
|
} else {
|
|
462
471
|
offset.value = targetOffset
|
|
@@ -473,8 +482,8 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
473
482
|
// 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
|
|
474
483
|
useAnimatedReaction(() => currentIndex.value, (newIndex: number, preIndex: number) => {
|
|
475
484
|
// 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
|
|
476
|
-
if (newIndex !== preIndex && bindchange) {
|
|
477
|
-
runOnJS(
|
|
485
|
+
if (newIndex !== preIndex && preIndex !== null && preIndex !== undefined && bindchange) {
|
|
486
|
+
runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent)
|
|
478
487
|
}
|
|
479
488
|
})
|
|
480
489
|
|
|
@@ -508,12 +517,12 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
508
517
|
}, [children.length])
|
|
509
518
|
|
|
510
519
|
useEffect(() => {
|
|
511
|
-
// 1. 如果用户在touch的过程中, 外部更新了current
|
|
520
|
+
// 1. 如果用户在touch的过程中, 外部更新了current以内部为准(小程序表现)
|
|
512
521
|
// 2. 手指滑动过程中更新索引,外部会把current再传入进来,导致offset直接更新,增加判断不同才更新
|
|
513
|
-
if (
|
|
514
|
-
updateCurrent(
|
|
522
|
+
if (propCurrent !== currentIndex.value && touchfinish.value) {
|
|
523
|
+
updateCurrent(propCurrent, step.value)
|
|
515
524
|
}
|
|
516
|
-
}, [
|
|
525
|
+
}, [propCurrent])
|
|
517
526
|
|
|
518
527
|
useEffect(() => {
|
|
519
528
|
autoplayShared.value = autoplay
|
|
@@ -603,7 +612,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
603
612
|
if (touchfinish.value !== false) {
|
|
604
613
|
currentIndex.value = selectedIndex
|
|
605
614
|
offset.value = resetOffset
|
|
606
|
-
runOnJS(
|
|
615
|
+
runOnJS(runOnJSCallback)('resumeLoop')
|
|
607
616
|
}
|
|
608
617
|
})
|
|
609
618
|
} else {
|
|
@@ -613,7 +622,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
613
622
|
}, () => {
|
|
614
623
|
if (touchfinish.value !== false) {
|
|
615
624
|
currentIndex.value = selectedIndex
|
|
616
|
-
runOnJS(
|
|
625
|
+
runOnJS(runOnJSCallback)('resumeLoop')
|
|
617
626
|
}
|
|
618
627
|
})
|
|
619
628
|
}
|
|
@@ -635,7 +644,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
635
644
|
}, () => {
|
|
636
645
|
if (touchfinish.value !== false) {
|
|
637
646
|
currentIndex.value = moveToIndex
|
|
638
|
-
runOnJS(
|
|
647
|
+
runOnJS(runOnJSCallback)('resumeLoop')
|
|
639
648
|
}
|
|
640
649
|
})
|
|
641
650
|
}
|
|
@@ -662,19 +671,10 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
662
671
|
'worklet'
|
|
663
672
|
const { diffOffset, half, isTriggerUpdateHalf } = computeHalf(eventData)
|
|
664
673
|
if (+diffOffset === 0) {
|
|
665
|
-
runOnJS(
|
|
674
|
+
runOnJS(runOnJSCallback)('resumeLoop')
|
|
666
675
|
} else if (isTriggerUpdateHalf) {
|
|
667
|
-
// 如果触发了onUpdate
|
|
668
|
-
|
|
669
|
-
offset.value = withTiming(-targetIndex * step.value, {
|
|
670
|
-
duration: easeDuration,
|
|
671
|
-
easing: easeMap[easeingFunc]
|
|
672
|
-
}, () => {
|
|
673
|
-
if (touchfinish.value !== false) {
|
|
674
|
-
currentIndex.value = targetIndex
|
|
675
|
-
runOnJS(resumeLoop)()
|
|
676
|
-
}
|
|
677
|
-
})
|
|
676
|
+
// 如果触发了onUpdate时的索引变更
|
|
677
|
+
handleEnd(eventData)
|
|
678
678
|
} else if (half) {
|
|
679
679
|
handleEnd(eventData)
|
|
680
680
|
} else {
|
|
@@ -745,18 +745,19 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
745
745
|
if (!step.value) return
|
|
746
746
|
touchfinish.value = false
|
|
747
747
|
cancelAnimation(offset)
|
|
748
|
-
runOnJS(
|
|
748
|
+
runOnJS(runOnJSCallback)('pauseLoop')
|
|
749
749
|
preAbsolutePos.value = e[strAbso]
|
|
750
750
|
moveTranstion.value = e[strAbso]
|
|
751
751
|
})
|
|
752
752
|
.onUpdate((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
753
753
|
'worklet'
|
|
754
|
-
if (touchfinish.value) return
|
|
755
754
|
const moveDistance = e[strAbso] - preAbsolutePos.value
|
|
755
|
+
if (touchfinish.value || moveDistance === 0) return
|
|
756
756
|
const eventData = {
|
|
757
757
|
translation: moveDistance,
|
|
758
758
|
transdir: moveDistance
|
|
759
759
|
}
|
|
760
|
+
preUpdateTransDir.value = moveDistance
|
|
760
761
|
// 1. 支持滑动中超出一半更新索引的能力:只更新索引并不会影响onFinalize依据当前offset计算的索引
|
|
761
762
|
const { half } = computeHalf(eventData)
|
|
762
763
|
if (childrenLength.value > 1 && half) {
|
|
@@ -794,11 +795,17 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
|
|
|
794
795
|
'worklet'
|
|
795
796
|
if (touchfinish.value) return
|
|
796
797
|
touchfinish.value = true
|
|
798
|
+
/**
|
|
799
|
+
* 安卓修正
|
|
800
|
+
* 问题:部分安卓机型onFinalize中拿到的absoluteX 有问题
|
|
801
|
+
* 案例:比如手指从右向左滑的时候,onUpdate拿到的是241.64346313476562, 而onFinalize中拿到的是241.81817626953125,理论上onFinalize中应该比onUpdate小才对吧
|
|
802
|
+
* 解决方式:修正
|
|
803
|
+
*/
|
|
797
804
|
// 触发过onUpdate正常情况下e[strAbso] - preAbsolutePos.value=0; 未触发过onUpdate的情况下e[strAbso] - preAbsolutePos.value 不为0
|
|
798
805
|
const moveDistance = e[strAbso] - preAbsolutePos.value
|
|
799
806
|
const eventData = {
|
|
800
807
|
translation: moveDistance,
|
|
801
|
-
transdir: moveDistance
|
|
808
|
+
transdir: Math.abs(moveDistance) > 1 ? moveDistance : preUpdateTransDir.value
|
|
802
809
|
}
|
|
803
810
|
// 1. 只有一个元素:循环 和 非循环状态,都走回弹效果
|
|
804
811
|
if (childrenLength.value === 1) {
|
package/package.json
CHANGED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
|
|
2
|
-
const { RetryRuntimeGlobal } = require('../retry-runtime-module')
|
|
3
|
-
const parseRequest = require('../utils/parse-request')
|
|
4
|
-
|
|
5
|
-
class ImportDependencyTemplate extends (
|
|
6
|
-
ModuleDependency.Template
|
|
7
|
-
) {
|
|
8
|
-
/**
|
|
9
|
-
* @param {Dependency} dependency the dependency for which the template should be applied
|
|
10
|
-
* @param {ReplaceSource} source the current replace source which can be modified
|
|
11
|
-
* @param {DependencyTemplateContext} templateContext the context object
|
|
12
|
-
* @returns {void}
|
|
13
|
-
*/
|
|
14
|
-
apply (
|
|
15
|
-
dependency,
|
|
16
|
-
source,
|
|
17
|
-
{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
|
|
18
|
-
) {
|
|
19
|
-
const dep = /** @type {ImportDependency} */ (dependency)
|
|
20
|
-
const block = /** @type {AsyncDependenciesBlock} */ (
|
|
21
|
-
moduleGraph.getParentBlock(dep)
|
|
22
|
-
)
|
|
23
|
-
let content = runtimeTemplate.moduleNamespacePromise({
|
|
24
|
-
chunkGraph,
|
|
25
|
-
block: block,
|
|
26
|
-
module: /** @type {Module} */ (moduleGraph.getModule(dep)),
|
|
27
|
-
request: dep.request,
|
|
28
|
-
strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
|
|
29
|
-
message: 'import()',
|
|
30
|
-
runtimeRequirements
|
|
31
|
-
})
|
|
32
|
-
// replace fakeType by 9 to fix require.async to commonjs2 module like 'module.exports = function(){...}'
|
|
33
|
-
content = content.replace(/(__webpack_require__\.t\.bind\(.+,\s*)(\d+)(\s*\))/, (_, p1, p2, p3) => {
|
|
34
|
-
return p1 + '9' + p3
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const { queryObj } = parseRequest(dep.request)
|
|
38
|
-
const retryRequireAsync = queryObj.retryRequireAsync && JSON.parse(queryObj.retryRequireAsync)
|
|
39
|
-
|
|
40
|
-
// require.async 的场景且配置了重试次数才注入 RetryRuntimeModule
|
|
41
|
-
if (queryObj.isRequireAsync && retryRequireAsync && retryRequireAsync.times > 0) {
|
|
42
|
-
runtimeRequirements.add(RetryRuntimeGlobal)
|
|
43
|
-
content = `${RetryRuntimeGlobal}(function() { return ${content} }, ${retryRequireAsync.times}, ${retryRequireAsync.interval})`
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
source.replace(dep.range[0], dep.range[1] - 1, content)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module.exports = ImportDependencyTemplate
|