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