2015-11-18 2 views
2

В моем инструменте редактора «на лету» я бы очень хотел получить фактическую визуализированную высоту текста/шрифта - (я имею в виду не просто получение размера шрифта CSS, ни расчетного, ни предустановленного).Javascript - получить фактическую визуализированную высоту шрифта

Возможно ли это в javascript?

Если нет напрямую, возможно ли что-то в качестве визуализации в холсте так же, как оно отображается как обычный текст, - а затем выяснить?

EDIT - мое «DEV» решение: на основе предложенных ссылок я построил немного чистый яваскрипт код, который проходит через пиксели в полотне и анализирует ли пиксель белый или нет, и действует соответствующим образом, то вряд ли версия разработчик коды - просто выводит несколько полезной информации и показывает, как получить доступ к вычисленным данным - http://jsfiddle.net/DV9Bw/1325/

HTML:

<canvas id="exampleSomePrettyRandomness" width="200" height="60"></canvas> 
<div id="statusSomePrettyRandomness"></div> 

JS:

function findPos(obj) { 
var curleft = 0, curtop = 0; 
if (obj.offsetParent) { 
    do { 
     curleft += obj.offsetLeft; 
     curtop += obj.offsetTop; 
    } while (obj = obj.offsetParent); 
    return { x: curleft, y: curtop }; 
} 
return undefined; 
} 


var status = document.getElementById('statusSomePrettyRandomness'); 
var example = document.getElementById('exampleSomePrettyRandomness'); 
var context = example.getContext('2d'); 
context.fillStyle = "rgb(255,255,255)"; 
context.fillRect(0, 0, 200, 200); 
context.fillStyle = "rgb(0,0,0)"; 
context.font = "30px Arial"; 
context.fillText("Hello World",0,30); 
var pos = findPos(example); 
var x = example.pageX - pos.x; 
var y = example.pageY - pos.y; 
var foundTop = false; 
xPos = 0; 
yPos = 0; 
topY = -1; 
bottomY = -1; 
var fuse = 1000; 
while(fuse-- > 0){ 
//status.innerHTML += yPos+"<br>"; 
if(yPos == (example.offsetHeight - 2)){ 
    xPos++; 
    yPos = 0; 
    continue; 
} 
    var data = context.getImageData(xPos, yPos, 1, 1).data; 
if(! foundTop){ 
    if((data[0] != 255) && (data[1] != 255) && (data[2] != 255)){ 
     topY = yPos; 
     status.innerHTML += "<br>Found top: "+topY+" X:"+xPos+" Color: rgba("+data[0]+","+data[1]+","+data[2]+")"+"<br>"; 
     foundTop = true; 
    } 
} else { 
    if((data[0] == 255) && (data[1] == 255) && (data[2] == 255)){ 
     bottomY = yPos; 
     status.innerHTML += "<br>Found bottom: "+bottomY+" X:"+xPos+"<br>"; 
     break; 
    } 
} 
yPos++; 
if(yPos > example.offsetHeight){ 
    status.innerHTML += "" 
     +"Y overflow ("+yPos+">"+example.offsetHeight+")" 
     +" - moving X to "+xPos 
     +" - reseting Y to "+yPos 
     +"<br>" 
    ; 
     xPos++; 
    yPos = 0; 
} 
} 
status.innerHTML += "Fuse:"+fuse+", Top:"+topY+", Bottom: "+bottomY+"<br>"; 
status.innerHTML += "Font height should be: "+(bottomY-topY)+"<br>"; 

EDIT 2: Почему это не дубликат: мой вопрос касается действительно реальной визуализированной высоты шрифта или буквы, «possible duplicate» - это то, сколько места вам нужно, чтобы распечатать текст, предоставленные ответы не отвечайте на мою точную проблему.

+0

Я не уверен, что я завершаю Я получил ваш вопрос, и я нахожусь на пике rn, но поскольку вы отметили свой вопрос [html5-canvas], возможно, [этот вопрос] (http://stackoverflow.com/q/17627893/3702797), и его ответ может помочь вам , – Kaiido

+0

Я отметил его, потому что я предполагаю, что может быть решение при рисовании шрифта так же, как оно отображается как текст, - но в холсте, как пиксели изображения, то я думаю, что я мог бы каким-то образом проанализировать пиксели холста, потому что знаю, что такое базовый цвет и каков цвет утопленного шрифта :) Теперь это более ясно? –

+1

Возможно, попробуйте этот подход? http://stackoverflow.com/questions/1134586/how-can-you-find-the-height-of-text-on-an-html-canvas –

ответ

4

Я не знаю ни одного метода, который бы возвращал height текста, такого как measureText (который в настоящее время возвращает width).

Однако в теории вы можете просто нарисовать текст на холсте затем trim the surrounding transparent pixels затем измерить высоту холста ..

Вот пример (высота будет регистрироваться в консоли):

// Create a blank canvas (by not filling a background color). 
 
var canvas = document.getElementById('canvas'); 
 
var ctx = canvas.getContext('2d'); 
 

 
// Fill it with some coloured text.. (black is default) 
 
ctx.font = "48px serif"; 
 
ctx.textBaseline = "hanging"; 
 
ctx.fillText("Hello world", 0, 0); 
 

 
// Remove the surrounding transparent pixels 
 
// result is an actual canvas element 
 
var result = trim(canvas); 
 

 
// you could query it's width, draw it, etc.. 
 
document.body.appendChild(result); 
 

 
// get the height of the trimmed area 
 
console.log(result.height); 
 

 
// Trim Canvas Pixels Method 
 
// https://gist.github.com/remy/784508 
 
function trim(c) { 
 

 
    var ctx = c.getContext('2d'), 
 

 
    // create a temporary canvas in which we will draw back the trimmed text 
 
    copy = document.createElement('canvas').getContext('2d'), 
 

 
    // Use the Canvas Image Data API, in order to get all the 
 
    // underlying pixels data of that canvas. This will basically 
 
    // return an array (Uint8ClampedArray) containing the data in the 
 
    // RGBA order. Every 4 items represent one pixel. 
 
    pixels = ctx.getImageData(0, 0, c.width, c.height), 
 

 
    // total pixels 
 
    l = pixels.data.length, 
 
    
 
    // main loop counter and pixels coordinates 
 
    i, x, y, 
 

 
    // an object that will store the area that isn't transparent 
 
    bound = { top: null, left: null, right: null, bottom: null }; 
 

 
    // for every pixel in there 
 
    for (i = 0; i < l; i += 4) { 
 

 
    // if the alpha value isn't ZERO (transparent pixel) 
 
    if (pixels.data[i+3] !== 0) { 
 

 
     // find it's coordinates 
 
     x = (i/4) % c.width; 
 
     y = ~~((i/4)/c.width); 
 
    
 
     // store/update those coordinates 
 
     // inside our bounding box Object 
 

 
     if (bound.top === null) { 
 
     bound.top = y; 
 
     } 
 
     
 
     if (bound.left === null) { 
 
     bound.left = x; 
 
     } else if (x < bound.left) { 
 
     bound.left = x; 
 
     } 
 
     
 
     if (bound.right === null) { 
 
     bound.right = x; 
 
     } else if (bound.right < x) { 
 
     bound.right = x; 
 
     } 
 
     
 
     if (bound.bottom === null) { 
 
     bound.bottom = y; 
 
     } else if (bound.bottom < y) { 
 
     bound.bottom = y; 
 
     } 
 
    } 
 
    } 
 
    
 
    // actual height and width of the text 
 
    // (the zone that is actually filled with pixels) 
 
    var trimHeight = bound.bottom - bound.top, 
 
     trimWidth = bound.right - bound.left, 
 

 
     // get the zone (trimWidth x trimHeight) as an ImageData 
 
     // (Uint8ClampedArray of pixels) from our canvas 
 
     trimmed = ctx.getImageData(bound.left, bound.top, trimWidth, trimHeight); 
 
    
 
    // Draw back the ImageData into the canvas 
 
    copy.canvas.width = trimWidth; 
 
    copy.canvas.height = trimHeight; 
 
    copy.putImageData(trimmed, 0, 0); 
 

 
    // return the canvas element 
 
    return copy.canvas; 
 
}
<canvas id="canvas"></canvas>

Image Data API: https://developer.mozilla.org/en-US/docs/Web/API/ImageData

+0

Мне не нужна ширина - мне нужна высота :) –

+0

@ jave.web Я обновил свой ответ, включив рабочий пример. – Pierre

+0

Спасибо, испытаны, ручные измерения - работает. Но я не могу понять, что делает код - было бы так приятно и немного прокомментировать его? :) –

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