Не могу нарисовать холст, используя палец в мобильных браузерах

0

Вот код:

canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
tmp_ctx = element[0].getContext('2d');

element.bind('mousemove touchmove', function(event){
                if(drawing){
                    if(event.offsetX!==undefined){
                        currentX = event.offsetX;
                        currentY = event.offsetY;
                    } else {
                        currentX = event.layerX - event.currentTarget.offsetLeft;
                        currentY = event.layerY - event.currentTarget.offsetTop;
                    }

                    if(currentTool=="karandaw" || currentTool=="lastik" || currentTool=="brush"){
                        drawPen(lastX, lastY, currentX, currentY);
                    }
                    if(currentTool=="oval"){
                        console.log("drawing ellipse");
                        drawEllipse(initX, initY, event.offsetX, event.offsetY);
                    }
                    if(currentTool=="crop"){
                        drawCrop(initX, initY, event.offsetX, event.offsetY);
                    }

                    lastX = currentX;
                    lastY = currentY;
                }
            });


function drawEllipse(x1, y1, x2, y2){
                console.log(tmp_ctx);
                tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                tmp_ctx.setLineDash([1,0]);
                tmp_ctx.beginPath();
                tmp_ctx.lineWidth = 3;
                tmp_ctx.strokeStyle = 'rgba('+curColor.r+','+curColor.g+','
                    +curColor.b+','+curColor.a+')';
                ctx.globalCompositeOperation='source-over';
                var mpx = (x1+x2)/2;
                var mpy = (y1+y2)/2;
                tmp_ctx.ellipse(mpx, mpy, Math.abs(mpx-x1), Math.abs(mpy-y1), 0, 0, Math.PI*2);
                tmp_ctx.stroke();
                tmp_ctx.closePath();
            }

Он хорошо работает в браузерах. Но на мобильных телефонах он ничего не рисует, хотя журналы показывают, что вызываются эти функции для рисования.

Есть ли ошибка?

HTML:

 <div id="canvas_container">
                        <canvas id="canvas"></canvas>
                        <canvas id="tmp_canvas" drawing></canvas>
                        <div id="canvas_area_1" ng-show="canvas_area_1"></div>
                        <div id="canvas_area_2" ng-show="canvas_area_2"></div>
                        <div id="canvas_area_3" ng-show="canvas_area_3"></div>
                    </div>

EDIT 1: версия для Chrome на мобильных устройствах - 47

EDIT 2: Я использую директиву (с угловым), чтобы сделать это. Вот полный код директивы:

app.directive("drawing", function(){
    return {
        restrict: "A",
        link: function(scope, element){
            canvas = document.getElementById("canvas");
            ctx = canvas.getContext('2d');
            tmp_ctx = element[0].getContext('2d');

            var drawing = false;
            var lastX;
            var lastY;
            var initX;
            var initY;

            //--- MOUSE EVENTS

            $(element).bind('mousedown touchstart', function(event){
                if(event.offsetX!==undefined){
                    initX = event.offsetX;
                    lastX = initX;
                    initY = event.offsetY;
                    lastY = initY;
                } else {
                    initX = event.layerX - event.currentTarget.offsetLeft;
                    initY = event.layerY - event.currentTarget.offsetTop;
                    lastX = initX;
                    lastY = initY;
                }

                if(currentTool=="karandaw" || currentTool=="lastik" || currentTool=="brush"){
                    drawPen(initX, initY, initX, initY);
                    appendDraw();
                }

                img_old = ctx.getImageData(0, 0, canvas.width, canvas.height);
                imageData = img_old;
                drawing = true;
                tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
            });

            $(element).bind('mousemove touchmove', function(event){
                if(drawing){
                    if(event.offsetX!==undefined){
                        currentX = event.offsetX;
                        currentY = event.offsetY;
                    } else {
                        currentX = event.layerX - event.currentTarget.offsetLeft;
                        currentY = event.layerY - event.currentTarget.offsetTop;
                    }

                    if(currentTool=="karandaw" || currentTool=="lastik" || currentTool=="brush"){
                        drawPen(lastX, lastY, currentX, currentY);
                    }
                    if(currentTool=="oval"){
                        console.log("drawing ellipse");
                        drawEllipse(initX, initY, event.offsetX, event.offsetY);
                    }
                    if(currentTool=="crop"){
                        drawCrop(initX, initY, event.offsetX, event.offsetY);
                    }

                    lastX = currentX;
                    lastY = currentY;
                }
            });

            $(element).bind('mouseup touchleave touchcancel', function(event){
                drawing = false;
                appendDraw();
            });

            //--- CHECK AND APPEND DRAW

            function appendDraw(){
                startedPainting = true;

                if(currentTool=="oval"){
                    drawEllipse(initX, initY, event.offsetX, event.offsetY);

                    if(drawPart=="oval_1"){
                        if(isCorrectDraw("oval_1", initX, initY, event.offsetX, event.offsetY)){
                            var mainScope = angular.element(document.getElementById("main")).scope();
                            startedPainting = false;
                            mainScope.$apply(function (){mainScope.level_3_part_17();});
                        }else{
                            tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                            return;
                        }
                    }

                    if(drawPart=="oval_2"){
                        if(isCorrectDraw("oval_2", initX, initY, event.offsetX, event.offsetY)){
                            var mainScope = angular.element(document.getElementById("main")).scope();
                            mainScope.$apply(function (){mainScope.level_3_part_14();});
                            startedPainting = false;
                        }else{
                            startedPainting = false;
                            tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                            var mainScope = angular.element(document.getElementById("main")).scope();
                            mainScope.$apply(function (){mainScope.level_3_part_12();});
                            return;
                        }
                    }

                    if(drawPart=="oval_3"){
                        if(isCorrectDraw("oval_3", initX, initY, event.offsetX, event.offsetY)){
                            var mainScope = angular.element(document.getElementById("main")).scope();
                            mainScope.$apply(function (){mainScope.level_3_part_8();});
                            startedPainting = false;
                        }else{
                            tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                            return;
                        }
                    }
                }else
                if( (currentTool=="karandaw" || currentTool=="brush") && drawPart=="pen"){
                    if(isCorrectDraw("pen")){
                        penCount++;
                        if(penCount==4){
                            var mainScope = angular.element(document.getElementById("main")).scope();
                            mainScope.$apply(function (){mainScope.level_3_part_23();});
                        }
                    }else{
                        tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                        return;
                    }

                }else
                if(currentTool=="crop"){
                    cropRight = false;
                    var mainScope = angular.element(document.getElementById("main")).scope();
                    mainScope.$apply(function (){mainScope.enableCut();});
                    return;
                }else
                if(currentTool=="cut"){
                    enableUndo();
                    return;
                }else
                if(currentTool=="paint"){
                    paintAt(event.offsetX, event.offsetY);
                    enableUndo();
                    return;
                }

                ctx.drawImage(tmp_canvas, 0, 0);
                fillTransparent();
                tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                enableUndo();
            }

            function enableUndo(){
                img_new=ctx.getImageData(0, 0, canvas.width, canvas.height);
                $("#level_3_otmenit_nazhata").css("display", "none");
            }

            //--- CHECK IF DRAWN CORRECTLY

            function isCorrectDraw(part, x1, y1, x2, y2){
                var result = true;
                if(part=="oval_3"){
                    oval_3_rx = (x1+x2)/2;
                    oval_3_ry = (y1+y2)/2;
                    oval_3_w = Math.abs(oval_3_rx-x1)*2;
                    oval_3_h = Math.abs(oval_3_ry-y1)*2;
                    if(oval_3_h>oval_3_maxH() || oval_3_w>oval_3_maxW() ||
                        oval_3_h<oval_3_minH() || oval_3_w<oval_3_minW())
                        result = false;
                }else
                if(part=="oval_2"){
                    oval_2_rx = (x1+x2)/2;
                    oval_2_ry = (y1+y2)/2;
                    oval_2_w = Math.abs(oval_2_rx-x1)*2;
                    oval_2_h = Math.abs(oval_2_ry-y1)*2;
                    if(oval_2_h>oval_2_maxH() || oval_2_w>oval_2_maxW() ||
                        oval_2_h<oval_2_minH() || oval_2_w<oval_2_minW() || !isAllowedShift(oval_2_rx, oval_3_rx))
                        result = false;
                }else
                if(part=="oval_1"){
                    oval_1_rx = (x1+x2)/2;
                    oval_1_ry = (y1+y2)/2;
                    oval_1_w = Math.abs(oval_1_rx-x1)*2;
                    oval_1_h = Math.abs(oval_1_ry-y1)*2;
                    if(oval_1_h>oval_1_maxH() || oval_1_w>oval_1_maxW() ||
                        oval_1_h<oval_1_minH() || oval_1_w<oval_1_minW() || !isAllowedShift(oval_1_rx, oval_3_rx))
                        result = false;
                }else
                if(part=="pen"){
                    var xshift = (oval_1_h>oval_1_w)? oval_1_h : oval_1_w;

                    if(Math.abs(oval_1_rx-lastX)>xshift || lastY>oval_1_ry )
                        result = false;
                }
                return result;
            }

            function isPointInEllipse(x, y, rx, ry, h, k){
                var a = (x-h)*(x-h);
                var b = (y-k)*(y-k);
                var c = rx*rx;
                var d = ry*ry;
                if( (a/c +  b/d) <=1)
                    return true;
                return false;
            }

            //--- DRAWING FUNCTIONS

            function fillTransparent(){
                var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
                var pix = imgd.data;

                for (var i = 0, n = pix.length; i < n; i += 4) {
                    if(pix[i]==0 && pix[i+1]==0 && pix[i+2]==0 && pix[i+3]==0){
                        pix[i] = 255;
                        pix[i+1] = 255;
                        pix[i+2] = 255;
                        pix[i+3] = 255;
                    }
                }
                ctx.putImageData(imgd, 0, 0);
            }

            function drawPen(x1, y1, x2, y2){
                tmp_ctx.lineCap = "round";
                tmp_ctx.lineJoin = "round";
                tmp_ctx.setLineDash([1,0]);
                tmp_ctx.beginPath();
                tmp_ctx.lineWidth = currentTool=="karandaw" ? 5 : 10;
                if(currentTool=="lastik"){
                    ctx.globalCompositeOperation='destination-out';
                    tmp_ctx.strokeStyle = "white";
                }else{
                    ctx.globalCompositeOperation='source-over';
                    tmp_ctx.strokeStyle = 'rgba('+curColor.r+','+curColor.g+','
                        +curColor.b+','+curColor.a+')';
                }

                if(x1==x2 && y1==y2)
                    x1++;

                tmp_ctx.moveTo(x1,y1);
                tmp_ctx.lineTo(x2,y2);
                tmp_ctx.stroke();
                tmp_ctx.closePath();
            }

            function drawEllipse(x1, y1, x2, y2){
                console.log(tmp_ctx);
                tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                tmp_ctx.setLineDash([1,0]);
                tmp_ctx.beginPath();
                tmp_ctx.lineWidth = 3;
                tmp_ctx.strokeStyle = 'rgba('+curColor.r+','+curColor.g+','
                    +curColor.b+','+curColor.a+')';
                ctx.globalCompositeOperation='source-over';
                var mpx = (x1+x2)/2;
                var mpy = (y1+y2)/2;
                tmp_ctx.ellipse(mpx, mpy, Math.abs(mpx-x1), Math.abs(mpy-y1), 0, 0, Math.PI*2);
                tmp_ctx.stroke();
                tmp_ctx.closePath();
            }

            function drawCrop(x1, y1, x2, y2){
                cutX = Math.min(x1, x2); cutY = Math.min(y1, y2); cutW = Math.abs(x2-x1); cutH = Math.abs(y2-y1);
                tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
                tmp_ctx.setLineDash([10]);
                tmp_ctx.beginPath();
                tmp_ctx.lineWidth = 1;
                tmp_ctx.strokeStyle = "rgba(0,0,0,1)";
                ctx.globalCompositeOperation='source-over';
                tmp_ctx.rect(cutX, cutY, cutW, cutH);
                tmp_ctx.stroke();
                tmp_ctx.closePath();
            }

            //---PAINT BUCKET

            function paintAt(startX, startY){
                imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

                var pixelPos = (startY * canvas.width + startX) * 4,
                    r = imageData.data[pixelPos],
                    g = imageData.data[pixelPos + 1],
                    b = imageData.data[pixelPos + 2],
                    a = imageData.data[pixelPos + 3];

                if (r === curColor.r && g === curColor.g && b === curColor.b && a === curColor.a){
                    return;
                }

                floodFill(startX, startY, r, g, b, a);

                clear_ctx(0, 0, canvas.width, canvas.height);
                ctx.putImageData(imageData, 0, 0);
            }

            function matchStartColor(pixelPos, startR, startG, startB, startA){
                var r = imageData.data[pixelPos],
                    g = imageData.data[pixelPos + 1],
                    b = imageData.data[pixelPos + 2],
                    a = imageData.data[pixelPos + 3];

                if (r === startR && g === startG && b === startB && a === startA)
                    return true;

                if (r === curColor.r && g === curColor.g && b === curColor.b && a === curColor.a)
                    return false;

                return false;
            }

            function colorPixel(pixelPos){
                imageData.data[pixelPos] = curColor.r;
                imageData.data[pixelPos + 1] = curColor.g;
                imageData.data[pixelPos + 2] = curColor.b;
                imageData.data[pixelPos + 3] = 255;
            }

            function floodFill(startX, startY, startR, startG, startB, startA){
                var newPos, x, y, pixelPos, reachLeft, reachRight,
                    drawingBoundTop = 0,
                    pixelStack = [[startX, startY]];

                while (pixelStack.length){
                    newPos = pixelStack.pop();
                    x = newPos[0];
                    y = newPos[1];

                    pixelPos = (y * canvas.width + x) * 4;

                    while(y-- >= drawingBoundTop && matchStartColor(pixelPos, startR, startG, startB, startA))
                        pixelPos -= canvas.width * 4;

                    pixelPos += canvas.width * 4;
                    y += 1;
                    reachLeft = false;
                    reachRight = false;

                    while (y++ < canvas.height-1 && matchStartColor(pixelPos, startR, startG, startB, startA)){
                        colorPixel(pixelPos);

                        if (x > 0){
                            if (matchStartColor(pixelPos - 4, startR, startG, startB, startA)){
                                if (!reachLeft){
                                    pixelStack.push([x - 1, y]);
                                    reachLeft = true;
                                }
                            } else if (reachLeft){
                                reachLeft = false;
                            }
                        }
                        if (x < canvas.width-1){
                            if (matchStartColor(pixelPos + 4, startR, startG, startB, startA)){
                                if (!reachRight){
                                    pixelStack.push([x + 1, y]);
                                    reachRight = true;
                                }
                            } else if (reachRight){
                                reachRight = false;
                            }
                        }

                        pixelPos += canvas.width * 4;
                    }
                }
            }//floodFill
        }
    };
});
  • 0
    Вы используете JQuery? Я уверен, что bind (), который вам нужен, это jquery.bind, а не javascript native [object] .bind ();
Теги:
canvas

1 ответ

0

Я думаю, что bind(), что вы имели в виду, это jquery.bind(), вместо этого собственный javascript.bind();

если вы идете по чистому маршруту javascript, попробуйте использовать addEventListener.

function moveHandler(event){
    if(drawing){
       if(event.offsetX!==undefined){
           currentX = event.offsetX;
           //.... next code
       }         
    }
}
element.addEventListener('touchmove', moveHandler);
element.addEventListener('mousemove', moveHandler);

instead of $(element).bind
  • 0
    Я попытался сделать $ (элемент) .bind. Не помогло Извините, не могли бы вы посмотреть РЕДАКТИРОВАТЬ 2 вопроса. Есть полный код
  • 0
    извините, я не знаком с angular, я сомневаюсь, что директива $ in действительно означает jquery .. также они используют jqLite вместо обычного jquery .. вы можете попробовать добавитьEventListener к элементу .. element.addEventListener ('')

Ещё вопросы

Сообщество Overcoder
Наверх
Меню