>  기사  >  웹 프론트엔드  >  캔버스를 사용하여 맞춤형 아바타 기능을 구현하는 방법

캔버스를 사용하여 맞춤형 아바타 기능을 구현하는 방법

php中世界最好的语言
php中世界最好的语言원래의
2018-03-27 11:39:363483검색

이번에는 캔버스를 사용하여 커스텀 아바타 기능을 구현하는 방법과, 캔버스를 사용하여 커스텀 아바타 기능을 구현할 때 어떤 노트가 있는지 알아보겠습니다.

앞에 적음:

이틀 전 사장님께서 타이거 공식 홈페이지의 커스텀 아바타 기능이 플래시로 구현되어 있다고 하더군요. 플래시가 설치되어 있지 않다면 수동으로 "허용"해야 한다고 하더군요. 실행하려면 플래시를 사용하세요. 그래서 같은 기능을 구현하려면 캔버스를 이용하라고 하더군요 ㅎㅎ 최근에 우연히 캔버스 공부를 하게 되어서 흔쾌히 동의했습니다.(사실 공부 안해보신 분들도 동의하시겠죠 ㅎㅎㅎ하하~)

결과 표시:

Git 주소:https://github.com/ry928330/portraitDIY

기능 설명:

  • 왼쪽의 작은 상자를 드래그하세요. , 또는 장소 작은 상자에 마우스를 놓고 오른쪽 하단의 늘이기 상자를 클릭하면 상자에 가려진 이미지가 자동으로 가로채어 오른쪽의 여러 컨테이너에 다시 그려집니다.

  • 너비와 높이를 입력하여 필요한 아바타 크기를 맞춤설정하세요. 현재는 너비와 높이가 동일한 아바타 이미지만 지원됩니다.

구현 세부 사항:

사진이 있는 영역을 스크린샷으로 찍고 싶으므로, 사진이 있는 영역을 덮을 캔버스를 만들어야 합니다. 여기에서는 전달된 DOM에 있는 요소의 클래스 이름을 기반으로 동일한 위치에 캔버스를 생성하고 원래 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;
}

이 캔버스를 사용하면 무엇이든 할 수 있습니다. 당신은 당신의 사진이 있는 지역에서 원합니다. 먼저 전체 영역을 연한 검정색 그림자로 칠한 다음 초기의 작은 상자 영역 내부의 색상을 지웁니다. 그런 다음 전체 페이지에 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 함수를 호출하여 작은 상자를 다시 지웁니다. 드래그 또는 늘이기 프로세스 동안 우리는 계속해서 producerSmallPic 함수를 호출하여 오른쪽 컨테이너(각 컨테이너는 캔버스)에 컨테이너 크기에 따라 필요한 아바타를 계속해서 다시 그립니다. 코드는 다음과 같습니다.

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을 캔버스로 변환합니다. 이 캔버스의 내용에는 가로채고 싶은 그림이 포함되어 있으며, 그런 다음 이 캔버스를 그림으로 변환하여 그림 주소 imageURL을 얻습니다.

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

다음으로 오른쪽의 캔버스 컨테이너를 활성화하고 이미지를 반환하면 전체 과정이 이렇게 끝납니다.

이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

H5는 캔버스에서 사용자 정의 경로 애니메이션을 구현합니다

H5 페이지에서 APP를 호출하는 방법

위 내용은 캔버스를 사용하여 맞춤형 아바타 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.