aboutsummaryrefslogtreecommitdiff
path: root/src/components/comments/ZoomInCropper.tsx
diff options
context:
space:
mode:
authorBrian Kim <brian@tagg.id>2021-07-13 16:01:11 -0400
committerBrian Kim <brian@tagg.id>2021-07-13 16:01:11 -0400
commitb7cba594635f4a6de3582ba4845bfc9757632ba1 (patch)
tree6336696356d8773bd505fe9c085cbb778f7e7b59 /src/components/comments/ZoomInCropper.tsx
parentf12996bfd3bcdd9ae0589e4fd4ca740705ad6d29 (diff)
Extremely rough working
Diffstat (limited to 'src/components/comments/ZoomInCropper.tsx')
-rw-r--r--src/components/comments/ZoomInCropper.tsx344
1 files changed, 308 insertions, 36 deletions
diff --git a/src/components/comments/ZoomInCropper.tsx b/src/components/comments/ZoomInCropper.tsx
index 7fa88f6e..3a492af3 100644
--- a/src/components/comments/ZoomInCropper.tsx
+++ b/src/components/comments/ZoomInCropper.tsx
@@ -1,15 +1,23 @@
import {RouteProp} from '@react-navigation/core';
import {useFocusEffect} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
-import React, {useCallback, useEffect, useState} from 'react';
-import {Image, StyleSheet, TouchableOpacity} from 'react-native';
+import React, {useCallback, useEffect, useRef, useState} from 'react';
+import {Image, StyleSheet, TouchableOpacity, View} from 'react-native';
import {normalize} from 'react-native-elements';
import ImageZoom, {IOnMove} from 'react-native-image-pan-zoom';
import PhotoManipulator from 'react-native-photo-manipulator';
import CloseIcon from '../../assets/ionicons/close-outline.svg';
import {MainStackParams} from '../../routes';
-import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {
+ cropVideo,
+ HeaderHeight,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
+ numberWithCommas,
+} from '../../utils';
import {TaggSquareButton} from '../common';
+import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';
+import Video from 'react-native-video';
type ZoomInCropperRouteProps = RouteProp<MainStackParams, 'ZoomInCropper'>;
type ZoomInCropperNavigationProps = StackNavigationProp<
@@ -27,6 +35,9 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
}) => {
const {screenType, title, media} = route.params;
const [aspectRatio, setAspectRatio] = useState<number>(1);
+ // width and height of video, if video
+ const [origDimensions, setOrigDimensions] = useState<number[]>([0, 0]);
+ const vidRef = useRef(null);
// Stores the coordinates of the cropped image
const [x0, setX0] = useState<number>();
@@ -34,6 +45,25 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
const [y0, setY0] = useState<number>();
const [y1, setY1] = useState<number>();
+ // Stores crop information for video
+ const [videoCrop, setVideoCrop] = useState<{
+ cropWidth?: number;
+ cropHeight?: number;
+ cropOffsetX?: number;
+ cropOffsetY?: number;
+ }>({});
+
+ const checkIfUriImage = (uri: string) => {
+ return (
+ uri.endsWith('jpg') ||
+ uri.endsWith('JPG') ||
+ uri.endsWith('PNG') ||
+ uri.endsWith('png') ||
+ uri.endsWith('GIF') ||
+ uri.endsWith('gif')
+ );
+ };
+
useFocusEffect(
useCallback(() => {
navigation.dangerouslyGetParent()?.setOptions({
@@ -49,7 +79,7 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
// Setting original aspect ratio of image
useEffect(() => {
- if (media.uri) {
+ if (media.uri && checkIfUriImage(media.uri)) {
Image.getSize(
media.uri,
(w, h) => {
@@ -57,45 +87,199 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
},
(err) => console.log(err),
);
+ } else if (media.uri && !checkIfUriImage(media.uri)) {
+ const tempVideoCrop = {...videoCrop};
+ tempVideoCrop.cropWidth = origDimensions[0];
+ tempVideoCrop.cropHeight = origDimensions[1];
+ setVideoCrop(tempVideoCrop);
}
}, []);
+ // Possible need to delay setting aspect ratio of video until loaded
+ useEffect(() => {
+ if (media.uri && !checkIfUriImage(media.uri)) {
+ const tempVideoCrop = {...videoCrop};
+ tempVideoCrop.cropWidth = origDimensions[0];
+ tempVideoCrop.cropHeight = origDimensions[1];
+ setVideoCrop(tempVideoCrop);
+ }
+ }, [origDimensions]);
+
// Crops original image based of (x0, y0) and (x1, y1) coordinates
const handleNext = () => {
- if (
- x0 !== undefined &&
- x1 !== undefined &&
- y0 !== undefined &&
- y1 !== undefined
- ) {
- PhotoManipulator.crop(media.uri, {
- x: x0,
- y: y1,
- width: Math.abs(x0 - x1),
- height: Math.abs(y0 - y1),
- })
- .then((croppedURL) => {
+ if (checkIfUriImage(media.uri)) {
+ if (
+ x0 !== undefined &&
+ x1 !== undefined &&
+ y0 !== undefined &&
+ y1 !== undefined
+ ) {
+ PhotoManipulator.crop(media.uri, {
+ x: x0,
+ y: y1,
+ width: Math.abs(x0 - x1),
+ height: Math.abs(y0 - y1),
+ })
+ .then((croppedURL) => {
+ navigation.navigate('CaptionScreen', {
+ screenType,
+ title: title,
+ media: {
+ uri: croppedURL,
+ isVideo: false,
+ },
+ });
+ })
+ .catch((err) => console.log('err: ', err));
+ } else if (
+ x0 === undefined &&
+ x1 === undefined &&
+ y0 === undefined &&
+ y1 === undefined
+ ) {
+ navigation.navigate('CaptionScreen', {
+ screenType,
+ title: title,
+ media,
+ });
+ }
+ } else {
+ if (!videoCrop.cropHeight || !videoCrop.cropWidth) {
+ const tempVideoCrop = {...videoCrop};
+ tempVideoCrop.cropWidth = origDimensions[0];
+ tempVideoCrop.cropHeight = origDimensions[1];
+ setVideoCrop(tempVideoCrop);
+ }
+ cropVideo(
+ media.uri,
+ (croppedURL: string) => {
navigation.navigate('CaptionScreen', {
screenType,
title: title,
media: {
uri: croppedURL,
- isVideo: false,
+ isVideo: true,
},
});
- })
- .catch((err) => console.log('err: ', err));
- } else if (
- x0 === undefined &&
- x1 === undefined &&
- y0 === undefined &&
- y1 === undefined
- ) {
- navigation.navigate('CaptionScreen', {
- screenType,
- title: title,
- media,
- });
+ },
+ videoCrop,
+ );
+ }
+ };
+
+ // for whenever the video is altered by the user
+ const onVideoMove = (zoomableEvent: any) => {
+ const {
+ distanceBottom,
+ distanceLeft,
+ distanceRight,
+ distanceTop,
+ lastMovePinch,
+ lastX,
+ lastY,
+ lastZoomLevel,
+ offsetX,
+ offsetY,
+ originalHeight,
+ originalWidth,
+ zoomLevel,
+ } = zoomableEvent;
+ // let cropWidth = origDimensions[0] / (zoomLevel * aspectRatio);
+ // let cropOffsetX = Math.abs((origDimensions[0] - cropWidth) / 2);
+ // let screenScale = SCREEN_HEIGHT / origDimensions[1];
+ // const relativeHeight = SCREEN_WIDTH / aspectRatio;
+ // let cropHeight = origDimensions[1];
+ // let cropOffsetY = 0;
+
+ let cropWidth = 0;
+ let cropHeight = 0;
+ let cropOffsetX = 0;
+ let cropOffsetY = 0;
+
+ // if (aspectRatio > 1) {
+ // cropWidth =
+ // originalWidth * (originalWidth - (distanceLeft + distanceRight));
+ // cropHeight = origDimensions[1];
+ // }
+
+ // console.log(relativeHeight * zoomLevel, SCREEN_HEIGHT, zoomLevel);
+ // if (cropHeight * screenScale > SCREEN_HEIGHT) {
+ // console.log('true');
+ // } else {
+ // console.log('false');
+ // }
+
+ // console.log(
+ // aspectRatio,
+ // zoomLevel,
+ // originalWidth,
+ // originalHeight,
+ // origDimensions[0],
+ // origDimensions[1],
+ // cropWidth,
+ // cropHeight,
+ // distanceBottom,
+ // distanceLeft,
+ // distanceRight,
+ // distanceTop,
+ // SCREEN_WIDTH * zoomLevel - SCREEN_WIDTH,
+ // distanceBottom + distanceTop,
+ // distanceLeft + distanceRight,
+ // );
+ // console.log(
+ // zoomLevel,
+ // distanceBottom,
+ // distanceLeft,
+ // distanceRight,
+ // distanceTop,
+ // originalWidth / (originalWidth - (distanceLeft + distanceRight)),
+ // );
+ if (vidRef !== null && vidRef.current !== null) {
+ vidRef.current.measure(
+ (
+ x: number,
+ y: number,
+ width: number,
+ height: number,
+ pageX: number,
+ pageY: number,
+ ) => {
+ // width
+ cropWidth = origDimensions[0] * (originalWidth / width);
+
+ // offsetX
+ // cropOffsetX = (origDimensions[0] - cropWidth) / 2;
+ cropOffsetX = -1 * origDimensions[0] * (pageX / width);
+ if (cropOffsetX < 0) {
+ cropOffsetX = 0;
+ } else if (cropOffsetX + cropWidth > origDimensions[0]) {
+ cropOffsetX = origDimensions[0] - cropWidth - 1;
+ }
+
+ // height
+ if (
+ height * (SCREEN_WIDTH / aspectRatio / originalHeight) >
+ SCREEN_HEIGHT
+ ) {
+ const superHeight = width / aspectRatio;
+ cropHeight = origDimensions[1] * (originalHeight / superHeight);
+ // cropOffsetY = (origDimensions[1] - cropHeight) / 2;
+ if (cropOffsetY < 0) {
+ cropOffsetY = 0;
+ } else if (cropOffsetY + cropHeight > origDimensions[1]) {
+ cropOffsetY = origDimensions[1] - cropHeight - 1;
+ }
+ } else {
+ cropHeight = origDimensions[1];
+ }
+ const tempVideoCrop = {...videoCrop};
+ tempVideoCrop.cropWidth = cropWidth;
+ tempVideoCrop.cropHeight = cropHeight;
+ tempVideoCrop.cropOffsetX = cropOffsetX;
+ tempVideoCrop.cropOffsetY = cropOffsetY;
+ setVideoCrop(tempVideoCrop);
+ },
+ );
}
};
@@ -138,13 +322,13 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
};
return (
- <>
+ <View style={styles.container}>
<TouchableOpacity
style={styles.closeButton}
onPress={() => navigation.goBack()}>
<CloseIcon height={25} width={25} color={'white'} />
</TouchableOpacity>
- <ImageZoom
+ {/* <ImageZoom
style={styles.zoomView}
cropWidth={SCREEN_WIDTH}
cropHeight={SCREEN_HEIGHT}
@@ -157,7 +341,76 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
uri: media.uri,
}}
/>
- </ImageZoom>
+ </ImageZoom> */}
+
+ {/* <Image style={{ flex: 1, width: null, height: '100%' }}
+ source={require('./image.jpg')}
+ resizeMode="contain" /> */}
+ {checkIfUriImage(media.uri) ? (
+ <ImageZoom
+ style={styles.zoomView}
+ cropWidth={SCREEN_WIDTH}
+ cropHeight={SCREEN_HEIGHT}
+ imageWidth={SCREEN_WIDTH}
+ imageHeight={SCREEN_WIDTH / aspectRatio}
+ onMove={onMove}>
+ <Image
+ style={{width: SCREEN_WIDTH, height: SCREEN_WIDTH / aspectRatio}}
+ source={{
+ uri: media.uri,
+ }}
+ />
+ </ImageZoom>
+ ) : (
+ <ReactNativeZoomableView
+ maxZoom={10}
+ minZoom={1}
+ zoomStep={0.5}
+ initialZoom={1}
+ bindToBorders={true}
+ // onZoomAfter={this.logOutZoomState}
+ onDoubleTapAfter={(
+ _1: any,
+ _2: any,
+ zoomableViewEventObject: any,
+ ) => {
+ onVideoMove(zoomableViewEventObject);
+ }}
+ onShiftingAfter={(_1: any, _2: any, zoomableViewEventObject: any) => {
+ onVideoMove(zoomableViewEventObject);
+ }}
+ onShiftingEnd={(_1: any, _2: any, zoomableViewEventObject: any) => {
+ onVideoMove(zoomableViewEventObject);
+ }}
+ onZoomAfter={(_1: any, _2: any, zoomableViewEventObject: any) => {
+ onVideoMove(zoomableViewEventObject);
+ }}
+ onZoomEnd={(_1: any, _2: any, zoomableViewEventObject: any) => {
+ onVideoMove(zoomableViewEventObject);
+ }}
+ style={styles.zoomView}>
+ <View style={styles.videoParent} ref={vidRef}>
+ <Video
+ source={{uri: media.uri}}
+ volume={1}
+ style={[
+ styles.media,
+ {
+ height: SCREEN_WIDTH / aspectRatio,
+ },
+ ]}
+ repeat={false}
+ resizeMode={'contain'}
+ onLoad={(response) => {
+ const {width, height} = response.naturalSize;
+ setOrigDimensions([width, height]);
+ setAspectRatio(width / height);
+ }}
+ />
+ </View>
+ </ReactNativeZoomableView>
+ )}
+
<TaggSquareButton
onPress={handleNext}
title={'Next'}
@@ -167,11 +420,18 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
style={styles.button}
labelStyle={styles.buttonLabel}
/>
- </>
+ </View>
);
};
const styles = StyleSheet.create({
+ container: {
+ backgroundColor: 'black',
+ height: SCREEN_HEIGHT,
+ width: SCREEN_WIDTH,
+ // flexDirection: 'column',
+ // justifyContent: 'center',
+ },
closeButton: {
position: 'absolute',
top: 0,
@@ -195,5 +455,17 @@ const styles = StyleSheet.create({
letterSpacing: normalize(1.3),
textAlign: 'center',
},
- zoomView: {backgroundColor: 'black'},
+ media: {
+ zIndex: 0,
+ flex: 1,
+ },
+ videoParent: {
+ flex: 1,
+ },
+ zoomView: {
+ backgroundColor: 'black',
+ flex: 1,
+ // borderColor: 'pink',
+ // borderWidth: 2,
+ },
});