2010-08-19 13 views
8

Tengo un lienzo con algunos dibujos de formas irregulares y me gustaría recibir un comentario cuando alguien hace clic en uno específico?lienzo html5 haciendo clic en Bezier detección de forma de camino

He estado buscando en todas partes esto y solo he encontrado soluciones para rectangle.

Creo que puede tener que ver con isPointInPath(), pero aún no he encontrado una explicación concisa sobre cómo usarlo.

Cualquier ayuda de bienvenida.

Respuesta

13

Realicé un tutorial que utiliza un segundo lienzo invisible para realizar la selección de objeto/prueba de golpe. Dibuja todas tus formas, una por una, en el segundo lienzo hasta que una de ellas tenga un píxel negro donde esté la ubicación del mouse. ¡Entonces has encontrado tu objeto!

Aquí hay un poco del tutorial que escribí en la selección de objetos con una lona:

// gctx is ghost context, made from the second canvas 
    // clear(gctx) 

    // ... 

    // run through all the boxes 
    var l = boxes.length; 
    for (var i = l-1; i >= 0; i--) { 
    // draw shape onto ghost context 
    drawshape(gctx, boxes[i], 'black', 'black'); 

    // get image data at the mouse x,y pixel 
    var imageData = gctx.getImageData(mx, my, 1, 1); 
    var index = (mx + my * imageData.width) * 4; 

    // if the mouse pixel exists, select and break 
    if (imageData.data[3] > 0) { 
     mySel = boxes[i]; 
     offsetx = mx - mySel.x; 
     offsety = my - mySel.y; 
     mySel.x = mx - offsetx; 
     mySel.y = my - offsety; 
     isDrag = true; 
     canvas.onmousemove = myMove; 
     invalidate(); 
     clear(gctx); 
     return; 
    } 

    } 

mi demo completo solamente utiliza rectángulos, pero en una versión posterior que va a utilizar círculos/caminos/texto.

Si quiere ver la demostración y mi código completo es here.

+0

Gracias. Finalmente hice algo similar, aunque me quedé en el lienzo de salvar, sin hacer ningún trazo o relleno mientras volvía a dibujar las formas. – Brousselaine

+0

@Simon Sarris He usado su tutorial para hacer esto: http://edumax.org.ro/extra/new/mindmap/ (use la cuadrícula como mapa y haga clic con el botón secundario para ver el menú) Estoy tratando de hacer rutas seleccionables también mediante el uso de tu método Tengo entendido que tiene un tutorial sobre este tema, pero, ¿hay alguna manera de darnos una pista sobre algunos pasos básicos que seguirá? (específicamente para la función .contains() de ruta) –

+0

Lo siento, casi todo mi tiempo libre en este momento lo paso escribiendo un libro, volveré a la serie de tutoriales web probablemente hacia fines de este año. Hacer rutas seleccionables se puede hacer con la función 'isPointInPath' del contexto, pero debe guardar todos los pasos necesarios para realizar cada ruta y cargar la ruta actual del contexto cada vez que necesite realizar una prueba. –

0

Puede usar un patitero, que convierte todas las formas en polígonos aproximados. Luego usa un algoritmo de 'punto en el polígono' para verificar si el punto tiene forma.

0

Esto se puede lograr utilizando Path2D.

var div = document.getElementById("result"); 
 
var canvas = document.getElementById("canvas"); 
 

 
var ctx = canvas.getContext("2d"); 
 

 
var path1 = new Path2D(); 
 
path1.rect(10, 10, 100, 100); 
 
path1.closePath(); 
 
ctx.stroke(path1); 
 

 
var path2 = new Path2D(); 
 
path2.moveTo(220, 60); 
 
path2.arc(170, 60, 50, 0, 2 * Math.PI); 
 
path2.closePath(); 
 
ctx.stroke(path2); 
 

 
var path3 = new Path2D("M230 10 h 80 v 80 h -80 Z"); 
 
ctx.fill(path3); 
 
path3.closePath(); 
 

 
$('canvas').click(function(event) 
 
{ 
 
    div.innerHTML = ""; 
 
    
 
    var x = event.pageX; 
 
    var y = event.pageY; 
 

 
    if (ctx.isPointInPath(path1, x, y)) 
 
    div.innerHTML = "Path1 clicked"; 
 

 
    if (ctx.isPointInPath(path2, x, y)) 
 
    div.innerHTML = "Path2 clicked"; 
 
    
 
    if (ctx.isPointInPath(path3, x, y)) 
 
    div.innerHTML = "Path3 clicked"; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<body> 
 
    <canvas id="canvas"></canvas> 
 
    <div id="result"></div> 
 
</body>