YanYuanFE / react-native-signature-canvas

:black_nib: React Native Signature Component based WebView Canvas for Android && IOS && expo
MIT License
418 stars 150 forks source link

Canvas content not getting resized on orientation change #157

Open bjarkof opened 3 years ago

bjarkof commented 3 years ago

Hi, I'm having a problem with the component, when the device orientation changes. I want to make the users able to rotate the device to obtain more space to write their signature. The problem is, when a signature is drawn in landscape mode, and then rotated back to portait, some of the signature to the right is cut off. Are there any way to fix this?

YanYuanFE commented 3 years ago

provide your code example?

udot-a commented 2 years ago

I have the same issue. Do you have any ideas on how to resolve it?

udot-a commented 2 years ago

import React, { useEffect, useMemo, useRef, useState } from 'react'; import s from '../styles/commonStyles'; import * as helpers from '../styles/helpers'; import colors from '../styles/colors'; import { View, StyleSheet } from 'react-native'; import Animated, { useAnimatedStyle, useSharedValue, withSpring, } from 'react-native-reanimated'; import { useSafeAreaFrame, useSafeAreaInsets, } from 'react-native-safe-area-context'; import { useTranslation } from 'react-i18next'; import Button from './Button'; import { DENY, PRIMARY } from '../constants/button-types'; import SignatureScreen from 'react-native-signature-canvas'; import Header from './Header'; import commonStyles from '../styles/commonStyles'; import { BUTTON_HEIGHT, HEADER_HEIGHT } from '../constants/style'; import Text from './Text'; import Orientation, { useDeviceOrientationChange, useOrientationChange, } from 'react-native-orientation-locker'; import { PORTRAIT, PORTRAIT_UPSIDEDOWN, UNKNOWN, } from '../constants/orientation'; import useEqualSelector from '../hooks/useEqualSelector'; import { deviceSelector } from '../store/selectors/settingSelectors';

function Signature(props) { const { show, setShow, onOK } = props;

const [isDraw, setDraw] = useState(false); const device = useEqualSelector(deviceSelector); const { top, bottom } = useSafeAreaInsets(); const { height, width } = useSafeAreaFrame(); const { t } = useTranslation(); const ref = useRef(); const [orientation, setOrientation] = useState(PORTRAIT); const [deviceOrientation, setDeviceOrientation] = useState(PORTRAIT); const isZebra = useMemo(() => device?.includes('Zebra'), [device]);

const blockHeight = useSharedValue(height / 2);

const animatedStyles = useAnimatedStyle(() => { return { bottom: blockHeight.value + bottom, top: blockHeight.value + top, }; });

useDeviceOrientationChange(setDeviceOrientation);

useOrientationChange(setOrientation);

useEffect(() => { if (show) { Orientation.unlockAllOrientations(); }

return () => Orientation.lockToPortrait();

}, [show]);

useEffect(() => { if (show && deviceOrientation === UNKNOWN) { Orientation.lockToPortrait(); } else if (show) { Orientation.unlockAllOrientations(); }

if (show && deviceOrientation === PORTRAIT_UPSIDEDOWN && !isZebra) {
  Orientation.lockToPortraitUpsideDown();
} else if (show){
  Orientation.unlockAllOrientations();
}

}, [show, deviceOrientation, isZebra]);

// useEffect(() => { // if (show && orientation === PORTRAIT_UPSIDEDOWN) { // Orientation.unlockAllOrientations(); // if (!isZebra) { // Orientation.lockToPortraitUpsideDown(); // } // } else { // Orientation.lockToPortrait(); // // } // return () => { // Orientation.lockToPortrait(); // }; // }, [show, orientation, isZebra]);

useEffect(() => { if (show) { blockHeight.value = withSpring(0); } else if (!show) { blockHeight.value = withSpring(height / 2); } }, [show, blockHeight]);

// Called after ref.current.readSignature() reads a non-empty base64 string const handleOK = signature => { onOK(signature); setDraw(false); setShow(false); // Callback from Component props };

// Called after ref.current.readSignature() reads an empty string const handleEmpty = () => { console.log('Empty'); };

// Called after ref.current.clearSignature() const handleClear = () => { ref?.current?.clearSignature(); setDraw(false); };

// Called after end of stroke const handleEnd = () => { ref?.current?.readSignature(); };

// Called after ref.current.getData() const handleData = data => { console.log(data); };

const handleConfirm = async () => { const res = await ref.current.readSignature(); };

const webStyle = `.m-signature-pad--footer .save { display: none; } .clear { display: none; } .description { display: none; }

.m-signature-pad--footer {
  display: none;
  }

body: {
  background: ${colors.background2};
}
.m-signature-pad {

font-size: 10px; // width: ${300}px; // height: ${300 - BUTTON_HEIGHT - HEADER_HEIGHT}px; // position: absolute; // top: 0; // left: 0; // zIndex: 100; // display: flex, // flexGrow: 1, margin-left: 0px; margin-top: 0px; border: none; background-color: #fff; border-radius: 6px; box-shadow: none; }

.m-signature-pad--body { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; border: 1px solid #f4f4f4; }

.m-signature-pad--body canvas { position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 6px; box-shadow: none; } `;

const isPortrait = useMemo( () => orientation === 'PORTRAIT-UPSIDEDOWN' || orientation === 'PORTRAIT' || orientation === UNKNOWN, [orientation], );

return ( <Animated.View style={[styles.container, { top }, animatedStyles]}> {show && (

{isPortrait && (
setShow(false)} title={t('delivery.clientSignature')} // white={false} /> )} {t('delivery.clientSignature')} setDraw(false)} onEnd={() => setDraw(true)} webStyle={webStyle} // trimWhitespace // webviewContainerStyle={{}} style={[ s.flexG, helpers.br(10), helpers.color.bg(colors.background2), ]} /> {t('delivery.drawSign')}
      {isPortrait && (
        <View style={[s.flexRow, helpers.width('100%')]}>
          <View style={helpers.width('50%')}>
            <Button
              disabled={!isDraw}
              type={PRIMARY}
              title={t('buttonTitles.done')}
              onPress={handleConfirm}
            />
          </View>
          <View style={helpers.width('50%')}>
            <Button
              type={DENY}
              title={t('buttonTitles.clear')}
              onPress={handleClear}
            />
          </View>
        </View>
      )}
    </View>
  )}
</Animated.View>

); }

const styles = StyleSheet.create({ container: { alignItems: 'center', position: 'absolute', backgroundColor: colors.white, left: 0, right: 0, top: 0, bottom: 0, zIndex: 10, }, camera: { ...s.flexG, height: 400, width: '100%', }, image: { position: 'absolute', alignSelf: 'center', width: 220, height: 100, bottom: 40, ...commonStyles.imgCover, }, bottomText: { ...s.ffInterMedium, ...s.fsSmallPlus, ...s.alignCenter, ...helpers.color.text(colors.whiteTransparent1), }, signBlock: { position: 'relative', }, });

export default Signature;

priyanshop commented 1 year ago

same issue i am facing