记录一个方法用于移动端横屏画布的旋转图片功能。
核心代码:
rotateBase64(data) {return new Promise((resolve) => {const imgView = new Image();imgView.src = data;const canvas = document.createElement('canvas');const context = canvas.getContext('2d');const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; // 裁剪坐标imgView.onload = () => {const imgW = imgView.width;const imgH = imgView.height;const size = imgH;canvas.width = size * 2;canvas.height = size * 2;cutCoor.sx = size;cutCoor.sy = size - imgW;cutCoor.ex = size + imgH;cutCoor.ey = size + imgW;context.translate(size, size);context.rotate(Math.PI / 2 * 3);context.drawImage(imgView, 0, 0);const imgData = context.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);canvas.width = imgH;canvas.height = imgW;context.putImageData(imgData, 0, 0);resolve(canvas.toDataURL('image/png'));};});}
整体功能:
import React, { Component } from 'react';
import styles from './index.less';
import { connect } from 'react-redux';
import bindDispatchToPromise from '@/constants/bindDispatchToPromise';
import SignaturePad from 'signature_pad'
import { Button, Toast } from 'antd-mobile';import {SIGNATURE,
} from "@/reducers/registrationInfo";@connect((state) => {return {}
})
class BaseInfo extends Component {signaturePad = null; constructor(props) {super(props)let {match: { params },} = this.props;this.state = {hasSometing: false // 画布上是否有东西}}componentDidMount() {this.init()}init = () => {const _canvas = document.querySelector("#signature");const winW = window.innerWidth;const winH = window.innerHeight;_canvas.width = winW;_canvas.height = winH;const signaturePad = new SignaturePad(_canvas, {minWidth: 3,maxWidth: 3,penColor: "#000",});// 添加操作事件signaturePad.addEventListener('endStroke', this.onEndStroke);this.signaturePad = signaturePad;}onEndStroke = () => {if (!this.state.hasSometing) {this.setState({hasSometing: true});}}handleClear = () => {this.signaturePad?.clear();this.setState({hasSometing: false});}rotateBase64(data) {return new Promise((resolve) => {const imgView = new Image();imgView.src = data;const canvas = document.createElement('canvas');const context = canvas.getContext('2d');const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; // 裁剪坐标imgView.onload = () => {const imgW = imgView.width;const imgH = imgView.height;const size = imgH;canvas.width = size * 2;canvas.height = size * 2;cutCoor.sx = size;cutCoor.sy = size - imgW;cutCoor.ex = size + imgH;cutCoor.ey = size + imgW;context.translate(size, size);context.rotate(Math.PI / 2 * 3);context.drawImage(imgView, 0, 0);const imgData = context.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);canvas.width = imgH;canvas.height = imgW;context.putImageData(imgData, 0, 0);resolve(canvas.toDataURL('image/png'));};});}handleSubmit = async () => {const {hasSometing} = this.state;console.log("hasSometing", hasSometing)if (!hasSometing) {Toast.show({content: "请先签名"})return}const data = this.signaturePad.toDataURL();const base64 = await this.rotateBase64(data)console.log('base64 ',base64 )// 最后正向旋转的图片}handleGoBack = () => {this.props.history.goBack();}render() {let {} = this.statereturn (<div className={styles.body}><canvasid="signature"className={styles.canvas}></canvas><div className={styles.footer}><Button className={styles.btn} onClick={this.handleGoBack}>返回</Button><Button color="primary" onClick={this.handleClear} className={styles.btn} >清空</Button><Button color="primary" onClick={this.handleSubmit} className={styles.btn} >确认</Button></div></div>)}
}export default BaseInfo;