这是代码:
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();
}
它在 PC 浏览器上运行良好。但是在手机上它什么都没有画,虽然日志显示那些绘图函数被调用了。
有什么错误吗?
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>
编辑 1:移动设备上的 Chrome 版本是 47
编辑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
}
};
});