首页 技术 正文
技术 2022年11月23日
0 收藏 565 点赞 4,914 浏览 7587 个字

效果图:

import React, { Component } from 'react';
import scaleImage from './images/scale.png';
import closeImage from './images/close.png';
import maskImage from './images/mask.png';
import { Button, message } from 'antd';class EidtImage extends Component {
constructor(props) {
super(props);
this.state = {
bounder: 7,
image1: {
img: undefined, // 保存图片对象
src: maskImage, // 图片路径
x: 50, // 图片左上角x坐标
y: 100, // 图片左上角y坐标
width: 100, // 用来绘制的宽度(注意不是图片自身的宽度,图片会被压缩显示)
height: 20, // 用来绘制图片的高度
drag: false, // 是否处于拖拽状态
scale: false, // 是否处于缩放状态
scaleDirection: '', // 缩放方向
scaleIcon: scaleImage,
closeIcon: closeImage,
selected: true, //拖拽模块是否处于选中转态,true为是
closeMoudle: false, //true:关闭遮层,false展示遮层
imageUrl: '' //画布背景图
},
imgUrl: '',
cansText: {}, //画布对象
canva: {},
}
} componentDidMount = () => {
this.canvasInit();
}
// 画布初始化
canvasInit = () => {
let canvasId = this.refs.canvas.id;
let canva = document.getElementById(canvasId);
const cansText = canva.getContext("2d");
const { imageUrl } = this.props;
this.setState({
cansText, canva, imageUrl
}, () => {
// 加载图片
this.loadimage();
}) } //加载
loadimage = () => {
const obj = this.state.image1;
const { cansText, canva, imageUrl } = this.state;
let bgImage = new Image();
bgImage.crossOrigin = "anonymous";//解决图片跨域
bgImage.src = imageUrl;
bgImage.onload = function () {
let bgImageW = bgImage.width;
let bgImageH = bgImage.height;
canva.width = 180;
canva.height = 180 * bgImageH / bgImageW;
cansText.drawImage(bgImage, 0, 0, 180, 180 * bgImageH / bgImageW);
if (obj.closeMoudle) return;
let image = new Image();
image.crossOrigin = "anonymous";//解决图片跨域
image.src = obj.src;
image.onload = function () {
cansText.drawImage(image, obj.x, obj.y, obj.width, obj.height);
obj.image = image;
if (obj.selected) {
// 虚线
cansText.setLineDash([5, 5]);//定义虚线的长度和间隔
cansText.strokeStyle = "#fff";
cansText.strokeRect(obj.x, obj.y, obj.width, obj.height);
//渲染伸缩图标
let scaleIcon = new Image();
scaleIcon.crossOrigin = "anonymous";
scaleIcon.src = obj.scaleIcon;
scaleIcon.onload = function () {
cansText.drawImage(scaleIcon, obj.x - 8, obj.y + obj.height - 12, 20, 20);
}
// 关闭遮层图标
let closeIcon = new Image();
closeIcon.crossOrigin = "anonymous";
closeIcon.src = obj.closeIcon;
closeIcon.onload = function () {
cansText.drawImage(closeIcon, obj.x + obj.width - 10, obj.y - 10, 20, 20)
}
} }
}
} // 监听鼠标按下事件
onmousedown = (e) => {
if (e) e.persist();
let that = this;
let { bounder, image1 } = that.state;
let mousex = e ? e.nativeEvent.offsetX : 1000;
let mousey = e ? e.nativeEvent.offsetY : 1000;
let bottom = image1.y + image1.height;
let top = image1.y;
let left = image1.x;
let right = image1.x + image1.width; //判断,是否关闭遮层
if (right - 10 < mousex && mousex < right + 10 && top - 10 < mousey && mousey < top + 10) {
image1.closeMoudle = true;
} // 判断,当前拖拽模块是否选中状态
if (right + 10 < mousex || mousex < left - 10 || bottom + 10 < mousey || mousey < top - 10) {
image1.selected = false;
} else {
image1.selected = true;
} // 判断是缩放还是拖拽,若点击位置和边线的差大于bounder则认为是拖拽,否则是缩放
if ((left + bounder <= mousex && mousex <= right - bounder) && (top + bounder <= mousey && mousey <= bottom - bounder)) {
image1.drag = true;
image1.scale = false;
image1.scaleDirection = '';
} else if (0 <= mousex - left && mousex - left <= bounder) {
image1.scaleDirection = 'left';
image1.scale = true;
image1.drag = false;
} else if (0 <= right - mousex && right - mousex <= bounder) {
image1.scaleDirection = 'right';
image1.scale = false;
image1.drag = true;
} if (0 <= mousey - top && mousey - top <= bounder) {
image1.scaleDirection += 'top';
image1.scale = false;
image1.drag = true;
} else if (0 <= bottom - mousey && bottom - mousey <= bounder) {
image1.scaleDirection += 'bottom';
image1.scale = true;
image1.drag = false;
}
this.loadimage();
}
// 鼠标弹起,重置所有事件参数
onmouseup = (e) => {
e.persist();
const { image1 } = this.state;
// body...
image1.drag = false;
image1.scale = false;
image1.scaleDirection = '';
this.setState({ image1 });
}
// 鼠标移动事件
onmousemove = (e) => {
e.persist();
const { image1, cansText, canva, imageUrl } = this.state;
// body...
let mousex = e.nativeEvent.offsetX;
let mousey = e.nativeEvent.offsetY;
if (image1.drag) {
// 画背景图
let bgImage = new Image();
bgImage.crossOrigin = "anonymous" //解决图片跨域
bgImage.src = imageUrl;
bgImage.onload = function () {
let bgImageW = bgImage.width;
let bgImageH = bgImage.height;
canva.width = 180;
canva.height = 180 * bgImageH / bgImageW; // 鼠标移出canvas区域
if (mousex < 0 || mousex >= 180 || mousey >= canva.height - 5 || mousey <= 0) {
image1.drag = false;
image1.scale = false;
};
cansText.drawImage(bgImage, 0, 0, 180, 180 * bgImageH / bgImageW); if (image1.closeMoudle) return; // 移动图片
if (e.movementX || e.movementY) {
let tem_imgx = image1.x + e.movementX;
let tem_imgy = image1.y + e.movementY;
image1.x = tem_imgx;
image1.y = tem_imgy;
if (image1.x + image1.width >= 180) {
image1.x = 180 - image1.width;
}
if (image1.y + image1.height >= 180 * bgImageH / bgImageW) {
image1.y = 180 * bgImageH / bgImageW - image1.height;
} if (image1.y <= 0) {
image1.y = 0;
}
if (image1.x <= 0) {
image1.x = 0;
}
if (image1.selected) {
//渲染伸缩图标
let scaleIcon = new Image();
scaleIcon.crossOrigin = "anonymous";
scaleIcon.src = image1.scaleIcon;
scaleIcon.onload = function () {
cansText.drawImage(scaleIcon, image1.x - 8, image1.y + image1.height - 12, 20, 20);
}
// 关闭遮层图标
let closeIcon = new Image();
closeIcon.crossOrigin = "anonymous";
closeIcon.src = image1.closeIcon;
closeIcon.onload = function () {
cansText.drawImage(closeIcon, image1.x + image1.width - 10, image1.y - 10, 20, 20)
}
// 虚线
cansText.setLineDash([5, 5]);//定义虚线的长度和间隔
cansText.strokeStyle = "#fff";
cansText.strokeRect(image1.x, image1.y, image1.width, image1.height);
}
// 清空画布
cansText.clearRect(image1.x, image1.y, image1.width, image1.height); // 被拖拽的图片
cansText.drawImage(image1.image, image1.x, image1.y, image1.width, image1.height);
};
} } //缩放
if (image1.scale) {
// 画背景图
let bgImage = new Image();
bgImage.crossOrigin = "anonymous"//解决图片跨域
bgImage.src = imageUrl;
bgImage.onload = function () {
let bgImageW = bgImage.width;
let bgImageH = bgImage.height;
canva.width = 180;
canva.height = 180 * bgImageH / bgImageW;
cansText.drawImage(bgImage, 0, 0, 180, 180 * bgImageH / bgImageW);
// 缩放图片
if (e.movementX || e.movementY) {
let movex = e.movementX;
let movey = e.movementY;
if (movex !== 0 || movey !== 0) {
//根据x缩放方向判断固定点
if (image1.scaleDirection.search('right') !== -1) {
image1.width += movex;
} else if (image1.scaleDirection.search('left') !== -1) {
image1.x += movex;
image1.width -= movex;
}
if (image1.scaleDirection.search('bottom') !== -1) {
image1.height += movey;
} else if (image1.scaleDirection.search('top') !== -1) {
image1.height -= movey;
image1.y += movey;
}
// 清除画布
cansText.clearRect(image1.x, image1.y, image1.width, image1.height);
// 伸缩图标
//渲染伸缩图标
let scaleIcon = new Image();
scaleIcon.crossOrigin = "anonymous";
scaleIcon.src = image1.scaleIcon;
scaleIcon.onload = function () {
cansText.drawImage(scaleIcon, image1.x - 8, image1.y + image1.height - 12, 20, 20);
} // 关闭遮层图标
let closeIcon = new Image();
closeIcon.crossOrigin = "anonymous";
closeIcon.src = image1.closeIcon;
closeIcon.onload = function () {
cansText.drawImage(closeIcon, image1.x + image1.width - 10, image1.y - 10, 20, 20)
}
// 虚线
cansText.setLineDash([5, 5]);//定义虚线的长度和间隔
cansText.strokeStyle = "#fff";
cansText.strokeRect(image1.x, image1.y, image1.width, image1.height);
// 被拖拽的图片
cansText.drawImage(image1.image, image1.x, image1.y, image1.width, image1.height);
};
};
}
}
} // 保存图片
saveImage = () => {
let that = this;
let { canva, imgUrl } = that.state;
// 在导出画布之前,把一些图标、虚线去掉;
this.onmousedown();
setTimeout(function () {
imgUrl = canva.toDataURL('image/jpeg'); //转换图片为dataURL
that.setState({
imgUrl
}, () => {
let obj={};
if(that.props.id==='imageUrlFront'){
obj={imageUrlFront:that.state.imgUrl}
}else if(that.props.id==='imageUrlLeft'){
obj={imageUrlLeft:that.state.imgUrl}
}else if(that.props.id==='imageUrlRight'){
obj={imageUrlRight:that.state.imgUrl}
}
that.props.parent.getEidtImageUrl(that, obj)
message.success('保存成功')
})
}, 100);
}
// 重新编辑
reMake = () => {
let {image1}=this.state;
let newImage=Object.assign({},image1,{closeMoudle:false,selected:true})
this.setState({
image1:newImage
},()=>{
this.canvasInit();
})
} render() {
return (
<React.Fragment>
<div className="canvas-container">
<canvas onMouseUp={this.onmouseup} onMouseDown={this.onmousedown} onMouseMove={this.onmousemove} id={this.props.id} ref="canvas" style={{ backgroundColor: '#fff' }}>您的浏览器不支持画布标签</canvas>
<Button type="primary" size="small" onClick={this.saveImage}>保存图片</Button>
<Button type="default" size="small" style={{ marginLeft: '35px' }} onClick={this.reMake}>重新编辑</Button>
</div>
</React.Fragment>
);
}}export default EidtImage;
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,454
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,868
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,704
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,464
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,103
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,261