@umituz/react-native-video-editor 1.0.35 → 1.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-video-editor",
3
- "version": "1.0.35",
3
+ "version": "1.1.0",
4
4
  "description": "Professional video editor with layer-based timeline, text/image/shape/audio/animation layers, and export functionality",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -21,8 +21,7 @@
21
21
  "video-editor",
22
22
  "timeline",
23
23
  "layers",
24
- "video-export",
25
- "animation"
24
+ "video-export"
26
25
  ],
27
26
  "author": "umituz",
28
27
  "license": "MIT",
@@ -59,7 +58,6 @@
59
58
  "react": "19.1.0",
60
59
  "react-native": "0.81.5",
61
60
  "react-native-gesture-handler": "^2.30.0",
62
- "react-native-reanimated": "^4.2.1",
63
61
  "typescript": "~5.9.2",
64
62
  "@types/react-native": "*",
65
63
  "@typescript-eslint/parser": "*",
@@ -4,9 +4,8 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { StyleSheet } from "react-native";
7
+ import { View, StyleSheet } from "react-native";
8
8
  import { GestureDetector } from "react-native-gesture-handler";
9
- import Animated, { useAnimatedStyle } from "react-native-reanimated";
10
9
  import { useAppDesignTokens } from "@umituz/react-native-design-system";
11
10
  import type { Layer } from "../../domain/entities";
12
11
  import { useDraggableLayerGestures } from "../hooks/useDraggableLayerGestures";
@@ -40,10 +39,7 @@ export const DraggableLayer: React.FC<DraggableLayerProps> = ({
40
39
  const initialHeight = (layer.size.height / 100) * canvasHeight;
41
40
 
42
41
  const {
43
- translateX,
44
- translateY,
45
- width,
46
- height,
42
+ state,
47
43
  composedGesture,
48
44
  topLeftResizeHandler,
49
45
  topRightResizeHandler,
@@ -61,30 +57,27 @@ export const DraggableLayer: React.FC<DraggableLayerProps> = ({
61
57
  onSizeChange,
62
58
  });
63
59
 
64
- const animatedStyle = useAnimatedStyle(() => {
65
- const rotationStr = `${layer.rotation}deg`;
66
- return {
67
- transform: [
68
- { translateX: translateX.value },
69
- { translateY: translateY.value },
70
- { rotate: rotationStr },
71
- ],
72
- opacity: layer.opacity,
73
- width: width.value,
74
- height: height.value,
75
- };
76
- });
60
+ const layerStyle = {
61
+ transform: [
62
+ { translateX: state.x },
63
+ { translateY: state.y },
64
+ { rotate: `${layer.rotation}deg` },
65
+ ],
66
+ opacity: layer.opacity,
67
+ width: state.width,
68
+ height: state.height,
69
+ };
77
70
 
78
71
  return (
79
72
  <GestureDetector gesture={composedGesture}>
80
- <Animated.View
73
+ <View
81
74
  style={[
82
75
  styles.layer,
83
76
  {
84
77
  borderColor: isSelected ? tokens.colors.primary : "transparent",
85
78
  borderWidth: isSelected ? 2 : 0,
86
79
  },
87
- animatedStyle,
80
+ layerStyle,
88
81
  ]}
89
82
  >
90
83
  <LayerContent layer={layer} />
@@ -97,7 +90,7 @@ export const DraggableLayer: React.FC<DraggableLayerProps> = ({
97
90
  bottomRightGesture={bottomRightResizeHandler}
98
91
  />
99
92
  )}
100
- </Animated.View>
93
+ </View>
101
94
  </GestureDetector>
102
95
  );
103
96
  };
@@ -4,9 +4,8 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { StyleSheet } from "react-native";
7
+ import { View, StyleSheet } from "react-native";
8
8
  import { Gesture, GestureDetector } from "react-native-gesture-handler";
9
- import Animated from "react-native-reanimated";
10
9
  import { useAppDesignTokens } from "@umituz/react-native-design-system";
11
10
 
12
11
  interface ResizeHandlesProps {
@@ -27,7 +26,7 @@ export const ResizeHandles: React.FC<ResizeHandlesProps> = ({
27
26
  return (
28
27
  <>
29
28
  <GestureDetector gesture={topLeftGesture}>
30
- <Animated.View
29
+ <View
31
30
  style={[
32
31
  styles.handle,
33
32
  styles.handleTopLeft,
@@ -40,7 +39,7 @@ export const ResizeHandles: React.FC<ResizeHandlesProps> = ({
40
39
  </GestureDetector>
41
40
 
42
41
  <GestureDetector gesture={topRightGesture}>
43
- <Animated.View
42
+ <View
44
43
  style={[
45
44
  styles.handle,
46
45
  styles.handleTopRight,
@@ -53,7 +52,7 @@ export const ResizeHandles: React.FC<ResizeHandlesProps> = ({
53
52
  </GestureDetector>
54
53
 
55
54
  <GestureDetector gesture={bottomLeftGesture}>
56
- <Animated.View
55
+ <View
57
56
  style={[
58
57
  styles.handle,
59
58
  styles.handleBottomLeft,
@@ -66,7 +65,7 @@ export const ResizeHandles: React.FC<ResizeHandlesProps> = ({
66
65
  </GestureDetector>
67
66
 
68
67
  <GestureDetector gesture={bottomRightGesture}>
69
- <Animated.View
68
+ <View
70
69
  style={[
71
70
  styles.handle,
72
71
  styles.handleBottomRight,
@@ -3,9 +3,8 @@
3
3
  * Manages gesture handling for draggable layers
4
4
  */
5
5
 
6
- import { useSharedValue } from "react-native-reanimated";
6
+ import { useState, useRef, useCallback } from "react";
7
7
  import { Gesture } from "react-native-gesture-handler";
8
- import { withSpring, runOnJS } from "react-native-reanimated";
9
8
 
10
9
  interface UseDraggableLayerGesturesParams {
11
10
  initialX: number;
@@ -19,11 +18,15 @@ interface UseDraggableLayerGesturesParams {
19
18
  onSizeChange: (width: number, height: number) => void;
20
19
  }
21
20
 
21
+ interface LayerState {
22
+ x: number;
23
+ y: number;
24
+ width: number;
25
+ height: number;
26
+ }
27
+
22
28
  interface UseDraggableLayerGesturesReturn {
23
- translateX: ReturnType<typeof useSharedValue<number>>;
24
- translateY: ReturnType<typeof useSharedValue<number>>;
25
- width: ReturnType<typeof useSharedValue<number>>;
26
- height: ReturnType<typeof useSharedValue<number>>;
29
+ state: LayerState;
27
30
  composedGesture: ReturnType<typeof Gesture.Race>;
28
31
  topLeftResizeHandler: ReturnType<typeof Gesture.Pan>;
29
32
  topRightResizeHandler: ReturnType<typeof Gesture.Pan>;
@@ -33,9 +36,6 @@ interface UseDraggableLayerGesturesReturn {
33
36
 
34
37
  const MIN_SIZE = 50;
35
38
 
36
- /**
37
- * Hook for managing draggable layer gestures
38
- */
39
39
  export function useDraggableLayerGestures({
40
40
  initialX,
41
41
  initialY,
@@ -47,102 +47,84 @@ export function useDraggableLayerGestures({
47
47
  onPositionChange,
48
48
  onSizeChange,
49
49
  }: UseDraggableLayerGesturesParams): UseDraggableLayerGesturesReturn {
50
- const translateX = useSharedValue(initialX);
51
- const translateY = useSharedValue(initialY);
52
- const width = useSharedValue(initialWidth);
53
- const height = useSharedValue(initialHeight);
50
+ const [state, setState] = useState<LayerState>({
51
+ x: initialX,
52
+ y: initialY,
53
+ width: initialWidth,
54
+ height: initialHeight,
55
+ });
56
+
57
+ const startRef = useRef({ x: initialX, y: initialY, width: initialWidth, height: initialHeight });
54
58
 
55
- const startX = useSharedValue(initialX);
56
- const startY = useSharedValue(initialY);
57
- const startWidth = useSharedValue(initialWidth);
58
- const startHeight = useSharedValue(initialHeight);
59
+ const clamp = useCallback((value: number, min: number, max: number) => {
60
+ return Math.max(min, Math.min(max, value));
61
+ }, []);
59
62
 
60
63
  const gestureHandler = Gesture.Pan()
61
64
  .onStart(() => {
62
- startX.value = translateX.value;
63
- startY.value = translateY.value;
64
- runOnJS(onSelect)();
65
+ startRef.current = { ...state, x: state.x, y: state.y };
66
+ onSelect();
65
67
  })
66
68
  .onUpdate((event) => {
67
- translateX.value = startX.value + event.translationX;
68
- translateY.value = startY.value + event.translationY;
69
+ const newX = startRef.current.x + event.translationX;
70
+ const newY = startRef.current.y + event.translationY;
71
+ setState((prev) => ({ ...prev, x: newX, y: newY }));
69
72
  })
70
73
  .onEnd(() => {
71
- translateX.value = withSpring(
72
- Math.max(0, Math.min(canvasWidth - width.value, translateX.value)),
73
- );
74
- translateY.value = withSpring(
75
- Math.max(0, Math.min(canvasHeight - height.value, translateY.value)),
76
- );
77
-
78
- const newX = (translateX.value / canvasWidth) * 100;
79
- const newY = (translateY.value / canvasHeight) * 100;
80
- runOnJS(onPositionChange)(newX, newY);
74
+ setState((prev) => {
75
+ const clampedX = clamp(prev.x, 0, canvasWidth - prev.width);
76
+ const clampedY = clamp(prev.y, 0, canvasHeight - prev.height);
77
+ const newX = (clampedX / canvasWidth) * 100;
78
+ const newY = (clampedY / canvasHeight) * 100;
79
+ onPositionChange(newX, newY);
80
+ return { ...prev, x: clampedX, y: clampedY };
81
+ });
81
82
  });
82
83
 
83
84
  const createResizeHandler = (
84
- deltaX: (translationX: number) => number,
85
- deltaY: (translationY: number) => number,
85
+ deltaX: (tx: number) => number,
86
+ deltaY: (ty: number) => number,
86
87
  ) => {
87
88
  return Gesture.Pan()
88
89
  .onStart(() => {
89
- startWidth.value = width.value;
90
- startHeight.value = height.value;
91
- startX.value = translateX.value;
92
- startY.value = translateY.value;
93
- runOnJS(onSelect)();
90
+ startRef.current = { ...state };
91
+ onSelect();
94
92
  })
95
93
  .onUpdate((event) => {
96
- const newWidth = Math.max(
97
- MIN_SIZE,
98
- startWidth.value + deltaX(event.translationX),
99
- );
100
- const newHeight = Math.max(
101
- MIN_SIZE,
102
- startHeight.value + deltaY(event.translationY),
103
- );
104
- width.value = Math.min(newWidth, canvasWidth - startX.value);
105
- height.value = Math.min(newHeight, canvasHeight - startY.value);
94
+ const newWidth = Math.max(MIN_SIZE, startRef.current.width + deltaX(event.translationX));
95
+ const newHeight = Math.max(MIN_SIZE, startRef.current.height + deltaY(event.translationY));
96
+ const clampedWidth = Math.min(newWidth, canvasWidth - startRef.current.x);
97
+ const clampedHeight = Math.min(newHeight, canvasHeight - startRef.current.y);
98
+
99
+ let newX = startRef.current.x;
100
+ let newY = startRef.current.y;
106
101
 
107
102
  if (deltaX(event.translationX) < 0) {
108
- translateX.value = Math.max(
109
- 0,
110
- startX.value + (startWidth.value - width.value),
111
- );
103
+ newX = Math.max(0, startRef.current.x + (startRef.current.width - clampedWidth));
112
104
  }
113
105
  if (deltaY(event.translationY) < 0) {
114
- translateY.value = Math.max(
115
- 0,
116
- startY.value + (startHeight.value - height.value),
117
- );
106
+ newY = Math.max(0, startRef.current.y + (startRef.current.height - clampedHeight));
118
107
  }
108
+
109
+ setState({ x: newX, y: newY, width: clampedWidth, height: clampedHeight });
119
110
  })
120
111
  .onEnd(() => {
121
- const newWidth = (width.value / canvasWidth) * 100;
122
- const newHeight = (height.value / canvasHeight) * 100;
123
- const newX = (translateX.value / canvasWidth) * 100;
124
- const newY = (translateY.value / canvasHeight) * 100;
125
- runOnJS(onSizeChange)(newWidth, newHeight);
126
- runOnJS(onPositionChange)(newX, newY);
112
+ setState((prev) => {
113
+ const newWidth = (prev.width / canvasWidth) * 100;
114
+ const newHeight = (prev.height / canvasHeight) * 100;
115
+ const newX = (prev.x / canvasWidth) * 100;
116
+ const newY = (prev.y / canvasHeight) * 100;
117
+ onSizeChange(newWidth, newHeight);
118
+ onPositionChange(newX, newY);
119
+ return prev;
120
+ });
127
121
  });
128
122
  };
129
123
 
130
- const topLeftResizeHandler = createResizeHandler(
131
- (tx) => -tx,
132
- (ty) => -ty,
133
- );
134
- const topRightResizeHandler = createResizeHandler(
135
- (tx) => tx,
136
- (ty) => -ty,
137
- );
138
- const bottomLeftResizeHandler = createResizeHandler(
139
- (tx) => -tx,
140
- (ty) => ty,
141
- );
142
- const bottomRightResizeHandler = createResizeHandler(
143
- (tx) => tx,
144
- (ty) => ty,
145
- );
124
+ const topLeftResizeHandler = createResizeHandler((tx) => -tx, (ty) => -ty);
125
+ const topRightResizeHandler = createResizeHandler((tx) => tx, (ty) => -ty);
126
+ const bottomLeftResizeHandler = createResizeHandler((tx) => -tx, (ty) => ty);
127
+ const bottomRightResizeHandler = createResizeHandler((tx) => tx, (ty) => ty);
146
128
 
147
129
  const composedGesture = Gesture.Race(
148
130
  gestureHandler,
@@ -153,10 +135,7 @@ export function useDraggableLayerGestures({
153
135
  );
154
136
 
155
137
  return {
156
- translateX,
157
- translateY,
158
- width,
159
- height,
138
+ state,
160
139
  composedGesture,
161
140
  topLeftResizeHandler,
162
141
  topRightResizeHandler,