移动端手签-图片base64旋转功能
记录一个方法用于移动端横屏画布的旋转图片功能。
核心代码:
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.state
return (
<div className={styles.body}>
<canvas
id="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;