canvas大图拆分成拼图碎片

原图
在这里插入图片描述
需要准备对应的碎片空白png图用于拆分拼图碎片
在这里插入图片描述

拆分后的9张图
在这里插入图片描述

var cutPicture = [ //对应碎片的起始坐标和宽高(实际根据自己业务需求调整,这里只举例9宫格)
    { x: 0, y: 0, w: 200, h: 200 },
    { x: 200, y: 0, w: 200, h: 200 },
    { x: 400, y: 0, w: 200, h: 200 },
    { x: 0, y: 200, w: 200, h: 200 },
    { x: 200, y: 200, w: 200, h: 200 },
    { x: 400, y: 200, w: 200, h: 200 },
    { x: 0, y: 400, w: 200, h: 200 },
    { x: 200, y: 400, w: 200, h: 200 },
    { x: 400, y: 400, w: 200, h: 200 }
]
var isShowCard = false // 是否执行中
var cardList = [] //拆分后的图片url

function initCanvas() {
    if (isShowCard) {
        return
    }
    isShowCard = true
    cardList = []
    let arr = []
    for (let i = 0; i < cutPicture.length; i++) {
        let promise = new Promise((resolve, reject) => {
            let row = cutPicture[i]
            const canvas = document.createElement('canvas');
            // 大图的绘画容器(实际根据业务需求调整)
            canvas.width = 600;
            canvas.height = 600;
            const ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const image = new Image();
            image.src = ''//需要拆分的大图url
            image.crossOrigin = 'anonymous'
            image.onload = () => {
                ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
                ctx.globalCompositeOperation = 'destination-in'

                let img = new Image()
                img.src = `${i+1}.png`//对应碎片位置的图片url
                img.crossOrigin = 'anonymous'
                img.onload = () => {
                    ctx.drawImage(img, row.x, row.y, row.w, row.h)
                    const fragmentCanvas = document.createElement('canvas');
                    fragmentCanvas.width = row.w
                    fragmentCanvas.height = row.h
                    const fragmentCtx = fragmentCanvas.getContext('2d');
                    // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
                    // image: 图像元素
                    // sx,sy: 图像截取区域的起始坐标(左上角顶点坐标)
                    // sw,sh: 图像截取区域的宽高
                    // dx,dy: 绘制图像区域在画布上的位置(截取后的内容,放入到另一个canvas中绘制的起始坐标)
                    // dw,dh: 绘制图像区域的宽高
                    fragmentCtx.drawImage(canvas, row.x, row.y, row.w, row.h, 0, 0, row.w, row.h);
                    let base64Img = fragmentCtx.canvas.toDataURL('image/png')
                    // 将base64上传到服务器 (如果需要上传服务器)
                    // const formData = new FormData()
                    // let blob = dataURLtoFile(base64Img, 'image/png');
                    // formData.append('file', new File([blob], new Date() + '.png'))
                    // uploadImageAjax(formData).then(res => {
                    //     cardList[i] = { url: res.data, index: i + 1 }
                    //     resolve()
                    // }).catch(err => {
                    //     reject()
                    // })
                    cardList[i] = { url: base64Img, index: i + 1 }
                    resolve()
                }
                img.onerror = () => {
                    reject()
                }
            }
            image.onerror = () => {
                reject()
            }
        })
        arr.push(promise)
    }
    return new Promise((resolve, reject) => {
        Promise.all(arr).then(() => {
            isShowCard = false
            console.log(cardList)
            resolve()
        }).catch(() => {
            isShowCard = false
            console.log('图片分割失败,请重试!')
            reject()
        })
    })
}
// 将base64转换为blob
function dataURLtoFile(dataURI, type) {
    let binary = atob(dataURI.split(',')[1]);
    let array = [];
    for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], { type: type });
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值