1

I am creating some tooltip for my project in three.js. Here is the code that i used to create the tooltip.

var defaultWidthForText = 450;
var canvasMinSize = 300;
var textMultiplier = 1.2;


function getMaxWidth(context, texts)
{
    let maxWidth = 0;
    for(let i in texts)
        maxWidth = Math.max(maxWidth, context.measureText(texts[i]).width);
    return maxWidth;
}

function makeTextSprite(message, parameters, transparent, opaque) {
    message = " " + message + " ";
    if (parameters === undefined) parameters = {};

    var fontface = parameters.hasOwnProperty("fontface") ?
        parameters["fontface"] : "Arial";

    var fontsize = parameters.hasOwnProperty("fontsize") ?
        parameters["fontsize"] : 24 ;

    var borderThickness = parameters.hasOwnProperty("borderThickness") ?
        parameters["borderThickness"] : 2;

    var borderColor = parameters.hasOwnProperty("borderColor") ?
        parameters["borderColor"] : { r: 0, g: 0, b: 0, a: 1.0 };

    var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
        parameters["backgroundColor"] : { r: 255, g: 255, b: 255, a: 1.0 };

    var textColor = parameters.hasOwnProperty("textColor") ?
        parameters["textColor"] : { r: 0, g: 0, b: 0, a: 1.0 };

    /// setting opaque
    if(opaque === undefined) backgroundColor.a = 0.3;
    else backgroundColor.a = opaque;

    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    context.font = "Bold " + fontsize + "px " + fontface;

    var texts = message.split('\n');
    var totalLine = texts.length;
    var textWidth = getMaxWidth(context, texts);

    // setting canvas size
    var size = Math.max(canvasMinSize, textWidth + 2 * borderThickness);
    canvas.width = size;
    canvas.height = size;
    context.font = "Bold " + fontsize + "px " + fontface;

    // background color
    context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
        + backgroundColor.b + "," + backgroundColor.a + ")";
    // border color
    context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
        + borderColor.b + "," + borderColor.a + ")";
    // border width
    context.lineWidth = borderThickness;

    let totalTextHeight = fontsize * textMultiplier * totalLine;
    roundRect(context, (size/2 - textWidth / 2) - borderThickness/2, size / 2 - fontsize/2 - totalTextHeight/2, textWidth + borderThickness, totalTextHeight + fontsize/2 , 6);


    // text color
    context.fillStyle = "rgba(" + textColor.r + "," + textColor.g + ","
        + textColor.b + "," + textColor.a + ")";

    let startY = size / 2  - totalTextHeight/2 + fontsize/2 ;
    for(var i = 0; i < totalLine; i++) {
        let curWidth = context.measureText(texts[i]).width;
        context.fillText(texts[i], size/2 - curWidth/2, startY + fontsize * i * textMultiplier);
    }

    // canvas contents will be used for a texture
    var texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;

    var spriteMaterial = new THREE.SpriteMaterial(
        { map: texture, transparent: true, depthTest: false, depthWrite: false });


    if (transparent !== undefined && transparent === true) {
        spriteMaterial.transparent = true;
        spriteMaterial.depthWrite = false;
        spriteMaterial.depthTest = false;
    }

    var sprite = new THREE.Sprite(spriteMaterial);
    return sprite;
}



function roundRect(ctx, x, y, w, h, r) {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.quadraticCurveTo(x + w, y, x + w, y + r);
    ctx.lineTo(x + w, y + h - r);
    ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
    ctx.lineTo(x + r, y + h);
    ctx.quadraticCurveTo(x, y + h, x, y + h - r);
    ctx.lineTo(x, y + r);
    ctx.quadraticCurveTo(x, y, x + r, y);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
}

This produce a tooltip like this picture.

Now i want to produce a tooltip where i can show some table in it like this.

If anyone could kindly point me to the right answer on stackoverflow or provide a solution.

Thanks.

Community
  • 1
  • 1
Mahmudur Rahman
  • 640
  • 1
  • 6
  • 23
  • You're creating a 2D canvas for your sprite texture, which means you can draw to it however you want. You're also sizing that canvas to correctly contain the text, and positioning the text to properly draw within the canvas. If you apply these concepts when considering what represents your canvas here will represent one cell of your table, then all you need to add are lines (which you can draw with the 2D context). – TheJim01 May 17 '17 at 13:34
  • I was also thinking about the same approach but i was just wondering if there is any other approach or library available that i can use to make the process simple. @TheJim01 – Mahmudur Rahman May 17 '17 at 13:38
  • I searched "draw HTML table to canvas" and got several good results. This is probably what you're looking for: http://stackoverflow.com/questions/13903952/can-i-draw-a-table-in-canvas-element – TheJim01 May 17 '17 at 13:44
  • Thanks for the reply. I will try and see if this works. @TheJim01 – Mahmudur Rahman May 17 '17 at 14:10

0 Answers0