I have a gradientRect as the back of my clockface svg. I want it to be rotated 45 degrees diagonally so the gradient goes from the top left to the bottom right not side to side. I've tried wrapping it in a g container
<g transform="rotate(45)">
<gradientRect id="bg" width="100%" height="100%" />
</g>
#bg {
gradient-type: "linear";
gradient-x1: "0";
gradient-y1: "50";
gradient-x2: "0";
gradient-y2: "100%-50";
gradient-color1: "magenta";
gradient-color2: "red";
}
It rotates the gradientrect but moves it out of place. I also need it to cover the whole screen. Any idea the best approach to have a diagonal linear gradient? Thanks!
Best AnswerI think a rect that size is too big to rotate. You may need to investigate BarbWire's suggestion of assembling smaller rects.
If you only want angles that are multiples of 45 deg, you can do it using a 336x336.
Best AnswerIt's definitely a matter of size!
I just ran a little test with rotating on tap. The big gradientRect got ugly cropped, while a 336x336 can even be rotated with smoothSecond angle without any problems.
So you might test out where the size-limit is or go with a combination of small rects rotated together in one group
Best AnswerIf you really need to cover all the secreen:
I now tested with 4 gradientRects (width: 210, height: 210) in the rotated group
1 set at (0,0)
2 set at (0,-h)
3 set at (-w,0)
4 set at (-w,-h)
This rotates without getting smashed, but can show 1px gaps depending on rotation angle, so you'd need to overlap them.
Making the gradient-quartett looking like one gradient would be another challenge.
@SunsetRunner and @Gondwana Tnx for help me! Finally I used a "merge" between real rotation and collision points to set x1, y1, x2, y2 and rotation angle and it's working!
Here's the code:
common/utils.js
function degreesToRadians(degrees){
var pi = Math.PI;
return degrees * (pi/180);
}
function opossiteAngle(angle){
var opposite;
if (angle == 0) {
opposite = 180; // or -180 as you wish
} else {
if (angle > 0) {
opposite = angle - 180;
} else {
opposite = angle + 180;
}
}
return opposite;
}
function calculateCoords(width, height, degrees){
let x0 = width / 2;
let y0 = height / 2;
let vx = Math.cos(degreesToRadians(degrees - 90));
let vy = Math.sin(degreesToRadians(degrees - 90));
//potential border positions
let ex = vx > 0 ? width : 0;
let ey = vy > 0 ? height : 0;
//check for horizontal/vertical directions
if (vx == 0) {
return [x0, ey];
}
if (vy == 0) {
return [ex, y0];
}
// in general case find times of intersections with horizontal and vertical edge line
let tx = (ex - x0) / vx;
let ty = (ey - y0) / vy;
// and get intersection for smaller parameter value
if (tx <= ty) {
return [ex, y0 + tx * vy];
}
return [x0 + ty * vx, ey];
}
export function calcColPts(width, height, degrees){
let pointOne = calculateCoords(width, height, degrees);
pointOne = [Math.ceil(pointOne[0]), Math.ceil(pointOne[1])];
let pointTwo = calculateCoords(width, height, opossiteAngle(degrees));
pointTwo = [Math.ceil(pointTwo[0]), Math.ceil(pointTwo[1])];
return [pointOne, pointTwo];
}
app/index.js
messaging.peerSocket.onmessage = evt => {
if (evt.data.key === "degreeGradient" && evt.data.newValue) {
let degrees = JSON.parse(evt.data.newValue);
document.getElementById("gGradRectangle").groupTransform.rotate.angle = (degrees <= 90) ? 90 : (degrees <= 180) ? 180 : (degrees <= 270) ? 270 : 359;
degrees = (degrees <= 90) ? degrees : (degrees <= 180) ? degrees - 90 : (degrees <= 270) ? degrees - 180 : degrees - 270;
let points = util.calcColPts(336, 336, 90 - degrees);
let x1 = Math.min(points[0][0], points[1][0]);
let y1 = Math.min(points[0][1], points[1][1]);
let x2 = Math.max(points[0][0], points[1][0]);
let y2 = Math.max(points[0][1], points[1][1]);
document.getElementById("gradRectangle").gradient.x1 = x1;
document.getElementById("gradRectangle").gradient.y1 = y1;
document.getElementById("gradRectangle").gradient.x2 = x2;
document.getElementById("gradRectangle").gradient.y2 = y2;
}
}
resources/index.view
<svg id="rectangleRoot">
<g id="gGradRectangle" transform="translate(50%, 50%)">
<gradientRect id="gradRectangle" x="-168" y="-168" width="336" height="336"
gradient-type="linear"
gradient-x1="168" gradient-y1="0"
gradient-x2="168" gradient-y2="336"
gradient-color1="white"
gradient-color2="black"/>
</g>
</svg>
Ah... interesting to see your use-case!
I hadn't fully understood before.
Nice, that you got it working 👍
I actually never would have thought of calculating the gradients coords (I#m so used to using groups for every transform).
That is an interesting approach. I like!
Best Answer