[Tip] Gradientes en cualquier dirección con QML

Para todos aquellos que estén desarrollando programas en QML habrán notado que si aplicamos un gradiente a un rectangulo, este gradiente solo es posible aplicarlo de forma vertical, tal que así:

Pero, ¿Que pasaría si quisiéramos aplicar un gradiente en cualquier angulo posible?, por ejemplo aplicar gradientes en un angulo de 30°.
Pues eso es lo que vamos a ver hoy.
Supongamos que tenemos 2 rectángulos, Rectángulo 1 y Rectángulo 2, siendo Rectángulo 2 hijo de Rectángulo 1, Rectángulo 2 será a quien apliquemos el gradiente y la rotación, el rectángulo tendrá una rotación con respecto a su centro igual a la dirección del gradiente y sus dimensiones deben ser lo suficientemente grandes como para contener a Rectángulo 1, mientras que a Rectángulo 1 la aplicaremos la propiedad clip para no mostrar las áreas sobrantes de Rectángulo 2.
Lo podemos ver más claramente en el siguiente gráfico, el rectángulo de color azul representa al Rectángulo 1 mientras que el rectángulo de color rojo representa al Rectángulo 2:

El desarrollo matemático es un poco largo, lo pueden encontrar completo en mi blog, pero al final arribamos a la formula que nos permite calcular las dimensiones del rectángulo interior (el que contiene el gradiente), con respecto a la dirección del gradiente:

Sw = RW |cos α| + RH |sin α|
Sh = RW |sin α| + RH |cos α|

Y finalmente, el código fuente del ejemplo:

import QtQuick 1.0
 
Rectangle
{
    id: recParent
    width: 640
    height: 480
    color: "#000000"
 
    Rectangle
    {
        id: recGradientContainer
        width: 400
        height: 300
        clip: true
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        property real gradientRotation: 30
 
        Rectangle
        {
            id: recGradient
 
            // Sw = RW |cos a| + RH |sin a|
            // Sh = RW |sin a| + RH |cos a|
            width: recGradientContainer.width * recGradient.cos + recGradientContainer.height * recGradient.sin
            height: recGradientContainer.width * recGradient.sin + recGradientContainer.height * recGradient.cos
 
            rotation: recGradientContainer.gradientRotation
            smooth: true
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
 
            // Convertimos grados a radianes.
            property real rotationRadians: recGradient.rotation * Math.PI / 180
 
            // Precalculamos seno y coseno para el angulo del gradiente.
            property real cos: Math.abs(Math.cos(recGradient.rotationRadians))
            property real sin: Math.abs(Math.sin(recGradient.rotationRadians))
 
            gradient: Gradient
            {
                GradientStop
                {
                    position: 0
                    color: "#ff0000"
                }
 
                GradientStop
                {
                    position: 1
                    color: "#0000ff"
                }
            }
        }
    }
}

¡Gracias por el tip! Muy

¡Gracias por el tip! Muy interesante como siempre y bastante ingenioso. Saludos.

Anuncios Google