2009-09-20 630 views

Respuesta

20

La selección de texto tiene muchos componentes visuales, algunos no visuales.

En primer lugar, para que el texto sea seleccionable, debe mantener una matriz, dónde está el texto, qué es el texto y qué fuente se utilizó. Usará esta información con la función de Lienzo measureText.

Al usar measureText, con su cadena de texto, puede identificar a qué letra debe llegar el cursor cuando hace clic en una imagen.

ctx.fillText("My String", 100, 100); 
textWidth = ctx.measureText("My String").width; 

de todas maneras tendrá que analizar la altura de la fuente de la propiedad "fuente", ya que no está incluido actualmente en medidas del texto. El texto de lienzo está alineado con la línea de base de forma predeterminada.

Con esta información, ahora tiene un cuadro delimitador, que puede consultar. Si el cursor está dentro del cuadro delimitador, ahora tiene la desafortunada tarea de deducir qué letra fue seleccionada intencionalmente; donde debe colocarse el inicio de su cursor. Esto puede implicar llamar a measureText varias veces.

En ese punto, usted sabe a dónde debe ir el cursor; necesitarás almacenar tu cadena de texto como una cadena de texto, en una variable, por supuesto.

Una vez que haya definido los puntos de inicio y fin de su rango, debe dibujar un indicador de selección. Esto se puede hacer en una nueva capa (un segundo elemento de lienzo), o dibujando un rectángulo usando el modo de composición XOR.También se puede hacer por simplemente borrando y redibujando el texto en la parte superior de un rectángulo lleno.

Dicho todo esto, la selección de texto, la edición de texto en Canvas son bastante laboriosas de programar, y sería prudente reutilizar los componentes ya escritos, Bespin es un excelente ejemplo.

Editaré mi publicación si encuentro otros ejemplos públicos. Creo que Bespin utiliza un método de selección basado en la cuadrícula, que posiblemente requiera una fuente de espacio único. Las ligaduras, interletraje, bidireccionalidad y otras características avanzadas de representación de fuente requieren programación adicional; es un problema complejo.

+1

Sí, Bespin requiere una fuente monoespaciada. – devongovett

1

lienzo es solo una superficie de dibujo. Usted rinde y el resultado es píxeles. Por lo tanto, necesitaría rastrear las posiciones de todo el texto que haya renderizado en el lienzo en algún tipo de estructura de datos que procesaría durante los eventos del mouse.

3

Si necesita tener texto seleccionable, sería mucho más fácil crear un div o lo que sea, y colocarlo en la parte superior del lienzo donde desea que se muestre el texto.

lienzo no tiene ningún mecanismo incorporado para seleccionar texto, por lo que tendría que implementar su propio texto y seleccionar el código, lo que puede ser un poco complicado de hacer bien.

5

no se puede seleccionar el texto dibujado en elementos de lienzo debido a la naturaleza de la etiqueta canvas. Pero hay algunas soluciones, como la que se usa en typefaceJS.

Otra solución sería agregar texto con elementos div posicionados en lugar de usar strokeText o fillText.

2

Puede obtener algunas ideas de Bespin.

implementaron un editor de texto en JavaScript utilizando lienzo con la selección de texto, barras de desplazamiento, cursor parpadeante, etc.

Source Code

+0

Mientras tanto, Bespin fue reemplazado por SkyWriter, que está inactivo y [se ha fusionado en Ace] (https://mozillalabs.com/en-US/skywriter/). –

+0

El proyecto está inactivo. – Pacerier

1

Una respuesta simple sería: o bien utilizar HTML o SVG en lugar de lienzo . A menos que realmente necesite el grado de ofertas de lona de control de bajo nivel.

2

FabricJS ahora tiene la capacidad de interactuar con objetos fuera del elemento de lienzo; por ejemplo, this demo muestra un botón que está vinculado a una imagen cargada en un elemento de lienzo.

El mismo enfoque se puede usar en otras librerías como Raphael enganchando cualquier evento move, obteniendo el cuadro delimitador del elemento y reposicionando el elemento HTML.

+0

Sitio abajo .......... – Pacerier

+0

@Pacerier enlace actualizado – gbjbaanb

3

Sugeriría usar la biblioteca EaselJS, puede agregar cada letra como un niño e incluso agregar eventos de mouse a ese objeto, es una biblioteca increíble, ¡vaya a verlo!

Cuestiones relacionadas