开发者

Calculate SVG Linear Gradient attribute x1 y1 x2 y2 if we know angle?

开发者 https://www.devze.com 2023-02-16 07:07 出处:网络
As we know in SVG the angular linear gradient is via setting the attribute x1,x2,y1,y2. However, If we only get the angle,

As we know in SVG the angular linear gradient is via setting the attribute x1,x2,y1,y2. However, If we only get the angle,

1.how to calculate the result of x1,y1,x2,y2?

2.is it correct fo开发者_Go百科r this formula tan (angle ) = (y2-y1)/(x2-x1)? how can I calculate the all the parameters.


building off of JT-'s answer, here is a function that will do exactly what you need in Javascript. Just call this function passing the element and degrees as an integer. I've also added "left","right","up","down" as optional arguments.

function svg_linear_gradient_direction(element, direction){

    if(direction === "left"){

        element.setAttributeNS(null, "x1", "100%");
        element.setAttributeNS(null, "y1", "0%");
        element.setAttributeNS(null, "x2", "0%");
        element.setAttributeNS(null, "y2", "0%");

    } else if(direction === "right"){

        element.setAttributeNS(null, "x1", "0%");
        element.setAttributeNS(null, "y1", "0%");
        element.setAttributeNS(null, "x2", "100%");
        element.setAttributeNS(null, "y2", "0%");

    } else if(direction === "down"){

        element.setAttributeNS(null, "x1", "0%");
        element.setAttributeNS(null, "y1", "0%");
        element.setAttributeNS(null, "x2", "0%");
        element.setAttributeNS(null, "y2", "100%");

    } else if(direction === "up"){

        element.setAttributeNS(null, "x1", "0%");
        element.setAttributeNS(null, "y1", "100%");
        element.setAttributeNS(null, "x2", "0%");
        element.setAttributeNS(null, "y2", "0%");

    } else if(typeof direction === "number"){

        var pointOfAngle = function(a) {
            return {
                x:Math.cos(a),
                y:Math.sin(a)
            };
        }

        var degreesToRadians = function(d) {
            return ((d * Math.PI) / 180);
        }

        var eps = Math.pow(2, -52);
        var angle = (direction % 360);
        var startPoint = pointOfAngle(degreesToRadians(180 - angle));
        var endPoint = pointOfAngle(degreesToRadians(360 - angle));

        if(startPoint.x <= 0 || Math.abs(startPoint.x) <= eps)
            startPoint.x = 0;

        if(startPoint.y <= 0 || Math.abs(startPoint.y) <= eps)
            startPoint.y = 0;

        if(endPoint.x <= 0 || Math.abs(endPoint.x) <= eps)
            endPoint.x = 0;

        if(endPoint.y <= 0 || Math.abs(endPoint.y) <= eps)
            endPoint.y = 0;

        element.setAttributeNS(null, "x1", startPoint.x);
        element.setAttributeNS(null, "y1", startPoint.y);
        element.setAttributeNS(null, "x2", endPoint.x);
        element.setAttributeNS(null, "y2", endPoint.y);
    }
}


The following should get you what you need, or close to it. The gist is that it creates a start and end point within your area of rotation, the result will be a set of unit vectors that you can use (i.e. between 0.0 and 1.0). Where inputAngle is the angle you want your gradient to be.

function pointOfAngle(a) {
    return {x:Math.cos(a),
            y:Math.sin(a)};
}

function degreesToRadians(d) {
    return ((d * Math.PI) / 180);
}

var eps = Math.pow(2, -52);
var inputAngle = 45;
var angle = (inputAngle % 360);
var startPoint = pointOfAngle(degreesToRadians(180 - angle));
var endPoint = pointOfAngle(degreesToRadians(360 - angle));

// if you want negative values you can remove the following checks
// but most likely it will produce undesired results
if(startPoint.x <= 0 || Math.abs(startPoint.x) <= eps)
    startPoint.x = 0;

if(startPoint.y <= 0 || Math.abs(startPoint.y) <= eps)
    startPoint.y = 0;

if(endPoint.x <= 0 || Math.abs(endPoint.x) <= eps)
    endPoint.x = 0;

if(endPoint.y <= 0 || Math.abs(endPoint.y) <= eps)
    endPoint.y = 0;

Not sure how the linear gradient values are used for SVG, but you may need to multiply by your elements size...

x1 = startPoint.x * width
y1 = startPoint.y * height
x2 = endPoint.x * width
y2 = endPoint.y * height


Set x_i, y_i as if the angle were 0 deg and apply a rotation by means of the gradientTransform attribute (gradientTransform="rotate(angle)"),

0

精彩评论

暂无评论...
验证码 换一张
取 消