คุณสมบัติส่วนประกอบนี้ประกอบด้วย:
การครอบตัดรูปภาพ (ลากกล่องครอบตัดและเปลี่ยนขนาดของกล่องครอบตัด)
ภาพโมเสก (วาดโมเสก, โมเสกใส);
การแสดงตัวอย่างรูปภาพ การคืนค่ารูปภาพ (กลับสู่รูปภาพต้นฉบับ กลับสู่รูปภาพที่ประมวลผล)
อัพโหลดรูปภาพ (รับลายเซ็น, อัพโหลดรูปภาพ)
2. ตรรกะหลัก2.1 การครอบตัดรูปภาพ
รับตำแหน่งของกล่องครอบตัด (สี่เหลี่ยมผืนผ้า) ที่สัมพันธ์กับผืนผ้าใบ (ซ้ายบน) และความสูงและความกว้างของกล่องครอบตัด รับ (getImageData) วัตถุรูปภาพ (ImageData) ที่ตำแหน่งที่สอดคล้องกันของผืนผ้าใบ ล้างผ้าใบผ้าใบ วาดวัตถุรูปภาพ (ImageData) ที่ได้รับจาก (putImageData) ที่ตำแหน่งที่สอดคล้องกันของผืนผ้าใบ สร้างภาพตัวอย่าง
2.2 ภาพโมเสก
การวาดภาพโมเสกคือการวาดพื้นที่ที่อยู่ตรงกลางเส้นทางการลากเมาส์ (ความกว้างของแปรง) ใหม่ให้เป็นสีอื่นๆ ผลลัพธ์โดยทั่วไปคือสีโดยรอบจะใกล้เคียงกัน
วิธีการเลือกสี:
1) ตัวอย่างเช่น หากคุณมีพิกัด (x, y) ของจุดที่เมาส์ลาก ให้กำหนดสี่เหลี่ยมด้วยพิกัดที่มุมซ้ายบน (x, y) กว้าง 30px และสูง 30px เราแบ่งความกว้างและความสูงของสี่เหลี่ยมผืนผ้าด้วย 5 (แบ่งออกเป็น 5 ส่วนซึ่งสามารถปรับแต่งได้ n ส่วน) ดังนั้นขณะนี้จึงมีกริดขนาดเล็ก 6px จำนวน 25 ตาราง ตารางเล็กๆ แต่ละตารางมีความกว้างและสูง 6px
2) จากนั้นเราสุ่มรับกริดขนาดเล็กและรับ (getImageData) วัตถุรูปภาพ (ImageData) ของกริดเล็ก ๆ นี้ จากนั้นสุ่มรับสีสี (rgba: ImageD) ของพิกเซลบางตัว (กว้าง 1px, สูง 1px) บนสิ่งนี้ วัตถุภาพ ata.data[0], ImageData.data[1], ImageData.data[2], ImageData.data[3]); สุดท้ายนี้ เราตั้งค่าสีของแต่ละพิกเซลของตารางขนาดเล็ก 6x6px แรกให้เป็นสี
3) สำหรับสีของตารางเล็กๆ อีก 24 ช่อง ให้ทำตาม 2 ขั้นตอน
2.3 โมเสกใส
เราต้องเข้าใจปัญหา ไม่ว่าจะเป็นการวาดภาพโมเสกหรือเคลียร์โมเสก สิ่งสำคัญคือการวาดภาพ เราวาดภาพโมเสกที่ตำแหน่งใดตำแหน่งหนึ่ง เมื่อเราเคลียร์มันแล้ว เราจะวาดวัตถุรูปภาพต้นฉบับที่ตำแหน่งปัจจุบันอีกครั้ง บรรลุผลของการทำความสะอาด ดังนั้นเราจึงจำเป็นต้องสำรองข้อมูลแคนวาสที่เหมือนกับรูปภาพต้นฉบับทุกประการ เมื่อทำการล้าง เราจำเป็นต้องได้รูปภาพในตำแหน่งที่สอดคล้องกันบนผืนผ้าใบสำรองและวาดไปยังตำแหน่งของโมเสก
2.4 การแสดงตัวอย่างรูปภาพ
การแสดงตัวอย่างรูปภาพคือการได้พื้นที่ของกรอบการครอบตัดและรับวัตถุรูปภาพในพื้นที่ แล้ววาดลงบนผืนผ้าใบ
2.5 คืนค่ารูปภาพให้เป็นรูปภาพต้นฉบับ
ล้างผ้าใบและวาดภาพต้นฉบับอีกครั้ง
2.6 คืนค่าเป็นรูปภาพที่ถูกจัดการ
การแสดงตัวอย่างคือการบันทึกออบเจ็กต์รูปภาพแคนวาส (ImageData) ล้างแคนวาส และวาดออบเจ็กต์รูปภาพที่บันทึกไว้ลงบนผืนผ้าใบ
2.7 การอัพโหลดรูปภาพ
รับเส้นทางรูปภาพแคนวาส (toDataURL) และแปลงอิมเมจ base64 ที่ได้รับให้เป็นออบเจ็กต์ File เพื่ออัปโหลด
3. รหัสที่สมบูรณ์มีดังนี้:
<เทมเพลต> <div class=canvas-clip :loading=loading> <div v-show=isDrop class=canvas-mainBox ref=canvas-mainBox id=canvas-mainBox @mousedown.stop=startMove($event) > <div class=canvas-minBox ซ้ายบน @mousedown.stop=startResize($event,0)></div> <div class=canvas-minBox ขึ้น @mousedown.stop=startResize($event,1)></div> <div class=canvas-minBox ขวาขึ้น @mousedown.stop=startResize($event,2)></div> <div class=canvas- minBox ขวา @mousedown.stop=startResize($event,3)></div> <div class=canvas-minBox ขวาลง @mousedown.stop=startResize($event,4)></div> <div class=canvas-minBox down @mousedown.stop=startResize($event,5)></div> <div class=canvas-minBox ซ้ายลง @mousedown.stop=startResize($event,6)></ div div> <div class=canvas-minBox left @mousedown.stop=startResize($event,7)></div> </div> <!-- Canvas--> <canvas class=canvas-area ref=canvas id=canvas :width=canvasWidth :height=canvasHeight @mousedown.stop=startMove($event) :class={hoverPaint:isMa,hoverClear:isMaClear} ></canvas> <!-- แคนวาสสำรอง--> <canvas class=canvas-copy ref=canvasCopy :width=canvasWidth :height=canvasHeight></canvas> <div class=canvas-btns> <button v-if=backBtn @click=clipBack>ย้อนกลับ</button> <button :class={active:btnIndex==0} @click= sourceImg>รูปภาพต้นฉบับ</button> <button :class={active:btnIndex==1} @click=paintRectReady :disabled=isDisabled>โมเสก</button> <ปุ่ม :class={active:btnIndex==2} @click=paintRectClearReady :disabled=isDisabled>ยางลบ</button> <button :class={active:btnIndex==3 } @click=clipReady :disabled=isDisabled>ครอบตัด</button> <button :class={active:btnIndex==4} @click=clipPosition>ดูตัวอย่าง</button> <button @click=getSignature>อัปโหลด</button> <button class=close @click=canvasClose()>x</button> <!-- <div class=paint-size v-if=isMaClear ||. isMa> <span>ขนาดแปรง</span> <input :defaultValue=maSize v-model=maSize max=100 min=1 type=range> <span class=size-num>{{maSize}}</span> </div> --> </div> </div></template><script>นำเข้า axios จาก axios; นำเข้า md5 จาก js-md5 ; นำเข้าคำขอจาก ../../axios/config; ส่งออกค่าเริ่มต้น { อุปกรณ์ประกอบฉาก: [imgUrl], ข้อมูล () { กลับ { resizeFX: , movePrev: , canvasWidth: 800, // ความกว้างของผ้าใบ canvasHeight: 600, // ความสูงของผ้าใบ: false, isDrop: false, // การครอบตัด isMa: false, // ขนาดโมเสค: 30, // ขนาดโมเสค isMaClear: false, // ล้างภาพโมเสค backBtn: false, // ปุ่ม Return isDisabled: false, // ปุ่มปิดการใช้งาน btnIndex: 0, // ปุ่มปัจจุบัน mouseX:'', // ตำแหน่งเมาส์ mouseY:'', clipEle: , // องค์ประกอบกล่องครอบตัด canvasDataSession: , // ข้อมูลแคนวาสก่อนแสดงตัวอย่างแคนวาส: , // Canvas ctx: , // บริบทของแคนวาส canvasCopy: , // คัดลอก canvas ctxCopy: , // คัดลอกตัวเลือกการอัพโหลดบริบทของ canvas: { // เส้นทางพารามิเตอร์การอัพโหลดรูปภาพ: , นโยบาย: , ลายเซ็นต์: , ชื่อผู้ใช้: } }; mount() { this.clipEle = this.$refs[canvas-mainBox]; this.canvas = this.$refs[canvas]; this.ctx = this.canvas.getContext(2d); = this.$refs[canvasCopy]; this.ctxCopy = this.canvasCopy.getContext(2d); this.draw(); }, วิธีการ: { // สร้างภาพวาด() { var img = รูปภาพใหม่(); img.setAttribute('crossOrigin', 'anonymous'); img.onload = () => { this.ctx.drawImage(img, 0, 0, 800 , 600); this.ctxCopy.drawImage (img, 0, 0, 800, 600); img.src = this.imgUrl + '?time=' + new Date().valueOf(); }, //Preview คำนวณตำแหน่งของกล่องครอบตัด (พิกัดด้านซ้ายบน) clipPosition() { this.isDisabled = true; this.backBtn = true; this.isMa = false; this.isMaClear = false; this.btnIndex = 4; // ตำแหน่งผ้าใบ var canvasPx = this.canvas.offsetLeft, canvasPy = this.canvas.offsetTop; if (this.isDrop) { // ตำแหน่งกล่องครอบตัด var clipPx = this.clipEle.offsetLeft, clipPy = this.clipEle.offsetTop, x = clipPx - canvasPx, y = clipPy - canvasPy, w = this.clipEle.offsetWidth, h = this.clipEle.offsetHeight, // จัดตำแหน่งภาพตัวอย่างให้อยู่ตรงกลาง X = 400 - this.clipEle.offsetWidth / 2, ตำแหน่ง Y = 300 - this.clipEle.offsetHeight / 2; } else { // ไม่มีช่องครอบตัด บันทึกรูปภาพทั้งหมด var x = 0, y = 0, w = this.canvas.offsetWidth , h = this.canvas.offsetHeight, // จัดตำแหน่งภาพตัวอย่างให้อยู่ตรงกลาง X = 0, ตำแหน่ง Y = 0; } var imageData = this.ctx.getImageData(x, y, w, h); this.canvasDataSession = this.ctx.getImageData ( 0, 0, this.canvasWidth, this.canvasHeight ); this.ctx.clearRect (0, 0, นี้ canvasWidth, this.canvasHeight); this.ctx.putImageData (รูปภาพข้อมูล, ตำแหน่ง X, ตำแหน่ง Y); this.clipEle.style.display = none; this.canvasCopy.style.display = none; }, // กลับสู่สถานะตัวอย่างล่วงหน้า clipBack() { this.btnIndex = -1; this.backBtn = false; = false ; this.isDrop = false; this.ctx.putImageData(this.canvasDataSession, 0, 0); this.canvasCopy.style.display = block; }, // ภาพต้นฉบับ sourceImg() { this.isDisabled = false; this.btnIndex = 0; this.backBtn = false; this.isMa = false; = รูปภาพใหม่ (); this.ctx.clearRect (0, 0, this.canvasWidth, this.canvasHeight); img.setAttribute('crossOrigin', 'anonymous'); img.onload = () => { this.ctx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight); }; .imgUrl + '?time=' + วันที่ใหม่().valueOf(); this.canvasCopy.style.display = block }, // รับลายเซ็น getSignature() { // Canvas image base64 ไปยัง File object var dataURL = this.canvas.toDataURL(image/jpg), arr = dataURL.split(,), mime = arr[0].match(/:( . *?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); (n--) { u8arr[n] = bstr.charCodeAt(n); } var obj = new Blob([u8arr], { ประเภท: mime }), time = new Date().toGMTString(), formData = new FormData(); formData.append(file, obj); // รับคำต่อท้ายไฟล์ var suffix = formData.get (ไฟล์). type.split (/) [1]; req .get (/ carsource-api/upyun/sign, { คำต่อท้าย: คำต่อท้าย }) . จากนั้น (ตอบกลับ => { ถ้า (response.data.code === 0) { this.uploadOption.path = response.data.data.path; formData.append (นโยบาย, response.data.data.policy); formData.append(การอนุญาต, response.data.data.signature); this.updateImg(formData); } }) .catch(function(error) {}); }, // อัพโหลด updateImg(formData) { axios({ url : http://v0.api.upyun.com/tmp-img, วิธีการ: POST, ข้อมูล: formData }). จากนั้น (ตอบกลับ => { ถ้า (response.data.code == 200) { this.$message.success(แก้ไขภาพสำเร็จ); this.canvasClose(upload, response.data.url.slice(4) } }); กล่องซูมย้าย startResize(e, n) { this.resizeFX = n; $(document).mousemove(this.resizeDiv); document.addEventListener(mouseup, this.stopResize); }, stopResize(e) { $(document).off(musemove, this.resizeDiv); document.removeEventListener(เมาส์อัพ, this.stopResize) this.movePrev = [e.pageX, e.pageY]; $(document).mousemove(this.moveDiv); document.addEventListener(mouseup, this.stopMove); }, stopMove(e) { $(document).off(มูสมูฟ, this.moveDiv); this.stopMove); }, moveDiv(e) { // โมเสกถ้า (this.isMa) { this.paintRect(e); } // ล้างภาพโมเสค if (this.isMaClear) { this.paintRectClear(e); } // ครอบตัด if (this.isDrop) { var targetDiv = $(#canvas-mainBox), offsetArr = targetDiv.offset(); var chaX = e.pageX - this.movePrev[0], chaY = e.pageY - this.movePrev[1], ox = parseFloat(targetDiv.css(ซ้าย)), oy = parseFloat(targetDiv.css(บนสุด)); targetDiv.css({ ซ้าย: ox + chaX + px, ด้านบน: oy + chaY + px }); this.movePrev = [e.pageX, e.pageY] } }, resizeDiv(e) { e.preventDefault(); e.stopPropagation(); // รับระยะห่างจากองค์ประกอบที่ต้องเปลี่ยนขนาดเป็นหน้า var targetDiv = $(#canvas-mainBox), offsetArr = targetDiv.offset(); = targetDiv.width() , eleSHeight = targetDiv.height(), ox = parseFloat(targetDiv.css(left)), oy = parseFloat(targetDiv.css(top)); // รับตำแหน่งเมาส์และเปรียบเทียบกับออฟเซ็ตเริ่มต้นขององค์ประกอบ var chaX = e.pageX - offsetArr.left, chaY = e.pageY - offsetArr.top; this.resizeFX) { กรณีที่ 0: //หากระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงหาก (chaX >= eleSWidth - 10 || chaY >= eleSHeight - 10) { return; } // รับค่าความต่างของตำแหน่ง (me) ตั้งค่าความกว้างและความสูงก่อน จากนั้นจึงกำหนดตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) *-1) ตำแหน่งเดิม + (me) targetDiv.css ({ ความกว้าง: eleSWidth + chaX * -1 + px, ความสูง: eleSHeight + chaY * -1 + px, ซ้าย: ox + chaX + px, ด้านบน: oy + chaY + px }); กรณีที่ 1: // ถ้าระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงใดๆ ถ้า (chaY >= eleSHeight - 10) { return; } // รับค่าความต่างของตำแหน่ง (me) กำหนดความกว้าง และ height ก่อน จากนั้นจึงกำหนดตำแหน่ง // Original width and height + ((me) *-1), ตำแหน่งเดิม + (me) targetDiv.css({ height: eleSHeight + chaY * -1 + px, top: oy + ช่า + px }); กรณีที่ 2: // หากระยะเคลื่อนที่ใกล้กับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงหาก (chaX <= 10 || chaY >= eleSHeight - 10) { return; ความแตกต่าง (me) ขั้นแรกให้ตั้งค่าความกว้างและความสูง กำหนดตำแหน่ง // ความสูงเดิม + ((me) *-1) ความกว้างเดิม + ((me)) ตำแหน่งเดิม + (me) targetDiv.css({ width : chaX + px, ความสูง: eleSHeight + chaY * -1 + px, ด้านบน: oy + chaY + px }); กรณีที่ 3: // หากระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงหาก (chaX <= 10 ) { return; } // รับค่าความแตกต่างของตำแหน่ง (me) ขั้นแรกให้ตั้งค่าความกว้างและความสูง จากนั้นจึงตั้งค่าตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) *-1) ตำแหน่งเดิม + (me) targetDiv .css({ ความกว้าง: chaX + px }); กรณีที่ 4: // หากระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงหาก (chaX <= 10 || chaY <= 10) { return; ความแตกต่าง (me) ตั้งค่าความกว้างและความสูงก่อน จากนั้นจึงตั้งค่าตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) *-1) ตำแหน่งเดิม + (me) targetDiv.css({ width: chaX + px, height : chaY + px }); กรณีที่ 5: // ถ้าระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงใดๆ ถ้า (chaY <= 10) { return; } // รับค่าความต่างของตำแหน่ง (me) กำหนดความกว้างและความสูง ขั้นแรก จากนั้นตั้งค่าตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) *-1) ตำแหน่งเดิม + (me) targetDiv.css({ height: chaY + px }); ระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการดำเนินการใด ๆ เกิดขึ้นหาก (chaX >= eleSWidth - 10 ||. chaY <= 10) { return; } // รับค่าความต่างของตำแหน่ง (me) ขั้นแรกให้ตั้งค่าความกว้างและความสูง จากนั้นจึงกำหนดตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) * -1) ตำแหน่งเดิม + (me) targetDiv.css({ width: eleSWidth + chaX * -1 + px, height: chaY + px, left: ox + chaX + px }); 7: //หากระยะการเคลื่อนที่ใกล้เคียงกับความกว้างหรือความสูง จะไม่มีการเปลี่ยนแปลงใดๆ หาก (chaX >= eleSWidth - 10) { return; } // รับค่าความต่างของตำแหน่ง (me) ตั้งค่าความกว้างและความสูงก่อน จากนั้นตั้งค่าตำแหน่ง // ความกว้างและความสูงดั้งเดิม + ((me) *-1), ตำแหน่งเดิม + (me) targetDiv.css({ width: eleSWidth + chaX * -1 + px, ซ้าย: ox + chaX + พิกเซล }); ค่าเริ่มต้น: break; } }, // การตัด clipReady() { this.btnIndex = 3; this.isMa = false; this.isMaClear = false; }, // .btnIndex = 1; this.isMa = true; this.isDrop = false; this.isMaClear = false; ยางลบ paintRectClearReady() { this.btnIndex = 2; this.isMa = false; this.isMaClear = true; }, // วาดสีโมเสค (e) { var offT = this.canvas.offsetTop, / / ระยะห่างจากบนสุด L = this.canvas.offsetLeft, // ระยะห่างจากซ้าย x = e.clientX, y = e.clientY; if(this.mouseX - x > this.maSize/2 || x - this.mouseX > this.maSize/2 || this.mouseY - y > this.maSize/2 || y - this.mouseY > this.maSize/2){ var oImg = this.ctx.getImageData(x - offL ,y - offT,this.maSize,this.maSize); var w = oImg.width; //ระดับของโมเสก ยิ่งตัวเลขมากเท่าไร ความเบลอก็จะยิ่งมากขึ้นเท่านั้น var num = 6; canvas var stepW = w/ num; var stepH = h/num; //นี่คือพิกเซลของ loop canvas for(var i=0;i<stepH;i++){ for(var j=0;j<stepW; เจ++){ //รับสีสุ่มของสี่เหลี่ยมจัตุรัสเล็ก นี่คือสี var ที่ได้จากตำแหน่งสุ่มของสี่เหลี่ยมจัตุรัสเล็ก = this.getXY(oImg,j*num+Math.floor(Math.random()*num),i *num +Math.floor(Math.random()*num)); //นี่คือพิกเซลของสี่เหลี่ยมจัตุรัสเล็กวงกลม for(var k=0;k<num;k++){ for(var l=0; l< หมายเลข;l++){ //กำหนดสีของสี่เหลี่ยมจัตุรัสเล็กๆ this.setXY(oImg,j*num+l,i*num+k,color); ; this.mouseX = e.clientX this.mouseY = e.clientY } }, getXY(obj,x,y){ var w = obj.width; var h = obj.height; var d = obj.data; var color = []; color[0] = d[4*(y*w+x)]; w+x)+1]; color[2] = d[4*(y*w+x)+2]; color[3] = d[4*(y*w+x)+3]; ; } setXY(obj,x,y,color){ var w = obj.width; var h = obj.height; var d = obj.data; d[4*(y*w+x)] = สี[0]; d[4*(y*w+x)+1] = สี[1]; d[4*(y*w+x)+2] = สี[2]; d[4*(y*w+x)+3] = color[3]; // ล้างภาพโมเสค paintRectClear(e) { var offT = this.canvasCopy.offsetTop, // ระยะทางจากด้านบน offL = this.canvasCopy .offsetLeft, // ระยะห่างไปทางซ้าย x = e.clientX, y = e.clientY, // รับข้อมูลภาพที่ตำแหน่งนี้ของรูปภาพต้นฉบับ imageData = this.ctxCopy.getImageData( x - offL, y - offT, this.maSize, this.maSize ); this.ctx.putImageData(imageData, x - offL, y - offT); }, // ปิดแคนวาสปิด (type , url) { this.$emit(isShowImgChange, type, url); } }};</script><style กำหนดขอบเขต> .canvas-clip { ตำแหน่ง: คงที่; ด้านบน: 0; ซ้าย: 0; ขวา: 0; z-index: 9010; 400px ความสูง: 300px ซ้าย: 50%; ขอบซ้าย: -200px; 1px solid #FFF; เคอร์เซอร์: ย้าย; z-index: 9009;}.canvas-minBox { ตำแหน่ง: สัมบูรณ์; ความสูง: 8px; : -4px; cursor: nw-resize;}.up { ด้านบน: -4px; n-resize;}.right-up { บน: -4px; ขวา: -4px; เคอร์เซอร์: ne-resize;}.right { บน: 50%; เคอร์เซอร์ขวา: -4px; -resize;}.right-down { ด้านล่าง: -4px; ขวา: -4px; เคอร์เซอร์: se-resize;}.down { ด้านล่าง: -4px; ขอบซ้าย: -4px; เคอร์เซอร์: s-resize;}.left-down { ด้านล่าง: -4px; เคอร์เซอร์: sw-resize;}.left { บน: 50%; ; ซ้าย: -4px; เคอร์เซอร์: w-resize;}.canvas-btns { ตำแหน่ง: คงที่; ขวา: 50px; ดัชนี z: 9003;}.canvas-btns { จอแสดงผล: inline-blovk; พื้นหลัง: สีเขียว; เคอร์เซอร์: ตัวชี้; ความกว้าง: 60px; ขนาดตัวอักษร: 15px;}.canvas-btns button.active { พื้นหลัง: rgb (32, 230, 32);}.canvas-btns button.close { พื้นหลัง: rgb(230, 72, 32);}.canvas-copy { ตำแหน่ง: สัมบูรณ์; ซ้าย: 50%; ขอบซ้าย: -400px; z-index: 9007;}.canvas-mosatic { ตำแหน่ง: สัมบูรณ์; ด้านบน: 50%; 50%; ระยะขอบบน: -300px; ระยะขอบซ้าย: -400px; ขอบซ้าย: -400px; z-index: 9008;}.paint-size{ ขอบด้านบน: 20px; 13px; color: #FFF; height: 30px; line-height: 30px; จอแสดงผล: อินไลน์บล็อก ความกว้าง: 15px;}.hoverClear{ เคอร์เซอร์: url('./paint.png'),auto;}.hoverPaint{ เคอร์เซอร์: url('./paint.png'),auto;}</style>
4. การเรนเดอร์มีดังนี้:
สรุปข้างต้นคือสิ่งที่โปรแกรมแก้ไขแนะนำให้คุณใช้โดยใช้ Html5 Canvas เพื่อทราบถึงฟังก์ชันการครอบตัดและโมเสก และฟังก์ชันการอัปโหลดบนคลาวด์ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใดๆ โปรดฝากข้อความถึงฉัน แล้วโปรแกรมแก้ไขจะตอบคำถามนี้ ตอบกลับคุณในเวลาของ ฉันอยากจะขอบคุณทุกคนที่ให้การสนับสนุนเว็บไซต์ศิลปะการต่อสู้ VeVb!
หากคุณคิดว่าบทความนี้มีประโยชน์สำหรับคุณ คุณสามารถพิมพ์ซ้ำได้ โปรดระบุแหล่งที่มา ขอขอบคุณ!