2017-10-24 12 views
5

Chúng tôi đang làm việc với JS vải để thêm đối tượng văn bản và hình ảnh vào canvas.Vải JS: Vùng chọn của đối tượng văn bản lớn hơn kích thước văn bản thực tế

Nhưng khi thêm bất kỳ đối tượng văn bản nào và chọn nó, nó sẽ hiển thị vùng chọn lớn hơn kích thước thực của văn bản.

Please refer this link to see the screen-shot.

Chúng tôi đang sử dụng mã sau để thêm đối tượng văn bản.

 
var text_object = new fabric.Text('00', { 
        fontSize: 192, 
        fontFamily: 'Times New Roman', 
        padding: 0 
        }); 
text_object.top = parseInt((canvas.height - text_object.height)/2); 
text_object.left = parseInt((canvas.width - text_object.width)/2); 
text_object.lockUniScaling = true; 
canvas.add(text_object); 
canvas.renderAll(); 
canvas.setActiveObject(text_object); 

Vấn đề chính là khi chúng tôi cố gắng lấy chiều rộng và chiều cao của đối tượng văn bản được thêm vào; nó cho chúng ta chiều rộng và chiều cao của vùng lựa chọn của đối tượng văn bản chứ không phải kích thước thực của văn bản.

Làm cách nào để chúng tôi có thể làm cho khu vực lựa chọn của đối tượng văn bản giống với kích thước thực của văn bản?

Hoặc làm cách nào chúng ta có thể nhận được kích thước văn bản thực tế, không có khu vực lựa chọn?

+0

bạn có thể tạo đoạn mã tối thiểu bằng mã của mình không, nêu rõ vấn đề của bạn? – Durga

+0

Tôi đã thêm đoạn mã được đề cập. Vì vậy, hãy kiểm tra. –

Trả lời

3

Không có cách nào trực tiếp đạt được những gì bạn muốn, đó sẽ là hộp giới hạn của đường dẫn vector của văn bản.

Nếu bạn đồng ý với giải pháp gần đúng, hãy hiển thị văn bản thành canvas trống, sử dụng getImageData để kiểm tra độ trong suốt của tất cả các pixel và tìm ra số điểm tối đa và phút x và y. Nó là hoàn hảo, nhưng bạn sẽ không nhận được một giải pháp tốt hơn một cách dễ dàng.

Tôi đoán rằng có thể có giải pháp phía máy chủ, nhưng tôi không biết bất kỳ điều gì. Và theo lý thuyết, bạn có thể tạo công cụ hiển thị phông chữ của riêng mình trong JS và vì vậy bạn sẽ có hộp giới hạn hoàn hảo, ngoại trừ trường hợp đơn giản/đồ chơi, một công cụ bố cục văn bản nghiêm trọng phải mất hàng năm trời. để thực hiện, vì vậy tôi đoán nó hoàn toàn nằm ngoài phạm vi.

Nếu bạn cần trợ giúp với phương pháp xấp xỉ, hãy cho tôi biết và tôi cung cấp ví dụ.

Edited để cung cấp một ví dụ:

function getVisiblePixelsBoundingBox(canvas) { 
 
    const context = canvas.getContext("2d"); 
 
    const imageData = context.getImageData(0, 0, canvas.width, canvas.height).data; 
 
    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; 
 
    for (let y = 0; y < canvas.height; y++) { 
 
     for (let x = 0; x < canvas.width; x++) { 
 
      const alpha = imageData[(y * canvas.width + x) * 4 + 3]; 
 
      if (alpha > 0) { 
 
       minX = Math.min(minX, x); 
 
       minY = Math.min(minY, y); 
 
       maxX = Math.max(maxX, x); 
 
       maxY = Math.max(maxY, y); 
 
      } 
 
     } 
 
    } 
 
    return { 
 
     left: minX, 
 
     top: minY, 
 
     width: maxX - minX, 
 
     height: maxY - minY 
 
    }; 
 
} 
 

 
// you will need to create a new canvas 
 
var canvas = document.createElement("canvas"), 
 
    context = canvas.getContext("2d"); 
 

 
// and set the width and height the same as the canvas you want to draw the text 
 
// here I'm just adding some values for the example: 
 
canvas.width = 600; 
 
canvas.height = 400; 
 

 
// now I'm going to draw some text on it 
 
context.font = "120px serif"; 
 
context.fillText("Lipsum", 100, 200); 
 

 
let boundingBox = getVisiblePixelsBoundingBox(canvas); 
 

 
// now this is not needed in your case, but want to see the canvas and 
 
// I will draw a rectangle around the bounding box to see how it works: 
 
document.body.appendChild(canvas); 
 
context.strokeStyle = "red"; 
 
context.strokeRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height);

Ok, vì vậy đây có vẻ tốt, nhưng hãy cẩn thận trong những vấn đề:

  • Độ chính xác được giới hạn pixel, vì vậy trong khi nó hoàn toàn ok để vẽ hộp giới hạn, nó không phải là tốt cho hoạt động tha t sẽ yêu cầu độ chính xác cao hơn nhiều, giống như các hình dạng căn chỉnh hoàn hảo. Ngoài ra, bởi vì phương pháp đo lường, nếu một phần của một hình dạng mỏng đến mức không thể nhìn thấy, thì nó sẽ không được đo (có thể không phải là một vấn đề lớn đối với bạn, bởi vì các hình dạng cực kỳ mỏng không xảy ra trong phông chữ).

  • Thực thi nó có thể chậm vì chúng tôi đang lặp lại tất cả các pixel để nhận kết quả (và JS không đặc biệt nhanh cho điều đó). Biết được điều này, bạn có thể bị cám dỗ để cố gắng giảm kích thước canvas và không sử dụng cùng một canvas của canvas mục tiêu của bạn, nhưng tôi khuyên bạn không nên, vì nó sẽ giới thiệu các vấn đề mới liên quan đến điểm tiếp theo.

  • Nếu bạn đo văn bản của mình ở bên ngoài khung hình, khi đó hộp giới hạn sẽ được giới hạn ở khu vực hiển thị (nó sẽ dính vào viền). Bạn có thể nghĩ đến việc tăng kích thước canvas nếu điều này xảy ra để có chiều rộng và chiều cao thực, nhưng nếu bạn không giới hạn kích thước phông chữ và số lượng văn bản, bạn có thể kết thúc bằng canvas lớn đến mức làm chậm trình duyệt hoặc có thể thậm chí làm hỏng nó ... Vì vậy, tôi chỉ chấp nhận rằng hộp giới hạn bám vào biên giới. Bạn có thể nghĩ rằng việc sử dụng chiều rộng được cung cấp bởi measureText có thể hữu ích, nhưng thật không may, để có được chiều cao và chiều cao bạn cần để quét toàn bộ hình ảnh.

+1

Dường như tiêu chuẩn cho TextMetrics đã được cập nhật nhưng chưa có trình duyệt hỗ trợ. https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics –

+0

Cảm ơn Roman. Vui lòng cung cấp trợ giúp với phương pháp xấp xỉ bằng ví dụ. Vì vậy, chúng tôi có thể kiểm tra nó và sẽ sử dụng nó nếu nó sẽ làm việc cho chúng tôi. –

+0

Ví dụ được cung cấp, vui lòng kiểm tra –

Các vấn đề liên quan