rectangulo mdn lineas figuras examples ejemplos dibujar create coordenadas javascript css html5 canvas letter-spacing

javascript - mdn - Espaciado entre letras en el elemento canvas



dibujar lineas en canvas javascript (9)

Aquí hay un coffeescript que le permite establecer kerning a su contexto como tal

tctx = tcanv.getContext(''2d'') tctx.kerning = 10 tctx.fillStyle = ''black'' tctx.fillText ''Hello World!'', 10, 10

el código de soporte es:

_fillText = CanvasRenderingContext2D::fillText CanvasRenderingContext2D::fillText = (str, x, y, args...) -> # no kerning? default behavior return _fillText.apply this, arguments unless @kerning? # we need to remember some stuff as we loop offset = 0 _.each str, (letter) => _fillText.apply this, [ letter x + offset + @kerning y ].concat args # in case any additional args get sent to fillText at any time offset += @measureText(letter).width + @kerning

El javascript sería

var _fillText, __slice = [].slice; _fillText = CanvasRenderingContext2D.prototype.fillText; CanvasRenderingContext2D.prototype.fillText = function() { var args, offset, str, x, y, _this = this; str = arguments[0], x = arguments[1], y = arguments[2], args = 4 <= arguments.length ? __slice.call(arguments, 3) : []; if (this.kerning == null) { return _fillText.apply(this, arguments); } offset = 0; return _.each(str, function(letter) { _fillText.apply(_this, [letter, x + offset + _this.kerning, y].concat(args)); offset += _this.measureText(letter).width + _this.kerning; }); };

La pregunta lo dice todo. He estado buscando y comenzando a preocuparme de que sea imposible.

Tengo este elemento canvas al que estoy dibujando texto. Quiero establecer el espaciado entre letras similar al atributo de letter-spacing CSS. Con eso me refiero a aumentar la cantidad de píxeles entre letras cuando se dibuja una cuerda.

Mi código para dibujar el texto es así, ctx es la variable de contexto canvas.

ctx.font = "3em sheepsans"; ctx.textBaseline = "middle"; ctx.textAlign = "center"; ctx.fillStyle = "rgb(255, 255, 255)"; ctx.fillText("Blah blah text", 1024 / 2, 768 / 2);

He intentado agregar ctx.letterSpacing = "2px"; antes del sorteo, pero sin resultado. ¿Hay alguna manera de hacer esto solo con una configuración simple, o tendré que hacer una función para dibujar individualmente cada personaje con el espaciado en mente?


El espaciado de letras en el lienzo ES APOYADO, utilicé esto

canvas = document.getElementById(''canvas''); canvas.style.letterSpacing = ''2px'';


En realidad, el lienzo del concepto de espaciado entre letras no es compatible.

Entonces usé javascript para hacer esto.

var value = $(''#sourceText1'').val().split("").join(" ");

O

var sample_text = "Praveen Chelumalla"; var text = sample_text.split("").join(" ");


No es verdad. Puede agregar propiedad de espaciado de letras al elemento canvas en css y funciona perfectamente. No hay necesidad de soluciones complicadas. Me acabo de dar cuenta en este momento en mi proyecto de lienzo. es decir: lienzo {ancho: 480px; altura: 350px; margen: 30px auto 0; relleno: 15px 0 0 0; fondo: rosa; bloqueo de pantalla; borde: 2px discontinuo marrón; espaciado entre letras: 0.1em; }


No estoy seguro de si debería funcionar (según las especificaciones), pero en algunos navegadores (Chrome) puede establecer la propiedad CSS letter-spacing en el elemento <canvas> sí, y se aplicará a todo el texto dibujado en el contexto . (Funciona en Chrome v56, no funciona en Firefox v51 o IE v11).

Tenga en cuenta que en Chrome v56 debe volver a obtener el contexto canvas 2d (y volver a establecer los valores que le interesan) después de cada cambio en el estilo de letter-spacing ; el espaciado parece hornearse en el contexto 2d que obtienes.

Ejemplo: https://jsfiddle.net/hg4pbsne/1/

var inp = document.querySelectorAll(''input''), can = document.querySelector(''canvas''), ctx = can.getContext(''2d''); can.width = can.offsetWidth; [].forEach.call(inp,function(inp){ inp.addEventListener(''input'', redraw, false) }); redraw(); function redraw(){ ctx.clearRect(0,0,can.width,can.height); can.style.letterSpacing = inp[0].value + ''px''; ctx = can.getContext(''2d''); ctx.textAlign = ''center''; ctx.textBaseline = ''middle''; ctx.font = ''4em sans-serif''; ctx.fillText(''Hello'', can.width/2, can.height*1/4); can.style.letterSpacing = inp[1].value + ''px''; ctx = can.getContext(''2d''); ctx.textAlign = ''center''; ctx.textBaseline = ''middle''; ctx.font = ''4em sans-serif''; ctx.fillText(''World'', can.width/2, can.height*3/4); };

canvas { background:white } canvas, label { display:block; width:400px; margin:0.5em auto }

<canvas></canvas> <label>hello spacing: <input type="range" min="-20" max="40" value="1" step="0.1"></label> <label>world spacing: <input type="range" min="-20" max="40" value="1" step="0.1"></label>

Respuesta original, entre navegadores:

Esto no es posible; HTML5 Canvas no tiene todo el poder de transformación de texto de CSS en HTML. Sugeriría que combine las tecnologías apropiadas para cada uso. Use HTML en capas con Canvas e incluso SVG, cada uno haciendo lo que mejor hace.

Tenga en cuenta también que "enrollar el suyo", dibujando cada carácter con un desplazamiento personalizado, producirá malos resultados para la mayoría de las fuentes, dado que hay pares de interletraje de letras y sugerencias de fuentes alineadas en píxeles.


No puede establecer la propiedad del espaciado entre letras, pero puede lograr un espacio entre letras más ancho en el lienzo insertando uno de los espacios en blanco entre cada letra de la cadena. Por ejemplo

ctx.font = "3em sheepsans"; ctx.textBaseline = "middle"; ctx.textAlign = "center"; ctx.fillStyle = "rgb(255, 255, 255)"; var ctext = "Blah blah text".split("").join(String.fromCharCode(8202)) ctx.fillText(ctext, 1024 / 2, 768 / 2);

Esto insertará un espacio entre cada letra.

Al usar 8201 (en lugar de 8202) se insertará el espacio delgado ligeramente más ancho

Para obtener más opciones de espacios en blanco, consulte esta lista de espacios Unicode

Este método le ayudará a conservar el kerning de la fuente mucho más fácilmente que al posicionamiento manual de cada letra, sin embargo, no podrá ajustar el espacio entre letras de esta manera.


Para permitir ''pares de interletraje de letras'' y similares, he escrito lo siguiente. Debe tener esto en cuenta, y las pruebas preliminares sugieren que sí. Si tiene algún comentario al respecto, le indicaré mi pregunta sobre el tema (Cómo agregar espacio entre letras en el lienzo HTML )

Básicamente usa measureText () para obtener el ancho de toda la cadena, y luego elimina el primer carácter de la cadena y mide el ancho de la cadena restante, y usa la diferencia para calcular la posición correcta, teniendo en cuenta los pares de kerning y similares. Vea el enlace dado para más pseudocódigo.

Aquí está el HTML:

<canvas id="Test1" width="800px" height="200px"><p>Your browser does not support canvas.</p></canvas>

Aquí está el código:

this.fillTextWithSpacing = function(context, text, x, y, spacing) { //Start at position (X, Y). //Measure wAll, the width of the entire string using measureText() wAll = context.measureText(text).width; do { //Remove the first character from the string char = text.substr(0, 1); text = text.substr(1); //Print the first character at position (X, Y) using fillText() context.fillText(char, x, y); //Measure wShorter, the width of the resulting shorter string using measureText(). if (text == "") wShorter = 0; else wShorter = context.measureText(text).width; //Subtract the width of the shorter string from the width of the entire string, giving the kerned width of the character, wChar = wAll - wShorter wChar = wAll - wShorter; //Increment X by wChar + spacing x += wChar + spacing; //wAll = wShorter wAll = wShorter; //Repeat from step 3 } while (text != ""); }

Código para prueba demo / eyeball:

element1 = document.getElementById("Test1"); textContext1 = element1.getContext(''2d''); textContext1.font = "72px Verdana, sans-serif"; textContext1.textAlign = "left"; textContext1.textBaseline = "top"; textContext1.fillStyle = "#000000"; text = "Welcome to go WAVE"; this.fillTextWithSpacing(textContext1, text, 0, 0, 0); textContext1.fillText(text, 0, 100);

Idealmente, lanzaría múltiples cadenas aleatorias y haría una comparación de píxel por píxel. Tampoco estoy seguro de cuán bueno es el interletraje predeterminado de Verdana, aunque entiendo que es mejor que Arial: sugerencias sobre otras fuentes para intentar aceptar con gratitud.

Entonces ... hasta ahora se ve bien. De hecho, se ve perfecto. Aún espero que alguien señale cualquier falla en el proceso.

Mientras tanto, pondré esto aquí para que otros vean si están buscando una solución al respecto.


Yo suelo:

ctx.font = "32px Tahoma";//set font ctx.scale(0.75,1);//important! the scale ctx.fillText("LaFeteParFete test text", 2, 274);//draw ctx.setTransform(1,0,0,1,0,0);//reset transform


No puede establecer el espaciado entre letras como una propiedad del contexto Canvas. Solo puede lograr el efecto haciendo un espaciado manual, lo siento. (Como en, dibujando cada letra de forma manual aumentando la x en una cantidad de píxel en cada una)

Para el registro, puede establecer algunas propiedades de texto usando ctx.font pero el espaciado entre letras no es uno de ellos. Los que puede configurar son: "font-style font-variant font-weight font-size / line-height font-family"

Por ejemplo, técnicamente puede escribir ctx.font = "bold normal normal 12px/normal Verdana" (o cualquier omisión de cualquiera de ellos) y se analizará correctamente.