改进上传模块

This commit is contained in:
wzhqwq 2021-08-01 12:38:24 +08:00
父節點 b8f99f4e4c
當前提交 7c6a84b9a0

查看文件

@ -8,6 +8,8 @@ export default class UploadUnit extends Component {
imgRef = createRef();
imgWidth;
imgHeight;
imgType;
uploadXhr = null;
constructor(props) {
super(props);
@ -40,6 +42,7 @@ export default class UploadUnit extends Component {
handleCancel() {
this.setState({ status: -1 });
if (this.uploadXhr) this.uploadXhr.abort();
setTimeout(() => {
this.props.onCancel();
}, 300);
@ -51,12 +54,13 @@ export default class UploadUnit extends Component {
this.handleCancel();
return;
}
this.imgType = file.type;
let reader = new FileReader();
this.setState({ status: -2 });
setTimeout(() => {
this.setState({ status: 0 });
reader.onload = () => {
var image = new Image();
let image = new Image();
// 被注释掉的是用来应对ios巨大图片没来得及加载的问题
// image.onload = () => setTimeout(() => this.convert(image), 1000);
image.onload = () => this.convert(image);
@ -69,8 +73,8 @@ export default class UploadUnit extends Component {
convert(img) {
if (this.converted) return;
var canvas = document.createElement('canvas');
var { width, height } = img;
let canvas = document.createElement('canvas');
let { width, height } = img;
if (width > 1600) {
height *= 1600 / width;
width = 1600;
@ -85,16 +89,16 @@ export default class UploadUnit extends Component {
this.imgHeight = height;
canvas.getContext('2d').drawImage(img, 0, 0, width, height);
canvas.toBlob(blob => {
this.setState({ src: canvas.toDataURL('image/jpeg', 1), status: 2, file: blob, width: width / height * 200 });
}, 'image/jpeg', 1);
this.setState({ src: canvas.toDataURL(this.imgType, 1), status: 2, file: blob, width: width / height * 200 });
}, this.imgType, 1);
}
async upload() {
var xhr = new XMLHttpRequest();
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
let data = JSON.parse(xhr.responseText);
if (data.code === 200) {
this.setState({ status: 4 });
this.props.onUpload(data.data.url);
@ -114,19 +118,19 @@ export default class UploadUnit extends Component {
this.setState({ status: 2 });
this.props.onUploadError('请求失败,请检查网络');
}
xhr.onprogress = e => {
if (e.lengthComputable) {
var percent = Math.round(e.loaded * 100 / e.total);
this.setState({ progress: percent });
}
xhr.upload.onprogress = e => {
console.log(e.loaded, e.total, e.lengthComputable);
if (e.lengthComputable)
this.setState({ progress: e.loaded / e.total });
};
xhr.open("POST", apis.uploadImage, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
var fd = new FormData();
let fd = new FormData();
fd.append("image", this.state.file, 'image.jpg');
xhr.send(fd);
this.setState({ status: 3, progress: 0 });
this.uploadXhr = xhr;
xhr.send(fd);
}
scale() {
@ -134,10 +138,9 @@ export default class UploadUnit extends Component {
let el = this.imgRef.current;
let { x, y } = el.getBoundingClientRect();
let { innerWidth, innerHeight } = window;
console.log(x, y, innerWidth, innerHeight);
let initialScale = 200 / this.imgHeight,
terminalScale = Math.min(1, Math.min(innerWidth / this.imgWidth, innerHeight / this.imgHeight));
this.setState({ transform: `translate(${x - (innerWidth - this.imgWidth * terminalScale) / 2}px, ${y - (innerHeight - this.imgHeight * terminalScale) / 2}px) scale(${initialScale})`, isScaled: true });
terminalScale = Math.min(1, Math.min((innerWidth - 10) / this.imgWidth, (innerHeight - 10) / this.imgHeight));
this.setState({ transform: `translate(${x + (this.imgWidth * initialScale - innerWidth) / 2}px, ${y + (200 - innerHeight) / 2}px) scale(${initialScale})`, isScaled: true });
setTimeout(() => {
this.setState({ transform: `translate(0, 0) scale(${terminalScale})` });
}, 0);
@ -148,17 +151,16 @@ export default class UploadUnit extends Component {
let el = this.imgRef.current;
let { x, y } = el.getBoundingClientRect();
let { innerWidth, innerHeight } = window;
let initialScale = 200 / this.imgHeight,
terminalScale = Math.min(1, Math.min(innerWidth / this.imgWidth, innerHeight / this.imgHeight));
this.setState({ transform: `translate(${x - (innerWidth - this.imgWidth * terminalScale) / 2}px, ${y - (innerHeight - this.imgHeight * terminalScale) / 2}px) scale(${initialScale})`, isScaled: true });
let initialScale = 200 / this.imgHeight;
this.setState({ transform: `translate(${x + (this.imgWidth * initialScale - innerWidth) / 2}px, ${y + (200 - innerHeight) / 2}px) scale(${initialScale})`, isScaled: true });
setTimeout(() => {
this.setState({ isScaled: false });
}, 300);
}
render() {
const angle = this.state.progress / 100 * Math.PI * 2;
console.log(this.state.transform);
const angle = Math.min(this.state.progress, 0.99) * Math.PI * 2;
console.log(this.state.progress);
return (
<div className="upload-wrap">
<div className={this.state.status === -1 ? 'upload-unit' : 'upload-unit open'} style={{ width: this.state.status <= 1 ? '' : `${this.state.width}px` }}>
@ -179,7 +181,7 @@ export default class UploadUnit extends Component {
<div className="progress-circle">
<svg viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d={
`M 50,3 A 47,47 0 ${this.state.progress < 50 ? 0 : 1},1 ${50 + Math.sin(angle) * 47},${50 - Math.cos(angle) * 47}`
`M 50,3 A 47,47 0 ${this.state.progress < 0.5 ? 0 : 1},1 ${50 + Math.sin(angle) * 47},${50 - Math.cos(angle) * 47}`
} fill="transparent" stroke="#FFF" strokeWidth="6" strokeLinecap="round"></path>
</svg>
</div>