Skip to content
This repository was archived by the owner on Jul 13, 2022. It is now read-only.

Commit ebf146b

Browse files
committed
resizeMode
1 parent 745abf0 commit ebf146b

File tree

9 files changed

+145
-35
lines changed

9 files changed

+145
-35
lines changed

android/src/main/java/io/autodidact/reanimatedcanvas/RCanvas.java

+24-3
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
import java.util.Locale;
1717
import java.util.Stack;
1818

19+
import io.autodidact.reanimatedcanvas.RPath.ResizeMode;
20+
1921
import static io.autodidact.reanimatedcanvas.RCanvasManager.TAG;
2022

2123
public class RCanvas extends ReactViewGroup {
2224

2325
protected ArrayList<RPath> mPaths = new ArrayList<>();
2426
protected ArrayList<String> mInteractionContainer = new ArrayList<>();
2527
protected RectF mHitSlop = new RectF();
28+
private @ResizeMode String mResizeMode = ResizeMode.NONE;
2629
private RPath mNextPath;
2730
protected Stack<RCanvasState> mStateStack;
2831
private final IntersectionHelper mIntersectionHelper;
@@ -83,6 +86,13 @@ public void setHitSlop(RectF hitSlop){
8386
}
8487
}
8588

89+
public void setResizeMode(@ResizeMode String resizeMode) {
90+
mResizeMode = resizeMode;
91+
for (RPath path: paths()) {
92+
path.setResizeMode(resizeMode);
93+
}
94+
}
95+
8696
public ArrayList<RPath> paths() {
8797
return new ArrayList<>(mPaths);
8898
}
@@ -115,26 +125,29 @@ private void allocNext() {
115125
}
116126

117127
public String init() {
118-
RCanvasState currentState = mStateStack.peek();
119128
String pathId = Utility.generateId();
120-
init(pathId, currentState.strokeColor, currentState.strokeWidth);
129+
init(pathId, null, null, null);
121130
return pathId;
122131
}
123132

124-
public void init(String pathId, @Nullable Integer strokeColor, @Nullable Float strokeWidth) {
133+
public void init(String pathId, @Nullable Integer strokeColor, @Nullable Float strokeWidth,
134+
@Nullable @ResizeMode String resizeMode) {
125135
RCanvasState currentState = mStateStack.peek();
126136
strokeColor = strokeColor == null ? currentState.strokeColor : strokeColor;
127137
strokeWidth = strokeWidth == null ? currentState.strokeWidth : strokeWidth;
138+
resizeMode = resizeMode == null ? mResizeMode : resizeMode;
128139
RPath path = init(pathId);
129140
path.setStrokeColor(strokeColor);
130141
path.setStrokeWidth(strokeWidth);
142+
path.setResizeMode(resizeMode);
131143
}
132144

133145
protected RPath init(String pathId) {
134146
if (getPathIndex(pathId) == -1) {
135147
RPath path = mNextPath;
136148
path.setPathId(pathId);
137149
path.setHitSlop(mHitSlop);
150+
path.setResizeMode(mResizeMode);
138151
mPaths.add(path);
139152
allocNext();
140153
return path;
@@ -181,4 +194,12 @@ protected ArrayList<RPath> filterPaths(final ArrayList<RPath> paths, final boole
181194
public void tearDown(){
182195

183196
}
197+
198+
@Override
199+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
200+
super.onSizeChanged(w, h, oldw, oldh);
201+
for (RPath path: paths()) {
202+
path.onSizeChanged(w, h, oldw, oldh);
203+
}
204+
}
184205
}

android/src/main/java/io/autodidact/reanimatedcanvas/RCanvasHandler.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import java.util.Iterator;
1717
import java.util.Map;
1818

19+
import io.autodidact.reanimatedcanvas.RPath.ResizeMode;
20+
1921
public class RCanvasHandler extends RCanvas {
2022

2123
private final ArrayList<Integer> reactTagRegistry = new ArrayList<>();
@@ -36,8 +38,9 @@ public ArrayList<RPath> restore(int saveCount) {
3638
}
3739

3840
@Override
39-
public void init(String pathId, @Nullable Integer strokeColor, @Nullable Float strokeWidth) {
40-
super.init(pathId, strokeColor, strokeWidth);
41+
public void init(String pathId, @Nullable Integer strokeColor, @Nullable Float strokeWidth,
42+
@Nullable @ResizeMode String resizeMode) {
43+
super.init(pathId, strokeColor, strokeWidth, resizeMode);
4144
ArrayList<RPath> added = new ArrayList<>();
4245
added.add(getPath(pathId));
4346
mEventDispatcher.emitChange(added, null, null);
@@ -102,6 +105,9 @@ public void setAttributes(String id, ReadableMap attributes, boolean standalone)
102105
if (attributes.hasKey("strokeWidth")) {
103106
path.setStrokeWidth(PixelUtil.toPixelFromDIP(attributes.getInt("strokeWidth")));
104107
}
108+
if (attributes.hasKey("resizeMode")) {
109+
path.setResizeMode(attributes.getString("resizeMode"));
110+
}
105111
if (attributes.hasKey("points")) {
106112
path.setPoints(Utility.processPointArray(attributes.getArray("points")));
107113
}

android/src/main/java/io/autodidact/reanimatedcanvas/RCanvasManager.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.lang.annotation.RetentionPolicy;
2323
import java.util.Map;
2424

25+
import io.autodidact.reanimatedcanvas.RPath.ResizeMode;
26+
2527
public class RCanvasManager extends ReactViewManager {
2628
static final String NAME = "ReanimatedCanvasManager";
2729
static final String TAG = "RCanvas";
@@ -97,6 +99,10 @@ public void setHitSlop(ReactViewGroup view, @Nullable ReadableMap hitSlop) {
9799
((RCanvasHandler) view).setHitSlop(Utility.parseHitSlop(hitSlop));
98100
}
99101

102+
@ReactProp(name = RPathManager.Props.RESIZE_MODE)
103+
public void setResizeMode(RCanvasHandler view, @Nullable @ResizeMode String resizeMode) {
104+
view.setResizeMode(resizeMode != null ? resizeMode : RPath.ResizeMode.NONE);
105+
}
100106

101107
@Retention(RetentionPolicy.SOURCE)
102108
@IntDef({
@@ -165,7 +171,8 @@ public void receiveCommand(@NonNull ReactViewGroup root, @Commands int command,
165171
String id = args.getString(0);
166172
Integer strokeColor = !args.isNull(1) ? args.getInt(1) : null;
167173
Float strokeWidth = !args.isNull(2) ? PixelUtil.toPixelFromDIP(args.getDouble(2)) : null;
168-
view.init(id, strokeColor, strokeWidth);
174+
@ResizeMode String resizeMode = args.size() == 4 && !args.isNull(3) ? args.getString(3) : null;
175+
view.init(id, strokeColor, strokeWidth, resizeMode);
169176
return;
170177
}
171178
case Commands.DRAW_POINT: {

android/src/main/java/io/autodidact/reanimatedcanvas/RPath.java

+50-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
import android.view.View;
1313

1414
import androidx.annotation.Nullable;
15+
import androidx.annotation.StringDef;
1516

1617
import com.facebook.react.bridge.Arguments;
1718
import com.facebook.react.bridge.ReactContext;
1819
import com.facebook.react.bridge.WritableArray;
1920
import com.facebook.react.bridge.WritableMap;
2021
import com.facebook.react.uimanager.PixelUtil;
2122

23+
import java.lang.annotation.Retention;
24+
import java.lang.annotation.RetentionPolicy;
2225
import java.util.ArrayList;
2326
import java.util.HashMap;
2427
import java.util.Locale;
@@ -29,13 +32,13 @@ public class RPath extends View {
2932
protected String mPathId;
3033
private RectF mHitSlop;
3134
private boolean mOverriddenHitSlop = false;
35+
private @RPath.ResizeMode String mResizeMode = RPath.ResizeMode.NONE;
3236

3337
private Paint mPaint;
3438
protected Path mPath;
3539

3640
protected ArrayList<PointF> mTempPoints;
3741

38-
3942
public RPath(ReactContext context) {
4043
super(context);
4144
mPath = new Path();
@@ -129,12 +132,14 @@ void setHitSlop(RectF hitSlop, boolean override) {
129132
}
130133
}
131134

135+
public void setResizeMode(@ResizeMode String resizeMode) {
136+
mResizeMode = resizeMode;
137+
}
138+
132139
private static boolean isTranslucent(int strokeColor) {
133140
return ((strokeColor >> 24) & 0xff) != 255 && strokeColor != Color.TRANSPARENT;
134141
}
135142

136-
137-
138143
public void addPoint(PointF p) {
139144
RPathState currentState = mPathStateStack.peek();
140145
ArrayList<PointF> points = currentState.points;
@@ -209,6 +214,47 @@ public WritableMap toWritableMap(Boolean includePoints){
209214
return path;
210215
}
211216

217+
@Retention(RetentionPolicy.SOURCE)
218+
@StringDef({
219+
ResizeMode.COVER,
220+
ResizeMode.STRETCH,
221+
ResizeMode.NONE
222+
})
223+
@interface ResizeMode {
224+
String COVER = "cover";
225+
String STRETCH = "stretch";
226+
String NONE = "none";
227+
}
228+
229+
@Override
230+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
231+
super.onSizeChanged(w, h, oldw, oldh);
232+
PointF scaler;
233+
float sx = w * 1.f / oldw * 1.f;
234+
float sy = h * 1.f / oldh * 1.f;
235+
float scale = sx;
236+
PointF next;
237+
switch (mResizeMode) {
238+
case ResizeMode.COVER:
239+
next = new PointF(Math.max(oldw * scale, w), Math.max(oldh * scale, h));
240+
scale = Math.min(next.x / oldw, next.y / oldh);
241+
scaler = new PointF(scale, scale);
242+
break;
243+
case ResizeMode.STRETCH:
244+
scaler = new PointF(sx, sy);
245+
break;
246+
default:
247+
case ResizeMode.NONE:
248+
return;
249+
}
250+
ArrayList<PointF> points = new ArrayList<>(mPathStateStack.peek().points);
251+
for (PointF point: points) {
252+
point.x *= scaler.x;
253+
point.y *= scaler.y;
254+
}
255+
setPoints(points);
256+
}
257+
212258
@Override
213259
public String toString() {
214260
HashMap<String, Object> props = new HashMap<>();
@@ -220,4 +266,5 @@ public String toString() {
220266
props.put("points", currentState.points);
221267
return String.format(Locale.ENGLISH, "RPath(%s)", props);
222268
}
269+
223270
}

android/src/main/java/io/autodidact/reanimatedcanvas/RPathManager.java

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import com.facebook.react.uimanager.ThemedReactContext;
1313
import com.facebook.react.uimanager.annotations.ReactProp;
1414

15+
import io.autodidact.reanimatedcanvas.RPath.ResizeMode;
16+
1517
public class RPathManager extends SimpleViewManager<RPathHandler> {
1618
final static String NAME = "ReanimatedPathManager";
1719

@@ -20,6 +22,7 @@ public class RPathManager extends SimpleViewManager<RPathHandler> {
2022
String POINTS = "points";
2123
String ANIMATE = "animate";
2224
String ANIMATION_CONTROLLER = "index";
25+
String RESIZE_MODE = "resizeMode";
2326
}
2427

2528
public RPathManager() {
@@ -78,6 +81,11 @@ public void setHitSlop(RPathHandler view, @Nullable ReadableMap hitSlop) {
7881
view.setHitSlop(Utility.parseHitSlop(hitSlop), true);
7982
}
8083

84+
@ReactProp(name = Props.RESIZE_MODE)
85+
public void setResizeMode(RPathHandler view, @Nullable @ResizeMode String resizeMode) {
86+
view.setResizeMode(resizeMode != null ? resizeMode : RPath.ResizeMode.NONE);
87+
}
88+
8189
@Override
8290
protected void onAfterUpdateTransaction(@NonNull RPathHandler view) {
8391
super.onAfterUpdateTransaction(view);

src/RCanvasBase.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ function RCanvasBase(props: RCanvasProperties, forwardedRef: Ref<RCanvasRef>) {
9090
node
9191
]
9292
);
93-
9493
return (
9594
<RNativeCanvas
9695
{...props}
@@ -99,6 +98,7 @@ function RCanvasBase(props: RCanvasProperties, forwardedRef: Ref<RCanvasRef>) {
9998
strokeWidth={strokeWidth.value()}
10099
strokeColor={strokeColor.value()}
101100
hitSlop={hitSlop}
101+
resizeMode={props.resizeMode}
102102
>
103103
<View
104104
style={StyleSheet.absoluteFill}
@@ -114,6 +114,7 @@ ForwardedRCanvasBase.defaultProps = {
114114
strokeColor: 'black',
115115
strokeWidth: 5,
116116
hitSlop: 20,
117+
resizeMode: 'cover',
117118
renderToHardwareTextureAndroid: false
118119
} as RCanvasProperties;
119120
ForwardedRCanvasBase.displayName = 'Forwarded(RCanvasBase)'

src/RCanvasBaseModule.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import _ from 'lodash';
22
import { MutableRefObject, useMemo } from 'react';
33
import { findNodeHandle, NativeModules, Platform, processColor, UIManager } from 'react-native';
4-
import { Commands, Point, RCanvasRef, RPathData } from './types';
5-
import { processColorProp } from './util';
4+
import { Commands, Point, RCanvasRef, RPathData, RPathAttributes } from './types';
5+
import { processColorProp, parseHitSlop } from './util';
66

77
export const VIEW_MANAGER = 'ReanimatedCanvasManager';
88
export const PATH_VIEW_MANAGER = 'ReanimatedPathManager';
@@ -37,10 +37,14 @@ export function update(tag: number, paths: { [id: string]: RPathData | null }) {
3737
dispatchCommand(tag, Commands.update, [paths]);
3838
}
3939

40-
export function setPathAttributes(tag: number, pathId: string, attr: { width: number, color: string | number }) {
41-
if (typeof attr.color === 'string') {
42-
attr.color = processColor(attr.color);
40+
export function setPathAttributes(tag: number, pathId: string, attr: RPathAttributes) {
41+
if (typeof attr.strokeColor === 'string') {
42+
attr.strokeColor = processColor(attr.strokeColor);
4343
}
44+
if (attr.hitSlop !== null) {
45+
attr.hitSlop = parseHitSlop(attr.hitSlop);
46+
}
47+
4448
dispatchCommand(tag, Commands.setAttributes, [pathId, attr]);
4549
}
4650

src/types.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,27 @@ export type Point = {
2424
y: number
2525
}
2626

27+
export enum ResizeMode {
28+
cover = 'cover',
29+
stretch = 'stretch',
30+
none = 'none',
31+
}
32+
2733
export interface RPathDataBase {
28-
strokeColor: string | number
29-
strokeWidth: number
34+
strokeColor: string | number,
35+
strokeWidth: number,
3036
points?: Point[]
3137
}
3238

3339
export interface RPathData extends RPathDataBase {
3440
id: string
3541
}
3642

43+
export interface RPathAttributes extends RPathDataBase {
44+
resizeMode?: ResizeMode,
45+
hitSlop?: ExtendedInsets | number
46+
}
47+
3748
export type IntersectionResponse = string[];
3849

3950
export interface NativeStrokeEvent extends Point {
@@ -78,7 +89,8 @@ interface ExtendedInsets extends Insets {
7889

7990
interface RCanvasCommonProps {
8091
strokeColor?: string | Animated.Adaptable<number>
81-
strokeWidth?: Animated.Adaptable<number>
92+
strokeWidth?: Animated.Adaptable<number>,
93+
resizeMode?: ResizeMode,
8294

8395
/**
8496
* pass a rect or a number to apply all insets equally

0 commit comments

Comments
 (0)