首頁 > web前端 > H5教程 > 怎麼用canvas實作自訂頭像功能

怎麼用canvas實作自訂頭像功能

php中世界最好的语言
發布: 2018-03-27 11:39:36
原創
3595 人瀏覽過

這次帶給大家怎麼用canvas實作自訂頭像功能,用canvas實作自訂頭像功能的注意事項有哪些,以下就是實戰案例,一起來看一下。

寫在最前面:

前兩天老大跟我說老虎官網上那個自訂頭像的功能是flash實現的,沒有安裝過的還得手動去「允許」falsh的運作。所以讓我用canvas實現一個一樣的功能,嘿嘿,剛好最近也在研究canvas,所以欣然答應(其實,你沒研究過難道就不答應麼,哈哈哈哈哈~)

成果展示:

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

功能說明:

  • 拖曳左側小方塊,或是滑鼠放在小方塊右下角,點擊拉伸方框,方框覆蓋部分的圖片被自動截取下來,然後再在右側的多個容器裡面重繪。

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

實作細節:

因為你要對圖片所在的區域進行截圖,所以你得製作一張canvas,蓋在圖片所在的區域。這裡,我們給了一個函數,根據傳入的DOM裡面元素的類別名稱創建相同位置的canvas,蓋在原來的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你就可以在你圖片所在區域肆意的操作了。首先,降整個區域畫上一個淺黑色的陰影,然後再擦除初始小方框區域裡面的顏色。然後給整個頁面添加mousedown,mousemove,mouseup事件,他們所做的功能就跟你在頁面中實現一個拖曳的功能類似,這裡重點說下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 = &#39;move&#39;;
    } 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 = &#39;se-resize&#39;;
    } 
    else {
        clearCanvasObj.isCanvasArea = false;
        //clearCanvasObj.isRightCorner = false;
        imgContainerCanvas.style.cursor = &#39;default&#39;;
    }
    var outerDomWidth = $(".imgContainer").width();
    var outerDomHeight = $(".imgContainer").height();
    var xDistance = event.clientX - clearCanvasObj.mouseX;
    var yDistance = event.clientY - clearCanvasObj.mouseY;
    //var outerCTX = canvas.getContext(&#39;2d&#39;);
    //移动小方框
    if (clearCanvasObj.beginDraw && clearCanvasObj.isCanvasArea && !clearCanvasObj.isRightCorner) {
        ry_CTX.fillStyle = clearCanvasObj.color;
        // console.log(&#39;1&#39;, 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;
        //判断方框是否达到边界
        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;
        //拖动时边界条件的判断
        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;
    }                            
}
登入後複製

函數裡面,你需要注意拖曳的邊界條件,一個是方框不能拖到圖片所在DOM外的邊界;另外一個就是當你滑鼠放在小方框所在的區域改變滑鼠的樣式。方框在拖曳的過程中,我們不斷重繪方框移動的區域(也就是不斷的畫上陰影),然後在新的位置呼叫clearRect函數,重新擦出一個小方框出來。在拖曳或是拉伸的過程中,我們會不斷呼叫produceSmallPic函數,在右邊的容器(每個容器都是一個canvas)裡面不斷根據容器大小重繪出所需的頭像。程式碼如下:

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);
        })
    }
}
登入後複製

我們說下這個函數的作用,這裡我們要注意一個參數imageURL,這個URL是由圖片所在的DOM轉換來的。因為你要把DOM所在的區域變成一張圖片,這樣你才能在利用drawImage函數截取你所需要的區域。所以我們先利用html2canvas函式庫函數講圖片所在的DOM轉換成canvas,這張canvas的內容是包含你所要截取的圖片的,然後把這張canvas轉換成圖片取得圖片地址imageURL,程式碼如下:

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

接著,你就可以方便右邊的canvas容器,講圖片重回裡面了,整個過程就這樣結束,回頭看來是不是很簡單。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

H5在Canvas中實作自訂路徑動畫

在H5頁面中怎麼呼叫APP

以上是怎麼用canvas實作自訂頭像功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板