稚久|从图片裁剪来聊聊前端二进制( 四 )
mousedown鼠标按下事件 。 这里要记录下鼠标按下时的开始坐标 , 即startX与startY , 同时要将标志位startDrag设为true , 标识鼠标开始移动 。
handleMouseDown = (event) => {this.setState({startX: event.clientX,startY: event.clientY,startDrag: true,});};mousemove鼠标移动事件 。 判断startDrag为true(即鼠标开始移动) , 然后记录对应移动的距离 。
handleMouseMove = (event) => {if (this.state.startDrag) {this.drawImage(event.clientX - this.state.startX + this.state.lastX,event.clientY - this.state.startY + this.state.lastY);}};mouseup鼠标弹起事件 。 这里要记录下最终鼠标的落点坐标 , 对应就是lastX与lastY 。
handleMouseUp = (event) => {this.setState({lastX: event.clientX - this.state.startX + this.state.lastX,lastY: event.clientY - this.state.startY + this.state.lastY,startDrag: false,});};裁剪图片这个时候我们就需要用到canvas了 , canvas和图片一样 , 所以新建canvas时就要确定其高宽 。
将图片放置入canvas时需要调用drawImage:
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)具体API使用参考MDN上的drawImage[6]
drawImage = (left = this.state.lastX, top = this.state.lastY) => {let image = this.imageRef.current;let canvas = this.canvasRef.current;let ctx = canvas.getContext("2d");ctx.clearRect(0, 0, canvas.width, canvas.height);let imageWidth = image.width;let imageHeight = image.height;if (imageWidth > imageHeight) {let scale = canvas.width / canvas.height;imageWidth = canvas.width * this.state.times;imageHeight = imageHeight * scale * this.state.times;} else {let scale = canvas.height / canvas.width;imageHeight = canvas.height * this.state.times;imageWidth = imageWidth * scale * this.state.times;}ctx.drawImage(image,(canvas.width - imageWidth) / 2 + left,(canvas.height - imageHeight) / 2 + top,imageWidth,imageHeight);};其中这里面我们还加入了scale , 这个变量是用来实现图片放大、缩小效果的 。
而且会判断图片的宽、高的大小关系 , 从而实现图片在canvas中对应的适配 。
读取裁剪后的图片并上传这时我们要获取canvas中图片的信息 , 用toDataURL就可以转换成上面用到的DataURL 。
confirm = () => {let canvas = this.canvasRef.current;let ctx = canvas.getContext("2d");const imageData = http://kandian.youth.cn/index/ctx.getImageData(100, 100, 100, 100);let avatarCanvas = document.createElement("canvas");avatarCanvas.width = 100;avatarCanvas.height = 100;let avatarCtx = avatarCanvas.getContext("2d");avatarCtx.putImageData(imageData, 0, 0);let avatarDataUrl = avatarCanvas.toDataURL();this.setState({ avatarDataUrl });this.avatarRef.current.src = http://kandian.youth.cn/index/avatarDataUrl;};然后取出其中base64信息 , 再用window.atob转换成由二进制字符串 。 但window.atob转换后的结果仍然是字符串 , 直接给Blob还是会出错 。 所以又要用Uint8Array转换一下 。
这时候裁剪后的文件就储存在blob里了,我们可以把它当作是普通文件一样 , 加入到FormData里 , 并上传至服务器了 。
upload = (event) => {// console.log("文件url", this.state.avatarDataUrl);let bytes = atob(this.state.avatarDataUrl.split(",")[1]);console.log("bytes", bytes);let arrayBuffer = new ArrayBuffer(bytes.length);let uInt8Array = new Uint8Array();for (let i = 0; i
推荐阅读
- 澳洋顺昌|今日股市概况与热点公司扫描(9/7)
- 雪佛兰|美系车里,雪佛兰和福特家用车,差距天壤之别
- 兔玩电竞|JPL职业联赛名将榜第一期,剑网3
- 贵娅说娱乐|搞笑GIF:美少女的自拍
- 鹿晗|鹿晗的人设,终于崩塌了
- 倪妮|双眼皮“割坏了”的倪妮,算什么绝世大美女啊?
- 武汉大学人民医院|泪目!武汉落日余晖照主角重逢
- 波兰队|周一欧国联:波黑VS波兰、以色列VS斯洛伐克
- 5G|小米首款“5G汽车”亮相,小米有哈不能造
- 【幸福花开新边疆】219国道旁的“脱贫事”
