溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

canvas怎樣實(shí)現(xiàn)自定義頭像功能

發(fā)布時(shí)間:2020-07-13 11:46:54 來(lái)源:億速云 閱讀:279 作者:Leah 欄目:web開(kāi)發(fā)

本篇文章給大家分享的是有關(guān)canvas怎樣實(shí)現(xiàn)自定義頭像功能,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

寫(xiě)在最前:

前兩天老大跟我說(shuō)老虎官網(wǎng)上那個(gè)自定義頭像的功能是flash實(shí)現(xiàn)的,沒(méi)有安裝過(guò)的還得手動(dòng)去“允許”falsh的運(yùn)行。所以讓我用canvas實(shí)現(xiàn)一個(gè)一樣的功能,嘿嘿,剛好最近也在研究canvas,所以欣然答應(yīng)(其實(shí),你沒(méi)研究過(guò)難道就不答應(yīng)么,哈哈哈哈哈~)

成果展示:

canvas怎樣實(shí)現(xiàn)自定義頭像功能

Git地址:https://github.com/ry928330/portraitDIY

功能說(shuō)明:

  • 拖拽左側(cè)小方框,或者是鼠標(biāo)放在小方框右下角,點(diǎn)擊拉伸方框,方框覆蓋部分的圖片被自動(dòng)截取下來(lái),然后再在右側(cè)的多個(gè)容器里面重繪。

  • 輸入寬高,自定義你需要訂制的頭像大小,目前只支持寬高相同的頭像圖片。

實(shí)現(xiàn)細(xì)節(jié):

因?yàn)槟阋獙?duì)圖片所在的區(qū)域進(jìn)行截圖,所以你得制作一張canvas,蓋在圖片所在的區(qū)域。這里,我們給出了一個(gè)函數(shù),根據(jù)傳入的DOM里面元素的類名創(chuàng)建相同位置的canvas,蓋在原來(lái)的DOM元素上面:

function createCanvasByClassName(tag) {
    var canvasInitialWidth = $('.' + tag).width();
    var canvasInitialHeight = $('.' + tag).height();
    var left = $('.' + tag).offset().left - $('.' + tag).parent('.portraitContainer').offset().left + 1;
    var top = $('.' + tag).offset().top - $('.' + tag).parent('.portraitContainer').offset().top + 1;
    //var left = $('.' + tag).offset().left + 1;
    //var top = $('.' + tag).offset().top + 1;
    clearCanvasObj.left = $('.' + tag).offset().left + 1;
    clearCanvasObj.top = $('.' + tag).offset().top + 1;
    // clearCanvasObj.left = left;
    // clearCanvasObj.top = top;
    var canvasElement = $('<canvas></canvas>');
    var randomNum = Math.floor(getRandom(0, 10000));
    clearCanvasObj.canvasId = randomNum;
    canvasElement.attr({
        id: 'canvas',
        width: canvasInitialWidth,
        height: canvasInitialHeight
    });
    canvasElement.css({
        position: 'absolute',
        top: top, 
        left: left
    });
    //$('body').append(canvasElement);
    var appendEle = $('.portraitContainer').append(canvasElement);
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    //ctx.fillStyle = "rgba(211,211,216,0.5)";
    ctx.clearRect(0, 0, canvasInitialWidth, canvasInitialHeight);
    ctx.fillStyle = "rgba(0,0,0, 0.4)";
    ctx.fillRect(0, 0, canvasInitialWidth, canvasInitialHeight);
    return canvas;
}

有了這張canvas你就可以在你圖片所在區(qū)域肆意的操作了。首先,降整個(gè)區(qū)域畫(huà)上一個(gè)淺黑色的陰影,然后再擦除初始小方框區(qū)域里面的顏色。然后給整個(gè)頁(yè)面添加mousedown,mousemove,mouseup事件,他們所做的功能就跟你在頁(yè)面中實(shí)現(xiàn)一個(gè)拖拽的功能類似,這里重點(diǎn)說(shuō)下mousemove里面做的操作,代碼如下:

function mousemoveFunc(event) {
    /* Act on the event */
    var nowMouseX = event.clientX - clearCanvasObj.left;
    var nowMouseY = event.clientY - clearCanvasObj.top;
    if (nowMouseX >= clearCanvasObj.xStart && nowMouseX <= clearCanvasObj.xStart + clearCanvasObj.width && nowMouseY >= clearCanvasObj.yStart && nowMouseY <= clearCanvasObj.yStart + clearCanvasObj.height) {
        clearCanvasObj.isCanvasArea = true;
        //clearCanvasObj.isRightCorner = false;
        imgContainerCanvas.style.cursor = 'move';
    } else if ((nowMouseX >= clearCanvasObj.xStart + clearCanvasObj.width - 10) && (nowMouseX <= clearCanvasObj.xStart+ clearCanvasObj.width + 10) 
        && (nowMouseY >= clearCanvasObj.yStart + clearCanvasObj.height - 10) && (nowMouseY <= clearCanvasObj.yStart + clearCanvasObj.height + 10)) {
        clearCanvasObj.isCanvasArea = true;
        //clearCanvasObj.beginDraw = false;
        imgContainerCanvas.style.cursor = 'se-resize';
    } 
    else {
        clearCanvasObj.isCanvasArea = false;
        //clearCanvasObj.isRightCorner = false;
        imgContainerCanvas.style.cursor = 'default';
    }
    var outerDomWidth = $(".imgContainer").width();
    var outerDomHeight = $(".imgContainer").height();
    var xDistance = event.clientX - clearCanvasObj.mouseX;
    var yDistance = event.clientY - clearCanvasObj.mouseY;
    //var outerCTX = canvas.getContext('2d');
    //移動(dòng)小方框
    if (clearCanvasObj.beginDraw && clearCanvasObj.isCanvasArea && !clearCanvasObj.isRightCorner) {
        ry_CTX.fillStyle = clearCanvasObj.color;
        // console.log('1', clearCanvasObj.xStart, clearCanvasObj.yStart)
        ry_CTX.fillRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
        //outerCTX.fillRect(0, 0, canvas.width, canvas.height);
        clearCanvasObj.xStart += xDistance;
        clearCanvasObj.yStart += yDistance;
        //判斷方框是否達(dá)到邊界
        if (clearCanvasObj.xStart <= 0) {
            clearCanvasObj.xStart = 0;
        }
        if (clearCanvasObj.yStart <= 0) {
            clearCanvasObj.yStart = 0;
        }
        if ((clearCanvasObj.xStart + clearCanvasObj.width) >= outerDomWidth) {
            clearCanvasObj.xStart = outerDomWidth - clearCanvasObj.width;
        }
        if ((clearCanvasObj.yStart + clearCanvasObj.height) >= outerDomHeight) {
            clearCanvasObj.yStart = outerDomHeight - clearCanvasObj.height;
        }
        // console.log('2', clearCanvasObj.xStart, clearCanvasObj.yStart)
        ry_CTX.clearRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
        produceSmallPic(clearCanvasObj.xStart+clearCanvasObj.left, clearCanvasObj.yStart+clearCanvasObj.top, clearCanvasObj.width, clearCanvasObj.height, imageURL)
        clearCanvasObj.mouseX = event.clientX;
        clearCanvasObj.mouseY = event.clientY;
    }
    //拖拽小方框
    if (clearCanvasObj.isRightCorner) {
        ry_CTX.fillStyle = clearCanvasObj.color;
        ry_CTX.fillRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
        var realDistance = Math.min(xDistance, yDistance)
        clearCanvasObj.width +=  realDistance;
        clearCanvasObj.height += realDistance;
        //拖動(dòng)時(shí)邊界條件的判斷
        if (clearCanvasObj.xStart + clearCanvasObj.width >= outerDomWidth) {
            clearCanvasObj.width = outerDomWidth - clearCanvasObj.xStart;
            clearCanvasObj.height = outerDomWidth - clearCanvasObj.xStart;
        }
        if (clearCanvasObj.yStart + clearCanvasObj.height >= outerDomHeight) {
            clearCanvasObj.width = outerDomHeight - clearCanvasObj.yStart;
            clearCanvasObj.height = outerDomHeight - clearCanvasObj.yStart;
        }
        if (clearCanvasObj.width <= 10) {
            clearCanvasObj.width = 10;
        }
        if (clearCanvasObj.height <= 10) {
            clearCanvasObj.height = 10;
        }
        ry_CTX.clearRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
        produceSmallPic(clearCanvasObj.xStart+clearCanvasObj.left, clearCanvasObj.yStart+clearCanvasObj.top, clearCanvasObj.width, clearCanvasObj.height, imageURL);
        clearCanvasObj.mouseX = event.clientX;
        clearCanvasObj.mouseY = event.clientY;
    }                            
}

函數(shù)里面,你需要注意拖拽的邊界條件,一個(gè)是方框不能拖到圖片所在DOM外的邊界;另外一個(gè)就是當(dāng)你鼠標(biāo)放在小方框所在的區(qū)域改變鼠標(biāo)的樣式。方框在拖動(dòng)的過(guò)程中,我們不斷重繪方框移動(dòng)的區(qū)域(也就是不斷的畫(huà)上陰影),然后在新的位置調(diào)用clearRect函數(shù),重新擦出一個(gè)小方框出來(lái)。在拖拽或是拉伸的過(guò)程中,我們會(huì)不斷調(diào)用produceSmallPic函數(shù),在右邊的容器(每個(gè)容器都是一個(gè)canvas)里面不斷根據(jù)容器大小重繪出所需的頭像。代碼如下:

function produceSmallPic(imageURL,left, top, width, height) {
    var img = new Image();
    img.src = imageURL;
    var targetCtx = new Array();
    var targetCanvas = null;
    img.onload = function() {
        portraitGroupsArr.forEach(function(item, index) {
            targetCanvas = document.getElementById(item.class);
            targetCtx.push(targetCanvas.getContext('2d'));
            targetCtx[index].clearRect(0,0, item.width, item.height);
            targetCtx[index].drawImage(img, left - clearCanvasObj.left, top - clearCanvasObj.top, width, height, 0, 0 , item.width, item.height);
        })
    }
}

我們說(shuō)下這個(gè)函數(shù)的作用,這里我們要注意一個(gè)參數(shù)imageURL,這個(gè)URL是由圖片所在的DOM轉(zhuǎn)化來(lái)的。因?yàn)槟阋袲OM所在的區(qū)域變成一張圖片,這樣你才能在利用drawImage函數(shù)截取你所需要的區(qū)域。所以我們先利用html2canvas庫(kù)函數(shù)講圖片所在的DOM轉(zhuǎn)化為canvas,這張canvas的內(nèi)容是包含你所要截取的圖片的,然后把這張canvas轉(zhuǎn)化為圖片取得圖片地址imageURL,代碼如下:

html2canvas(document.getElementById('imgContainer'), {
        onrendered: function(canvas) {
            var imageURL = canvasTransToImage(canavs);
            ...
        }
})
function canvasTransToImage(canvas) {
    var imageURL = canvas.toDataURL('image/png');
    return imageURL;
}

接著,你就可以便利右側(cè)的canvas容器,講圖片重回到里面了,整個(gè)過(guò)程就這樣結(jié)束,回頭看來(lái)是不是很簡(jiǎn)單。

以上就是canvas怎樣實(shí)現(xiàn)自定義頭像功能,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI