Рассчитать атрибут линейного градиента SVG x1 y1 x2 y2, если мы знаем угол? - PullRequest
3 голосов
/ 13 марта 2011

Как мы знаем в SVG, угловой линейный градиент задается через атрибут x1, x2, y1, y2. Однако, если мы получим только угол,

1.как вычислить результат x1, y1, x2, y2?

2. Правильно ли для этой формулы tan (angle) = (y2-y1) / (x2-x1)? Как я могу рассчитать все параметры.

Ответы [ 3 ]

6 голосов
/ 26 октября 2012

, основываясь на ответе JT, вот функция, которая будет делать именно то, что вам нужно в Javascript.Просто вызовите эту функцию, передавая элемент и градусы как целое число.Я также добавил «влево», «вправо», «вверх», «вниз» в качестве необязательных аргументов.

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);
    }
}
5 голосов
/ 27 мая 2011

Следующее должно дать вам то, что вам нужно, или близко к нему. Суть в том, что он создает начальную и конечную точки в пределах вашей области вращения, в результате вы получите набор векторов единиц, которые вы можете использовать (то есть между 0,0 и 1,0). Где inputAngle - это угол, под которым вы хотите, чтобы ваш градиент был.

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;

Не уверен, как значения линейного градиента используются для SVG, но вам может понадобиться умножить их на размер элемента ...

x1 = startPoint.x * width
y1 = startPoint.y * height
x2 = endPoint.x * width
y2 = endPoint.y * height
1 голос
/ 02 апреля 2011

Установите x_i, y_i, как если бы угол был равен 0 градусам, и примените вращение с помощью атрибута radiusTransform (gradientTransform="rotate(angle)"),

...