2015-02-20 2 views
0

Я хочу, чтобы нарисовать линию на холсте срисовать плавные линии на холсте

context.globalCompositeOperation = 'destination-out'; 
context.globalAlpha = 0.118; 

Результат выглядит следующим образом:

enter image description here

Фон, если изображение представляет собой желтый прямоугольник , Я использую круг для перетаскивания его по изображению, и он будет рисовать линию. Как вы видите, моя нарисованная линия не так гладко. Вы можете видеть круги, и у вас нет составной линии.

Я создал JSFiddle here:

console.clear(); 

var history = new Array(); 

var imageObj = new Image(); 
var img = null; 

stage = new Konva.Stage({ 
    container: 'container', 
    width: 600, 
    height: 400 
}); 
layer = new Konva.Layer(); 
stage.add(layer); 

var rect = new Konva.Rect({ 
     x: 30, 
     y: 30, 
     width: 438, 
     height: 300, 
     fill: 'yellow' 
    }); 
layer.add(rect); 

var canvas = document.createElement('canvas'); 
var context = canvas.getContext('2d'); 



var circle = new Konva.Circle({ 
    x: 0, 
    y: 0, 
    radius: 40, 
    opacity: 0.7, 
    fill: '#ff5e0a', 
    stroke: '#d95009', 
    strokeWidth: 1, 
    draggable: true 
}); 
layer.add(circle); 


circle.on('dragmove touchmove', function (e) { 
    erase(e.evt.clientX, e.evt.clientY, circle.radius(), img.x(), img.y()); 
}); 


imageObj.onload = function() { 
    canvas.width = imageObj.width; 
    canvas.height = imageObj.height; 
    context.drawImage(imageObj, 0, 0, imageObj.width, imageObj.height); 

    img = new Konva.Image({ 
     x: 30, 
     y: 30, 
     image: canvas 
    }); 

    layer.add(img); 

    circle.moveToTop(); 
    layer.draw(); 
}; 

imageObj.crossOrigin = "anonymous"; 
imageObj.src = "https://dl.dropboxusercontent.com/u/47067729/darth-vader.jpg"; 


function erase(absX, absY, radius, imgX, imgY) { 
    var x = 0; 
    var y = 0; 

    // set pointer 
    circle.x(absX); 
    circle.y(absY); 

    x= absX - imgX; 
    y= absY - imgY; 

    context.globalCompositeOperation = 'destination-out'; 
    context.globalAlpha = 0.118; 
    context.beginPath(); 
    context.arc(x, y, radius, 0, 2 * Math.PI); 
    context.fill(); 

    layer.draw(); 
} 

Как я могу сделать более гладкие и сложные линии, где вы не можете увидеть каждый маленький кусок кружков?

+0

Если вы рисуете полупрозрачный диск каждый раз, когда вы получаете событие касания экрана, результат действительно будет зависеть от скорости, с которой движется палец на экране. Возможно, вы захотите интерполировать позицию последовательных событий, чтобы что плотность остается постоянной независимо от расстояния между двумя точками. –

+0

@kuroineko Как я могу это сделать? – confile

+0

Я не знаю 'Konva', но, возможно, уже есть способ сделать это автоматически с помощью этой библиотеки. Если нет, вам необходимо запомнить предыдущее положение экрана события и переместить центр вашего круга из предыдущего в текущее положение с шагом постоянной дистанции, нарисовав круг для каждого шага. –

ответ

1

Предполагая, что ваша Konva thingie не предоставляет готового решения, вам придется интерполировать позиции событий сенсорного экрана с постоянным перемещением.

Что-то вроде этого:

circle.on('dragmove touchmove', function (e) { 

    if (circle.prev_pos) { 
     var dx = e.evt.clientX - circle.prev_pos.x; 
     var dy = e.evt.clientY - circle.prev_pos.y; 
     var dist = Math.max (Math.abs(dx), Math.abs(dy)); 
     dx = dx/dist; 
     dy = dy/dist; 
     var x = circle.prev_pos.x; 
     var y = circle.prev_pos.y; 
     var d; 
     for (d = 0 ; d < dist ; d++) 
     { 
      erase(x, y, circle.radius(), img.x(), img.y()); 
      x += dx; 
      y += dy; 
     } 
    } 
    circle.prev_pos = { x:e.evt.clientX, y:e.evt.clientY}; 
}); 

См this fiddle.

+0

Что вы подразумеваете под «вам придется интерполировать позиции событий сенсорного экрана с постоянным перемещением», не могли бы вы быть более конкретными, чтобы я мог принять ваш ответ? Как '' circle.prev_pos'' переходит в '' prev.x''? – confile

+1

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

+0

Я внедрил ваш код здесь http://jsfiddle.net/confile/p9xvt76m/, но нет никакой разницы, чем моя. – confile

Смежные вопросы