如何找到由画布创建的文本的中心位置坐标?

时间:2019-04-28 18:41:43

标签: javascript html5 path html5-canvas coordinates

我想找到由画布动态创建的文本的中心位置坐标。例如,我想查找数字2的文本中心的x和y坐标,该文本以50px的间隔用arial字体系列书写了600px。示例:

HTML

<canvas id="myCanvas"></canvas>

JS

const myCanvas = document.getElementById('myCanvas');
const ctx = myCanvas.getContext('2d');
ctx.font = "600px Arial";             // ** Font family and Font-Size Changeable
ctx.fillText('2',10,450);             // ** Number Changeable

jsfiddle

sample image

文本,字体系列和字体大小可动态更改。如何找到中心位置坐标

1 个答案:

答案 0 :(得分:2)

实际上取决于您如何定义文本的“中心位置”。一种方法可能是搜索某些定义文本边界框的像素。此边界框始终是一个矩形,在每个维度(x,y)中分别具有边的最小/最大坐标。

enter image description here

因此,可以将文本的中心定义为此边界框的中心。 getCenterCoordsFromText就是这样做的,它根据边界框或整个画布的坐标系返回居中的x / y坐标。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.font = "100px Arial";
ctx.fillText("2", 14, 92);

function getCenterCoordsFromText(colors, relativeToCanvas) {
    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = imageData.data;
    var minX = Infinity;
    var minY = Infinity;
    var maxX = 0;
    var maxY = 0;
    for (var i = 0; i < data.length; i += 4) {
        var x = (i / 4) % canvas.width;
        var y = Math.floor((i / 4) / canvas.width);
        var pixelFound = data[i] === colors.red &&
            data[i + 1] === colors.green &&
            data[i + 2] === colors.blue &&
            data[i + 3] === colors.alpha;
        if (pixelFound) {
            if (minY > y) {
                minY = y;
            }
            if (maxY < y) {
                maxY = y;
            }
            if (minX > x) {
                minX = x;
            }
            if (maxX < x) {
                maxX = x;
            }
        }

    }
    var middleX = (maxX - minX) / 2;
    var middleY = (maxY - minY) / 2;
    return {
        x: (relativeToCanvas ? minX : 0) + middleX,
        y: (relativeToCanvas ? minY : 0) + middleY,
        offsetX: relativeToCanvas ? minX : 0,
        offsetY: relativeToCanvas ? minY : 0
    }
}

// get locally centered coordinates within bounding-box 
var relToCanvasCoordSystem = false;
var letterCoordRelToBox = getCenterCoordsFromText({
    red: 0,
    green: 0,
    blue: 0,
    alpha: 255 
}, relToCanvasCoordSystem);
document.getElementById("relBoundingBoxCoord").innerHTML = 'x: ' + letterCoordRelToBox.x + ' y: ' + letterCoordRelToBox.y;

// get globally centered coordinates of the bounding-box based on the whole canvas
relToCanvasCoordSystem = true;
var letterCoordRelToCanvas = getCenterCoordsFromText({
    red: 0,
    green: 0,
    blue: 0,
    alpha: 255 
}, relToCanvasCoordSystem);
document.getElementById("relCanvasCoord").innerHTML = 'x: ' + letterCoordRelToCanvas.x + ' y: ' + letterCoordRelToCanvas.y;

// draw a colored reference for bounding-box-coordinates-system note
function drawBoundingBox(offsetX, offsetY, width, height){
    ctx.beginPath();
    ctx.strokeStyle = "#FF0000";
    ctx.moveTo(offsetX, offsetY);
    ctx.lineTo(offsetX + width, offsetY);
    ctx.stroke(); 
    ctx.lineTo(offsetX + width, offsetY + height);
    ctx.stroke(); 
    ctx.lineTo(offsetX, offsetY + height);
    ctx.stroke(); 
    ctx.lineTo(offsetX, offsetY);
    ctx.stroke();
}

var offsetX = letterCoordRelToCanvas.offsetX;
var offsetY = letterCoordRelToCanvas.offsetY;
var boxWidth = letterCoordRelToBox.x*2;
var boxHeight = letterCoordRelToBox.y*2;
drawBoundingBox(offsetX, offsetY, boxWidth, boxHeight);
canvas {
  border: 1px solid #a3a3a3;
}

.bbcs{
  color: red;
}

.ccs{
  color: #a3a3a3;
}
<p>relative to <span class="bbcs">bounding-box-coordinate-system</span>:</p>
<div id="relBoundingBoxCoord"></div>
<p>relative to <span class="ccs">canvas-coordinate-system</span>:</p>
<div id="relCanvasCoord"></div>
<br/>

<canvas id="canvas" height="100" width="100"></canvas>