Home > Enterprise >  Properly inject JavaScript functions inside of the QT project
Properly inject JavaScript functions inside of the QT project

Time:02-01

I created the below image in html and JavaScript where the alphabets curve around the arc of the image. I am trying to convert the code I wrote and properly inject the functions inside of a QT project. However, my current implementation does not work due TypeError: Type errors. Can someone help with this?

Also if possible: I would like to rotate the alphabets to be vertical to the arc instead of horizontal.

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Canvas {
        anchors.fill: parent

        Image {
            id: abcBar
            source: "alphabetBar.png"
            visible: false
        }


        onPaint: {
            var ctx = getContext('2d');
            ctx.save();
            ctx.canvas.width = 160;
            ctx.canvas.height = 432;
            ctx.font = "18px Roboto";
            ctx.textAlign = "center";
            ctx.fillStyle = "#000000"

            const centerX = 10;
            const centerY = ctx.canvas.height / 2;
            const angle = Math.PI;
            const radius = 130
            ctx.fillStyle = "#000000"
            ctx.restore();


            ctx.save();
            ctx.drawImage(abcBar, 0, 0, ctx.canvas.width, ctx.canvas.height);
            console.log('loaded')
            ctx.restore();

            const args = {
                ctx,
                text: "A • D • G • J • M • P • S • V • Z",
                offset: 0,
                G1: {
                    x: 20,
                    y: 80,
                },
                G2: {
                    x: 190,
                    y: 230,
                },
                G3: {
                    x: 0,
                    y: 372
                },
            }
            textOnCurve(args);
        }
    }


    function textOnCurve({ ctx, text, offset, G1, G2, G3, G4}){

        const x1 = G1.x;
        const y1 = G1.y;
        const x2 = G2.x;
        const y2 = G2.y;
        const x3 = G3.x;
        const y3 = G3.y;
        const x4 = G3.x;
        const y4 = G3.y;

        ctx.save();
        ctx.textAlign = "center";

        var widths = [];
        for (var i = 0; i < text.length; i  )
        {
            widths[widths.length] = ctx.measureText(text[i]).width;
        }

        ctx.beginPath();
        var ch = curveHelper(x1, y1, x2, y2, x3, y3, x4, y4);
        ctx.stroke();

        var pos = offset;
        var cpos = 0;
        for (var j = 0; j < text.length; j  )
        {
            pos  = widths[j] / 2;
            cpos = ch.forward(pos);
            ch.tangent(cpos);
            ctx.setTransform(ch.vect.x, ch.vect.y, -ch.vect.y, ch.vect.x, ch.vec.x, ch.vec.y);
            ctx.fillText(text[j], 0, 0);
            pos  = widths[j] / 2;
        }
        ctx.restore();
    }

    function curveHelper(x1, y1, x2, y2, x3, y3, x4, y4)
    {
        var tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
        var a, b, c, u;
        var vec, currentPos, vec1, vect, quad, currentDist;
        vec = { x: 0, y: 0 } ;
        vec1 = { x: 0, y: 0 } ;
        vect = { x: 0, y: 0 } ;
        quad = false;
        currentPos = 0;
        currentDist = 0;
        if (x4 === undefined || x4 === null)
        {
            quad = true;
            x4 = x3;
            y4 = y3;
        }
        var estLen = Math.sqrt((x4 - x1)* (x4 - x1)  (y4 - y1)* (y4 - y1));
        var onePix = 1 / estLen;

        function posAtC(c)
        {
            tx1 = x1; ty1 = y1;
            tx2 = x2; ty2 = y2;
            tx3 = x3; ty3 = y3;
            tx1  = (tx2 - tx1)* c;
            ty1  = (ty2 - ty1)* c;
            tx2  = (tx3 - tx2)* c;
            ty2  = (ty3 - ty2)* c;
            tx3  = (x4 - tx3)* c;
            ty3  = (y4 - ty3)* c;
            tx1  = (tx2 - tx1)* c;
            ty1  = (ty2 - ty1)* c;
            tx2  = (tx3 - tx2)* c;
            ty2  = (ty3 - ty2)* c;
            vec.x = tx1   (tx2 - tx1)* c;
            vec.y = ty1   (ty2 - ty1)* c;
            return vec;
        }

        function posAtQ(c)
        {
            tx1 = x1; ty1 = y1;
            tx2 = x2; ty2 = y2;
            tx1  = (tx2 - tx1)* c;
            ty1  = (ty2 - ty1)* c;
            tx2  = (x3 - tx2)* c;
            ty2  = (y3 - ty2)* c;
            vec.x = tx1   (tx2 - tx1)* c;
            vec.y = ty1   (ty2 - ty1)* c;
            return vec;
        }

        function forward(dist)
        {
            var step;
            helper.posAt(currentPos);
            while (currentDist < dist)
            {
                vec1.x = vec.x;
                vec1.y = vec.y;
                currentPos  = onePix;
                helper.posAt(currentPos);
                currentDist  = step = Math.sqrt((vec.x - vec1.x)* (vec.x - vec1.x)  (vec.y - vec1.y)* (vec.y - vec1.y));
            }
                currentPos -= ((currentDist - dist)/ step)* onePix
                currentDist -= step;
                helper.posAt(currentPos);
                currentDist  = Math.sqrt((vec.x - vec1.x)* (vec.x - vec1.x)  (vec.y - vec1.y)* (vec.y - vec1.y));
                return currentPos;
        }

        function tangentQ(pos)
        {
            a = (1 - pos)* 2;
            b = pos * 2;
            vect.x = a * (x2 - x1)  b * (x3 - x2);
            vect.y = a * (y2 - y1)  b * (y3 - y2);
            u = Math.sqrt(vect.x * vect.x   vect.y * vect.y);
            vect.x /= u;
            vect.y /= u;
        }

        function tangentC(pos)
        {
            a = (1 - pos)
            b = 6 * a * pos;
            a *= 3 * a;
            c = 3 * pos * pos;
            vect.x = -x1 * a   x2 * (a - b)  x3 * (b - c)  x4 * c;
            vect.y = -y1 * a   y2 * (a - b)  y3 * (b - c)  y4 * c;
            u = Math.sqrt(vect.x * vect.x   vect.y * vect.y);
            vect.x /= u;
            vect.y /= u;
        }

        var helper = {
            vec: vec,
            vect: vect,
            forward: forward,
        }

        if (quad)
        {
            helper.posAt = posAtQ;
            helper.tangent = tangentQ;
        } else
        {
            helper.posAt = posAtC;
            helper.tangent = tangentC;
        }
            return helper
    }
}

Illustration created in html alphabetBar.png

CodePudding user response:

The reference to Image on line 35 is not going to work because it is a browser-specific JavaScript class which is not available in the QML JavaScript runtime. Even though it seems like the QML Image class you have commented out should be referencable in the runtime, no QML components are directly referencable in JavaScript as classes like this.

You will need to port your code to use Canvas::loadImage() as documented here:

https://doc.qt.io/qt-5/qml-qtquick-canvas.html#loadImage-method

Or you can uncomment your QML Image object and call Context2d::drawImage() with its id as the first argument as documented here:

https://doc.qt.io/qt-5/qml-qtquick-context2d.html#drawImage-method-2

Note, if you do that, the Image will appear twice in the window unless you set visible: false on the QML one.

  •  Tags:  
  • Related