Łukasz Przeniosło
Łukasz Przeniosło

Reputation: 2949

Apply gradient to drawn figure

I have this MWE code here which is drawing a triangle with a set color:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0

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

    Rectangle
    {
        id: rectMain
        anchors.centerIn: parent
        width: parent.width
        height: parent.height
        color: "white"

        Canvas
        {
            anchors.fill: parent

            // set properties with default values
            property real hFactor: 1    // height factor
            property real trbase: 200
            property color strokeColor: "black"
            property color fillColor: "yellow"
            property int lineWidth: 1
            property real alpha: 1
            property real rotAngle: 0
            property real parentWidth: parent.width; // try
            property real parentHeight: parent.height;

            onStrokeColorChanged: requestPaint();
            onFillColorChanged: requestPaint();
            onLineWidthChanged: requestPaint();

            onPaint:
            {
                hFactor = Math.abs(hFactor)

                var ctx = getContext("2d") // get context to draw with
                ctx.clearRect(0, 0, width, height); // remove what is painted so far
                ctx.lineWidth = lineWidth
                ctx.strokeStyle = strokeColor
                ctx.fillStyle = fillColor
                ctx.globalAlpha = alpha

                ctx.save();
                ctx.beginPath();
                ctx.translate(parentWidth / 2, parentHeight / 2);
                ctx.rotate((Math.PI / 180) * rotAngle);
                ctx.moveTo(0, 0);

                // drawing part, first calculate height using Pythagoras equation
                var trheight = Math.sqrt(Math.pow(trbase, 2) - Math.pow(trbase / 2, 2));
                trheight = trheight * hFactor;
                var hfBase = trbase * hFactor;
                ctx.lineTo(hfBase / -2, trheight); // left arm
                ctx.lineTo(hfBase / 2, trheight); // right arm

                ctx.closePath(); // base drawn automatically
                ctx.fill();
                ctx.stroke();
                ctx.restore();
            }
        }
    }
}

I am trying to figure out how to apply gradient to this code, so having 2 colors (for example yellow and red) the triangle would gradient from the first to the other like this (edited in paint):

enter image description here

I tried using Gradient object from the documentation here: https://doc.qt.io/qt-5/qml-qtquick-gradient.html but with no success.

Upvotes: 0

Views: 854

Answers (1)

nayab
nayab

Reputation: 2380

createLinearGradient method is used to draw gradient on canvas. Just create a gradient using this method, add colors of gradient and finally assign it to fillStyle.

import QtQuick 2.9
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0

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

    Rectangle
    {
        id: rectMain
        anchors.centerIn: parent
        width: parent.width
        height: parent.height
        color: "white"

        Canvas
        {
            anchors.fill: parent

            // set properties with default values
            property real hFactor: 1    // height factor
            property real trbase: 200
            property color strokeColor: "black"
            property color fillColor: "yellow"
            property int lineWidth: 1
            property real alpha: 1
            property real rotAngle: 0
            property real parentWidth: parent.width; // try
            property real parentHeight: parent.height;

            onStrokeColorChanged: requestPaint();
            onFillColorChanged: requestPaint();
            onLineWidthChanged: requestPaint();

            onPaint:
            {
                hFactor = Math.abs(hFactor)

                var ctx = getContext("2d") // get context to draw with
                ctx.clearRect(0, 0, width, height); // remove what is painted so far
                ctx.lineWidth = lineWidth
                ctx.strokeStyle = strokeColor

                // create a gradient
                var gradient = ctx.createLinearGradient(100,0,100,200)
                        gradient.addColorStop(0, "yellow")
                        gradient.addColorStop(1, "red")



                ctx.fillStyle = gradient // assign gradient
                ctx.globalAlpha = alpha

                ctx.save();
                ctx.beginPath();
                ctx.translate(parentWidth / 2, parentHeight / 2);
                ctx.rotate((Math.PI / 180) * rotAngle);
                ctx.moveTo(0, 0);

                // drawing part, first calculate height using Pythagoras equation
                var trheight = Math.sqrt(Math.pow(trbase, 2) - Math.pow(trbase / 2, 2));
                trheight = trheight * hFactor;
                var hfBase = trbase * hFactor;
                ctx.lineTo(hfBase / -2, trheight); // left arm
                ctx.lineTo(hfBase / 2, trheight); // right arm

                ctx.closePath(); // base drawn automatically
                ctx.fill();
                ctx.stroke();
                ctx.restore();
            }
        }
    }
}

Here is the output

enter image description here

Also check simple example on gradient from QML book.

Upvotes: 1

Related Questions