@mpxjs/webpack-plugin 2.10.6-beta.2 → 2.10.6-beta.4
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/file-loader.js +1 -1
- package/lib/index.js +35 -14
- package/lib/platform/index.js +2 -4
- package/lib/platform/json/wx/index.js +43 -25
- package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
- package/lib/platform/template/wx/component-config/index.js +2 -2
- package/lib/platform/template/wx/component-config/template.js +1 -26
- package/lib/platform/template/wx/index.js +5 -11
- package/lib/react/LoadAsyncChunkModule.js +68 -0
- package/lib/react/index.js +3 -1
- package/lib/react/processJSON.js +72 -17
- package/lib/react/processScript.js +4 -3
- package/lib/react/script-helper.js +92 -18
- package/lib/runtime/components/react/AsyncContainer.tsx +217 -0
- package/lib/runtime/components/react/AsyncSuspense.tsx +81 -0
- package/lib/runtime/components/react/dist/AsyncContainer.jsx +160 -0
- package/lib/runtime/components/react/dist/AsyncSuspense.jsx +68 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +53 -27
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
- package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
- package/lib/runtime/components/react/dist/utils.jsx +84 -0
- package/lib/runtime/components/react/getInnerListeners.ts +1 -1
- package/lib/runtime/components/react/mpx-input.tsx +1 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +2 -2
- package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -2
- package/lib/runtime/components/react/mpx-swiper.tsx +53 -25
- package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
- package/lib/runtime/components/react/types/global.d.ts +15 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
- package/lib/runtime/components/react/utils.tsx +83 -1
- package/lib/runtime/optionProcessor.js +2 -2
- package/lib/template-compiler/compiler.js +11 -61
- package/lib/utils/dom-tag-config.js +17 -3
- package/lib/web/index.js +0 -2
- package/lib/web/processScript.js +7 -29
- package/lib/web/processTemplate.js +4 -10
- package/lib/web/script-helper.js +1 -1
- package/package.json +1 -1
- package/lib/dependencies/WriteVfsDependency.js +0 -46
- package/lib/utils/get-template-content.js +0 -47
- package/lib/web/template2vue.js +0 -280
- package/lib/web/wxml-template-loader.js +0 -29
|
@@ -223,14 +223,14 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
223
223
|
setHeight(height || 0);
|
|
224
224
|
}
|
|
225
225
|
nodeRef.current?.measure((x, y, width, height) => {
|
|
226
|
-
const {
|
|
226
|
+
const { top: navigationY = 0 } = navigation?.layout || {};
|
|
227
227
|
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 };
|
|
228
228
|
resetBoundaryAndCheck({ width, height });
|
|
229
229
|
});
|
|
230
230
|
props.onLayout && props.onLayout(e);
|
|
231
231
|
};
|
|
232
232
|
const extendEvent = useCallback((e, type) => {
|
|
233
|
-
const {
|
|
233
|
+
const { top: navigationY = 0 } = navigation?.layout || {};
|
|
234
234
|
const touchArr = [e.changedTouches, e.allTouches];
|
|
235
235
|
touchArr.forEach(touches => {
|
|
236
236
|
touches && touches.forEach((item) => {
|
|
@@ -2,7 +2,7 @@ import Animated, { useAnimatedStyle, interpolate } from 'react-native-reanimated
|
|
|
2
2
|
import { forwardRef, useRef, useContext, createElement } from 'react';
|
|
3
3
|
import useInnerProps from './getInnerListeners';
|
|
4
4
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
5
|
-
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject } from './utils';
|
|
5
|
+
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject, isHarmony } from './utils';
|
|
6
6
|
import { SwiperContext } from './context';
|
|
7
7
|
const _SwiperItem = forwardRef((props, ref) => {
|
|
8
8
|
const { 'enable-var': enableVar, 'external-var-context': externalVarContext, style, customStyle, itemIndex } = props;
|
|
@@ -29,7 +29,7 @@ const _SwiperItem = forwardRef((props, ref) => {
|
|
|
29
29
|
'style'
|
|
30
30
|
], { layoutRef });
|
|
31
31
|
const itemAnimatedStyle = useAnimatedStyle(() => {
|
|
32
|
-
if (!step.value)
|
|
32
|
+
if (!step.value && !isHarmony)
|
|
33
33
|
return {};
|
|
34
34
|
const inputRange = [step.value, 0];
|
|
35
35
|
const outputRange = [0.7, 1];
|
|
@@ -125,6 +125,10 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
125
125
|
const moveTranstion = useSharedValue(0);
|
|
126
126
|
// 记录从onBegin 到 onTouchesUp 的时间
|
|
127
127
|
const moveTime = useSharedValue(0);
|
|
128
|
+
// 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
|
|
129
|
+
const anotherDirectionMove = useSharedValue(0);
|
|
130
|
+
// 另一个方向的
|
|
131
|
+
const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase();
|
|
128
132
|
const timerId = useRef(0);
|
|
129
133
|
const intervalTimer = props.interval || 500;
|
|
130
134
|
const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
|
|
@@ -405,7 +409,11 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
405
409
|
}
|
|
406
410
|
}, [children.length]);
|
|
407
411
|
useEffect(() => {
|
|
408
|
-
|
|
412
|
+
// 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
|
|
413
|
+
// 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
|
|
414
|
+
if (props.current !== currentIndex.value) {
|
|
415
|
+
updateCurrent(props.current || 0, step.value);
|
|
416
|
+
}
|
|
409
417
|
}, [props.current]);
|
|
410
418
|
useEffect(() => {
|
|
411
419
|
autoplayShared.value = autoplay;
|
|
@@ -468,20 +476,26 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
468
476
|
targetOffset: -moveToTargetPos
|
|
469
477
|
};
|
|
470
478
|
}
|
|
471
|
-
function
|
|
479
|
+
function checkUnCircular(eventData) {
|
|
472
480
|
'worklet';
|
|
473
481
|
const { translation } = eventData;
|
|
474
482
|
const currentOffset = Math.abs(offset.value);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
483
|
+
// 向右滑动swiper
|
|
484
|
+
if (translation < 0) {
|
|
485
|
+
const boundaryOffset = step.value * (childrenLength.value - 1);
|
|
486
|
+
const gestureMovePos = Math.abs(translation) + currentOffset;
|
|
487
|
+
return {
|
|
488
|
+
// 防止快速连续向右滑动时,手势移动的距离 加 当前的offset超出边界
|
|
489
|
+
targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
|
|
490
|
+
canMove: currentOffset < boundaryOffset
|
|
491
|
+
};
|
|
482
492
|
}
|
|
483
493
|
else {
|
|
484
|
-
|
|
494
|
+
const gestureMovePos = currentOffset - translation;
|
|
495
|
+
return {
|
|
496
|
+
targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
|
|
497
|
+
canMove: currentOffset > 0
|
|
498
|
+
};
|
|
485
499
|
}
|
|
486
500
|
}
|
|
487
501
|
function handleEnd(eventData) {
|
|
@@ -541,7 +555,7 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
541
555
|
}
|
|
542
556
|
});
|
|
543
557
|
}
|
|
544
|
-
function
|
|
558
|
+
function computeHalf() {
|
|
545
559
|
'worklet';
|
|
546
560
|
const currentOffset = Math.abs(offset.value);
|
|
547
561
|
let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value;
|
|
@@ -551,6 +565,14 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
551
565
|
// 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
|
|
552
566
|
const diffOffset = preOffset - currentOffset;
|
|
553
567
|
const half = Math.abs(diffOffset) > step.value / 2;
|
|
568
|
+
return {
|
|
569
|
+
diffOffset,
|
|
570
|
+
half
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function handleLongPress() {
|
|
574
|
+
'worklet';
|
|
575
|
+
const { diffOffset, half } = computeHalf();
|
|
554
576
|
if (+diffOffset === 0) {
|
|
555
577
|
runOnJS(resumeLoop)();
|
|
556
578
|
}
|
|
@@ -610,19 +632,30 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
610
632
|
runOnJS(pauseLoop)();
|
|
611
633
|
preAbsolutePos.value = e[strAbso];
|
|
612
634
|
moveTranstion.value = e[strAbso];
|
|
635
|
+
anotherDirectionMove.value = e[anotherAbso];
|
|
613
636
|
moveTime.value = new Date().getTime();
|
|
614
637
|
})
|
|
615
|
-
.
|
|
638
|
+
.onUpdate((e) => {
|
|
616
639
|
'worklet';
|
|
617
640
|
if (touchfinish.value)
|
|
618
641
|
return;
|
|
619
|
-
const
|
|
620
|
-
const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
|
|
642
|
+
const moveDistance = e[strAbso] - preAbsolutePos.value;
|
|
621
643
|
const eventData = {
|
|
622
644
|
translation: moveDistance
|
|
623
645
|
};
|
|
624
|
-
//
|
|
625
|
-
|
|
646
|
+
// 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
|
|
647
|
+
const { half } = computeHalf();
|
|
648
|
+
if (half) {
|
|
649
|
+
const { selectedIndex } = getTargetPosition(eventData);
|
|
650
|
+
currentIndex.value = selectedIndex;
|
|
651
|
+
}
|
|
652
|
+
// 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
|
|
653
|
+
const { canMove, targetOffset } = checkUnCircular(eventData);
|
|
654
|
+
if (!circularShared.value) {
|
|
655
|
+
if (canMove) {
|
|
656
|
+
offset.value = targetOffset;
|
|
657
|
+
preAbsolutePos.value = e[strAbso];
|
|
658
|
+
}
|
|
626
659
|
return;
|
|
627
660
|
}
|
|
628
661
|
const { isBoundary, resetOffset } = reachBoundary(eventData);
|
|
@@ -632,30 +665,23 @@ const SwiperWrapper = forwardRef((props, ref) => {
|
|
|
632
665
|
else {
|
|
633
666
|
offset.value = moveDistance + offset.value;
|
|
634
667
|
}
|
|
635
|
-
preAbsolutePos.value =
|
|
668
|
+
preAbsolutePos.value = e[strAbso];
|
|
636
669
|
})
|
|
637
|
-
.
|
|
670
|
+
.onFinalize((e) => {
|
|
638
671
|
'worklet';
|
|
639
672
|
if (touchfinish.value)
|
|
640
673
|
return;
|
|
641
|
-
const
|
|
642
|
-
const moveDistance = touchEventData[strAbso] - moveTranstion.value;
|
|
674
|
+
const moveDistance = e[strAbso] - moveTranstion.value;
|
|
643
675
|
touchfinish.value = true;
|
|
644
676
|
const eventData = {
|
|
645
677
|
translation: moveDistance
|
|
646
678
|
};
|
|
647
|
-
if (childrenLength.value === 1) {
|
|
648
|
-
return handleBackInit();
|
|
649
|
-
}
|
|
650
|
-
// 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
|
|
651
|
-
if (!circularShared.value && !canMove(eventData)) {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
679
|
const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000;
|
|
655
680
|
if (Math.abs(strVelocity) < longPressRatio) {
|
|
656
681
|
handleLongPress();
|
|
657
682
|
}
|
|
658
683
|
else {
|
|
684
|
+
// 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
|
|
659
685
|
handleEnd(eventData);
|
|
660
686
|
}
|
|
661
687
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { forwardRef, useRef, useContext, useMemo, useState } from 'react';
|
|
2
2
|
import { warn, isFunction } from '@mpxjs/utils';
|
|
3
3
|
import Portal from './mpx-portal/index';
|
|
4
|
+
import { usePreventRemove } from '@react-navigation/native';
|
|
4
5
|
import { getCustomEvent } from './getInnerListeners';
|
|
5
6
|
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
|
|
6
7
|
import { WebView } from 'react-native-webview';
|
|
@@ -55,8 +56,8 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
55
56
|
const webViewRef = useRef(null);
|
|
56
57
|
const fristLoaded = useRef(false);
|
|
57
58
|
const isLoadError = useRef(false);
|
|
59
|
+
const isNavigateBack = useRef(false);
|
|
58
60
|
const statusCode = useRef('');
|
|
59
|
-
const [isLoaded, setIsLoaded] = useState(true);
|
|
60
61
|
const defaultWebViewStyle = {
|
|
61
62
|
position: 'absolute',
|
|
62
63
|
left: 0,
|
|
@@ -64,27 +65,18 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
64
65
|
top: 0,
|
|
65
66
|
bottom: 0
|
|
66
67
|
};
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const navigation = useNavigation();
|
|
69
|
+
const [isIntercept, setIsIntercept] = useState(false);
|
|
70
|
+
usePreventRemove(isIntercept, (event) => {
|
|
71
|
+
const { data } = event;
|
|
72
|
+
if (isNavigateBack.current) {
|
|
73
|
+
navigation?.dispatch(data.action);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
71
76
|
webViewRef.current?.goBack();
|
|
72
|
-
e.preventDefault();
|
|
73
77
|
}
|
|
74
78
|
isNavigateBack.current = false;
|
|
75
|
-
};
|
|
76
|
-
const navigation = useNavigation();
|
|
77
|
-
// useEffect(() => {
|
|
78
|
-
// let beforeRemoveSubscription:any
|
|
79
|
-
// if (__mpx_mode__ !== 'ios') {
|
|
80
|
-
// beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
|
|
81
|
-
// }
|
|
82
|
-
// return () => {
|
|
83
|
-
// if (isFunction(beforeRemoveSubscription)) {
|
|
84
|
-
// beforeRemoveSubscription()
|
|
85
|
-
// }
|
|
86
|
-
// }
|
|
87
|
-
// }, [])
|
|
79
|
+
});
|
|
88
80
|
useNodesRef(props, ref, webViewRef, {
|
|
89
81
|
style: defaultWebViewStyle
|
|
90
82
|
});
|
|
@@ -131,13 +123,13 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
131
123
|
};
|
|
132
124
|
const _changeUrl = function (navState) {
|
|
133
125
|
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
|
|
134
|
-
canGoBack.current = navState.canGoBack;
|
|
135
126
|
currentPage.__webViewUrl = navState.url;
|
|
127
|
+
setIsIntercept(navState.canGoBack);
|
|
136
128
|
}
|
|
137
129
|
};
|
|
138
130
|
const _onLoadProgress = function (event) {
|
|
139
131
|
if (__mpx_mode__ !== 'ios') {
|
|
140
|
-
|
|
132
|
+
setIsIntercept(event.nativeEvent.canGoBack);
|
|
141
133
|
}
|
|
142
134
|
};
|
|
143
135
|
const _message = function (res) {
|
|
@@ -227,7 +219,6 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
227
219
|
};
|
|
228
220
|
const onLoadEndHandle = function (res) {
|
|
229
221
|
fristLoaded.current = true;
|
|
230
|
-
setIsLoaded(true);
|
|
231
222
|
const src = res.nativeEvent?.url;
|
|
232
223
|
if (isLoadError.current) {
|
|
233
224
|
isLoadError.current = false;
|
|
@@ -275,18 +266,13 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
275
266
|
setPageLoadErr(true);
|
|
276
267
|
}
|
|
277
268
|
};
|
|
278
|
-
const onLoadStart = function () {
|
|
279
|
-
if (!fristLoaded.current) {
|
|
280
|
-
setIsLoaded(false);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
269
|
return (<Portal>
|
|
284
270
|
{pageLoadErr
|
|
285
271
|
? (<View style={[styles.loadErrorContext, defaultWebViewStyle]}>
|
|
286
272
|
<View style={styles.loadErrorText}><Text style={{ fontSize: 14, color: '#999999' }}>{currentErrorText.text}</Text></View>
|
|
287
273
|
<View style={styles.loadErrorButton} onTouchEnd={_reload}><Text style={{ fontSize: 12, color: '#666666' }}>{currentErrorText.button}</Text></View>
|
|
288
274
|
</View>)
|
|
289
|
-
: (<WebView style={defaultWebViewStyle}
|
|
275
|
+
: (<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} allowsBackForwardNavigationGestures={true}></WebView>)}
|
|
290
276
|
</Portal>);
|
|
291
277
|
});
|
|
292
278
|
_WebView.displayName = 'MpxWebview';
|
|
@@ -48,90 +48,6 @@ const InitialValue = Object.assign({
|
|
|
48
48
|
const TransformOrigin = 'transformOrigin';
|
|
49
49
|
// transform
|
|
50
50
|
const isTransform = (key) => Object.keys(TransformInitial).includes(key);
|
|
51
|
-
// 多value解析
|
|
52
|
-
const parseValues = (str, char = ' ') => {
|
|
53
|
-
let stack = 0;
|
|
54
|
-
let temp = '';
|
|
55
|
-
const result = [];
|
|
56
|
-
for (let i = 0; i < str.length; i++) {
|
|
57
|
-
if (str[i] === '(') {
|
|
58
|
-
stack++;
|
|
59
|
-
}
|
|
60
|
-
else if (str[i] === ')') {
|
|
61
|
-
stack--;
|
|
62
|
-
}
|
|
63
|
-
// 非括号内 或者 非分隔字符且非空
|
|
64
|
-
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
65
|
-
temp += str[i];
|
|
66
|
-
}
|
|
67
|
-
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
68
|
-
result.push(temp);
|
|
69
|
-
temp = '';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return result;
|
|
73
|
-
};
|
|
74
|
-
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
75
|
-
const parseTransform = (transformStr) => {
|
|
76
|
-
const values = parseValues(transformStr);
|
|
77
|
-
const transform = [];
|
|
78
|
-
values.forEach(item => {
|
|
79
|
-
const match = item.match(/([/\w]+)\((.+)\)/);
|
|
80
|
-
if (match && match.length >= 3) {
|
|
81
|
-
let key = match[1];
|
|
82
|
-
const val = match[2];
|
|
83
|
-
switch (key) {
|
|
84
|
-
case 'translateX':
|
|
85
|
-
case 'translateY':
|
|
86
|
-
case 'scaleX':
|
|
87
|
-
case 'scaleY':
|
|
88
|
-
case 'rotateX':
|
|
89
|
-
case 'rotateY':
|
|
90
|
-
case 'rotateZ':
|
|
91
|
-
case 'rotate':
|
|
92
|
-
case 'skewX':
|
|
93
|
-
case 'skewY':
|
|
94
|
-
case 'perspective':
|
|
95
|
-
// rotate 处理成 rotateZ
|
|
96
|
-
key = key === 'rotate' ? 'rotateZ' : key;
|
|
97
|
-
// 单个值处理
|
|
98
|
-
transform.push({ [key]: global.__formatValue(val) });
|
|
99
|
-
break;
|
|
100
|
-
case 'matrix':
|
|
101
|
-
transform.push({ [key]: parseValues(val, ',').map(val => +val) });
|
|
102
|
-
break;
|
|
103
|
-
case 'translate':
|
|
104
|
-
case 'scale':
|
|
105
|
-
case 'skew':
|
|
106
|
-
case 'translate3d': // x y 支持 z不支持
|
|
107
|
-
case 'scale3d': // x y 支持 z不支持
|
|
108
|
-
{
|
|
109
|
-
// 2 个以上的值处理
|
|
110
|
-
key = key.replace('3d', '');
|
|
111
|
-
const vals = parseValues(val, ',').splice(0, 3);
|
|
112
|
-
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
113
|
-
if (vals.length === 1 && key === 'scale') {
|
|
114
|
-
vals.push(vals[0]);
|
|
115
|
-
}
|
|
116
|
-
const xyz = ['X', 'Y', 'Z'];
|
|
117
|
-
transform.push(...vals.map((v, index) => {
|
|
118
|
-
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
|
|
119
|
-
}));
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
return transform;
|
|
126
|
-
};
|
|
127
|
-
// format style
|
|
128
|
-
const formatStyle = (style) => {
|
|
129
|
-
if (!style.transform || Array.isArray(style.transform))
|
|
130
|
-
return style;
|
|
131
|
-
return Object.assign({}, style, {
|
|
132
|
-
transform: parseTransform(style.transform)
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
51
|
// transform 数组转对象
|
|
136
52
|
function getTransformObj(transforms) {
|
|
137
53
|
'worklet';
|
|
@@ -140,7 +56,7 @@ function getTransformObj(transforms) {
|
|
|
140
56
|
}, {});
|
|
141
57
|
}
|
|
142
58
|
export default function useAnimationHooks(props) {
|
|
143
|
-
const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
|
|
59
|
+
const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props;
|
|
144
60
|
const enableStyleAnimation = enableAnimation || !!animation;
|
|
145
61
|
const enableAnimationRef = useRef(enableStyleAnimation);
|
|
146
62
|
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
@@ -148,7 +64,6 @@ export default function useAnimationHooks(props) {
|
|
|
148
64
|
}
|
|
149
65
|
if (!enableAnimationRef.current)
|
|
150
66
|
return { enableStyleAnimation: false };
|
|
151
|
-
const originalStyle = formatStyle(style);
|
|
152
67
|
// id 标识
|
|
153
68
|
const id = animation?.id || -1;
|
|
154
69
|
// 有动画样式的 style key
|
|
@@ -177,7 +92,7 @@ export default function useAnimationHooks(props) {
|
|
|
177
92
|
useEffect(() => {
|
|
178
93
|
// style 更新后同步更新 lastStyleRef & shareValMap
|
|
179
94
|
updateStyleVal();
|
|
180
|
-
}, [
|
|
95
|
+
}, [originalStyle]);
|
|
181
96
|
// ** 获取动画样式prop & 驱动动画
|
|
182
97
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
183
98
|
useEffect(() => {
|
|
@@ -237,6 +237,88 @@ function transformPosition(styleObj, meta) {
|
|
|
237
237
|
meta.hasPositionFixed = true;
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
|
+
// 多value解析
|
|
241
|
+
function parseValues(str, char = ' ') {
|
|
242
|
+
let stack = 0;
|
|
243
|
+
let temp = '';
|
|
244
|
+
const result = [];
|
|
245
|
+
for (let i = 0; i < str.length; i++) {
|
|
246
|
+
if (str[i] === '(') {
|
|
247
|
+
stack++;
|
|
248
|
+
}
|
|
249
|
+
else if (str[i] === ')') {
|
|
250
|
+
stack--;
|
|
251
|
+
}
|
|
252
|
+
// 非括号内 或者 非分隔字符且非空
|
|
253
|
+
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
254
|
+
temp += str[i];
|
|
255
|
+
}
|
|
256
|
+
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
257
|
+
result.push(temp);
|
|
258
|
+
temp = '';
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
262
|
+
}
|
|
263
|
+
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
264
|
+
function parseTransform(transformStr) {
|
|
265
|
+
const values = parseValues(transformStr);
|
|
266
|
+
const transform = [];
|
|
267
|
+
values.forEach(item => {
|
|
268
|
+
const match = item.match(/([/\w]+)\((.+)\)/);
|
|
269
|
+
if (match && match.length >= 3) {
|
|
270
|
+
let key = match[1];
|
|
271
|
+
const val = match[2];
|
|
272
|
+
switch (key) {
|
|
273
|
+
case 'translateX':
|
|
274
|
+
case 'translateY':
|
|
275
|
+
case 'scaleX':
|
|
276
|
+
case 'scaleY':
|
|
277
|
+
case 'rotateX':
|
|
278
|
+
case 'rotateY':
|
|
279
|
+
case 'rotateZ':
|
|
280
|
+
case 'rotate':
|
|
281
|
+
case 'skewX':
|
|
282
|
+
case 'skewY':
|
|
283
|
+
case 'perspective':
|
|
284
|
+
// rotate 处理成 rotateZ
|
|
285
|
+
key = key === 'rotate' ? 'rotateZ' : key;
|
|
286
|
+
// 单个值处理
|
|
287
|
+
transform.push({ [key]: global.__formatValue(val) });
|
|
288
|
+
break;
|
|
289
|
+
case 'matrix':
|
|
290
|
+
transform.push({ [key]: parseValues(val, ',').map(val => +val) });
|
|
291
|
+
break;
|
|
292
|
+
case 'translate':
|
|
293
|
+
case 'scale':
|
|
294
|
+
case 'skew':
|
|
295
|
+
case 'translate3d': // x y 支持 z不支持
|
|
296
|
+
case 'scale3d': // x y 支持 z不支持
|
|
297
|
+
{
|
|
298
|
+
// 2 个以上的值处理
|
|
299
|
+
key = key.replace('3d', '');
|
|
300
|
+
const vals = parseValues(val, ',').splice(0, 3);
|
|
301
|
+
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
302
|
+
if (vals.length === 1 && key === 'scale') {
|
|
303
|
+
vals.push(vals[0]);
|
|
304
|
+
}
|
|
305
|
+
const xyz = ['X', 'Y', 'Z'];
|
|
306
|
+
transform.push(...vals.map((v, index) => {
|
|
307
|
+
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
|
|
308
|
+
}));
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
return transform;
|
|
315
|
+
}
|
|
316
|
+
// format style transform
|
|
317
|
+
function transformTransform(style) {
|
|
318
|
+
if (!style.transform || Array.isArray(style.transform))
|
|
319
|
+
return;
|
|
320
|
+
style.transform = parseTransform(style.transform);
|
|
321
|
+
}
|
|
240
322
|
export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
|
|
241
323
|
const varStyle = {};
|
|
242
324
|
const unoVarStyle = {};
|
|
@@ -365,6 +447,8 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
|
|
|
365
447
|
transformPosition(normalStyle, positionMeta);
|
|
366
448
|
// transform number enum stringify
|
|
367
449
|
transformStringify(normalStyle);
|
|
450
|
+
// transform 字符串格式转化数组格式
|
|
451
|
+
transformTransform(normalStyle);
|
|
368
452
|
return {
|
|
369
453
|
hasVarDec,
|
|
370
454
|
varContextRef,
|
|
@@ -24,7 +24,7 @@ const getTouchEvent = (
|
|
|
24
24
|
) => {
|
|
25
25
|
const { navigation, propsRef, layoutRef } = config
|
|
26
26
|
const props = propsRef.current
|
|
27
|
-
const {
|
|
27
|
+
const { top: navigationY = 0 } = navigation?.layout || {}
|
|
28
28
|
const nativeEvent = event.nativeEvent
|
|
29
29
|
const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent
|
|
30
30
|
const { id } = props
|
|
@@ -218,7 +218,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
218
218
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
219
219
|
|
|
220
220
|
useEffect(() => {
|
|
221
|
-
if (
|
|
221
|
+
if (value !== tmpValue.current) {
|
|
222
222
|
const parsed = parseValue(value)
|
|
223
223
|
tmpValue.current = parsed
|
|
224
224
|
setInputValue(parsed)
|
|
@@ -327,7 +327,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
327
327
|
setHeight(height || 0)
|
|
328
328
|
}
|
|
329
329
|
nodeRef.current?.measure((x: number, y: number, width: number, height: number) => {
|
|
330
|
-
const {
|
|
330
|
+
const { top: navigationY = 0 } = navigation?.layout || {}
|
|
331
331
|
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 }
|
|
332
332
|
resetBoundaryAndCheck({ width, height })
|
|
333
333
|
})
|
|
@@ -335,7 +335,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
const extendEvent = useCallback((e: any, type: 'start' | 'move' | 'end') => {
|
|
338
|
-
const {
|
|
338
|
+
const { top: navigationY = 0 } = navigation?.layout || {}
|
|
339
339
|
const touchArr = [e.changedTouches, e.allTouches]
|
|
340
340
|
touchArr.forEach(touches => {
|
|
341
341
|
touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number; clientX: number; clientY: number }) => {
|
|
@@ -3,7 +3,7 @@ import Animated, { useAnimatedStyle, interpolate, SharedValue } from 'react-nati
|
|
|
3
3
|
import { ReactNode, forwardRef, useRef, useContext, createElement } from 'react'
|
|
4
4
|
import useInnerProps from './getInnerListeners'
|
|
5
5
|
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
|
|
6
|
-
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject } from './utils'
|
|
6
|
+
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, extendObject, isHarmony } from './utils'
|
|
7
7
|
import { SwiperContext } from './context'
|
|
8
8
|
|
|
9
9
|
interface SwiperItemProps {
|
|
@@ -80,7 +80,7 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
|
|
|
80
80
|
],
|
|
81
81
|
{ layoutRef })
|
|
82
82
|
const itemAnimatedStyle = useAnimatedStyle(() => {
|
|
83
|
-
if (!step.value) return {}
|
|
83
|
+
if (!step.value && !isHarmony) return {}
|
|
84
84
|
const inputRange = [step.value, 0]
|
|
85
85
|
const outputRange = [0.7, 1]
|
|
86
86
|
// 实现元素的宽度跟随step从0到真实宽度,且不能触发重新渲染整个组件,通过AnimatedStyle的方式实现
|