react-native-signature-canvas icon indicating copy to clipboard operation
react-native-signature-canvas copied to clipboard

Canvas content not getting resized on orientation change

Open bjarkof opened this issue 3 years ago • 4 comments

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?

bjarkof avatar Jun 14 '21 10:06 bjarkof

provide your code example?

YanYuanFE avatar Jul 14 '21 13:07 YanYuanFE

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

udot-a avatar Sep 01 '22 15:09 udot-a

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 && ( <View> {isPortrait && ( <Header left={() => setShow(false)} title={t('delivery.clientSignature')} // white={false} /> )}

      <View
        style={[
          styles.signBlock,
          s.flex,
          orientation.includes('LANDSCAPE') && helpers.width(width - 50),
          orientation === 'LANDSCAPE-LEFT' && helpers.margin.left(-50),
          orientation === 'LANDSCAPE-RIGHT' && helpers.margin.right(-50),
          helpers.color.bg(colors.background2),
          !orientation.includes('LANDSCAPE') && helpers.br(8),
          !orientation.includes('LANDSCAPE') && helpers.margin(8),
          helpers.padding(8),
        ]}>
        <Text
          style={[
            s.ffInterMedium,
            s.fsSmall,
            s.secondary,
            helpers.margin(16, 0, 8, 16),
          ]}>
          {t('delivery.clientSignature')}
        </Text>
        <SignatureScreen
          ref={ref}
          // onEnd={handleEnd}
          onOK={handleOK}
          // onEmpty={handleEmpty}
          // onClear={handleClear}
          // onGetData={handleData}
          // autoClear={true}
          // rotated
          descriptionText=""
          onBegin={() => setDraw(false)}
          onEnd={() => setDraw(true)}
          webStyle={webStyle}
          // trimWhitespace
          // webviewContainerStyle={{}}
          style={[
            s.flexG,
            helpers.br(10),
            helpers.color.bg(colors.background2),
          ]}
        />
        <Text
          style={[
            s.fsSmallPlus,
            s.asCenter,
            helpers.margin(8, 0, 30, 0),
            helpers.color.text(colors.grey),
          ]}>
          {t('delivery.drawSign')}
        </Text>
      </View>

      {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;

udot-a avatar Sep 01 '22 15:09 udot-a

same issue i am facing

priyanshop avatar Aug 22 '23 06:08 priyanshop