Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Find resulting x and y of rotated text

(Versa)

 

resources/index.gui

<g id="test" transform="translate(50%,50%)">
  <text id="test-text">a test</text>
</g>
<text id="text-angle"></text>

resources/styles.css

#test-text {
  x: 50;
  y: 0%;
  font-size: 32;
  font-family: Seville-Regular;
  text-anchor: start;
  fill: white;
}
#text-angle {
x: 5%;
y: 90%;
font-size: 24;
font-family: Seville-Regular;
text-length: 32;
text-anchor: start;
fill: white;
}

app/index.js

// partial code shown
let test = document.getElementById("test");
let testText = document.getElementById("test-text");

// when relevant area is clicked...
function showText() { test.groupTransform.rotate.angle = angle; testText.text = angle; textAngle.text = `angle: ${angle}, x: ${testText.x}, y: ${testText.y}`;
// testText.x is always 50 and testText.y is always 0, no matter what is shown on the screen }

I have also defined an area that, when clicked, increments the text angle by 30.

 

Changing the angle causes the text to be rotated as expected but the reported x and y of that text is always the same, as can be seen in the attached images.

 

test1-screenshot.pngtest1-screenshot (1).png

 

I was hoping to find the actual x and y that result from any given angle.

(The same would be great for 'translated' components as well)

 

Any help would be appreciated.

 

Cheers,

Nick

Best Answer
0 Votes
8 REPLIES 8
The text is at the same position, it just has a rotation applied.

If you need to work out the rotated version of x and y you can do it manually fairly easily.
Best Answer
0 Votes

Thanks Alan,

I was hoping that they'd provide the resulting x,y (for all transformations) which would simplify things, i.e. there'd be no need for me to do additional calculations in code.

 

Cheers,

Nick

Best Answer
0 Votes

@allan175 What would be the correct formula for this? Does it rotate around (0,0)?

 

Could this be in the right direction? (assuming it rotates around (0,0))

 

let x = 2; // original x
let y = 3; // original y
let angle = 90; // angle in degrees
// From degrees to radians: angle * Math.PI / 180
let radians = angle * Math.PI / 180;

let xAfterRotation = x*Math.cos(radians) + y*Math.sin(radians);
let yAfterRotation = y*Math.cos(radians) - x*Math.sin(radians);
console.log('New (x,y): (' + xAfterRotation + ', ' + yAfterRotation +')');

This gives (3,-2) as the coordinate after rotation (clockwise).
I haven't tested this with fitbit studio, I quickly ran it with jsfiddle.

 

 

 

Best Answer
0 Votes
@JeCom I think it rotates around the text's origin (with justification, so left/centre/right etc).

The rotation code you have is right, for non (0,0) origin you just need to subtract the position, do the rotation then add the position back in again.
Best Answer

Thanks JeCom,

 

I've got this function in my toolkit that I'll end up using as it also offers specifying a central point to rotate around. (though, it is a long since I last used it)

I was hoping I wouldn't have to do it in code, since the SDK has already done the work.

 

function calcRotatedPoint(centerX, centerY, x, y, angle) {
    let rads = (Math.PI / 180) * angle;
    let cos = Math.cos(rads);
    let sin = Math.sin(rads);
    let newX = (cos * (x - centerX)) + (sin * (y - centerY)) + centerX;
    let newY = (cos * (y - centerY)) - (sin * (x - centerX)) + centerY;
    
  return [newX, newY];
}

Cheers,

Nick

Best Answer

That looks great, I've been trying to rotate text around it's position but didn't have the right mindset about it. This will come in handy 🙂

Best Answer
0 Votes

Thanks Alan,

You are correct, this was used for Cartesian coordinates where higher Y values mean 'up', which is the opposite to what have have in the SDK (which is CSS based)...

 

Cheers,

Nick

Best Answer
0 Votes

in the end, thanks to all the above comments (and the web), the following code was settled on.

I hope it is of use to others too.

resources/index.gui

<svg class="background">
    <gradientRect id="bar" x="0" y="0" width="348" height="40"
      gradient-type="linear"
      gradient-x1="0" gradient-y1="25%"
      gradient-x2="0" gradient-y2="75%"
      gradient-color1="#ebd197"
      gradient-color2="#998100"
    />
  
  <circle cx="150" cy="150" r="10" fill="#444444" />
  
  <text id="test-text1">1</text>
  <text id="test-text2">2</text>
  <text id="test-text3">3</text>
  <text id="test-text4">4</text>
  <text id="test-text5">5</text>
  <text id="test-text6">6</text>
  <text id="test-text7">7</text>
  <text id="test-text8">8</text>
  <text id="test-text9">9</text>
  <text id="test-text10">10</text>
  <text id="test-text11">11</text>
  <text id="test-text12">12</text>
  
  <text id="text-angle"></text>
</svg>

 

// I have 12 textboxes, named 'test-text1' to 'test-text12'
let names = ['6', '7', '8', '9', '10', '11', '12', '1', '2', '3', '4', '5'];

// Angle to place each of the above textboxes. 6 o'clock is at 0-degrees, the rest are at 30-degree increments
let tmpAngle = 0; for (let i=1; i <= 12; i++) {
// get the testbox let c = document.getElementById(`test-text${i}`);
// 110 is the distance from the center (150,150) that the text will be placed on
// the smaller the number, the closed the textboxes will be to the center dot. let a = rotatePoint({x: 150, y: 150}, {x: 0, y: 110}, tmpAngle);

// slight adjustment to make sure things are centered... c.x = a.x - 7; c.y = a.y + 7;
// get the text to show c.text = names[i-1]; c.style.fill = 'white'; c.style.fontSize = 24;
console.log(`test-text${i}, ${tmpAngle}, ${names[i-1]}`);
tmpAngle += 30; } // ---------------------------------------- function rotatePoint(origin, offsets, angle) { let radians = angle * Math.PI / 180.0; let cos = Math.cos(radians); let sin = Math.sin(radians); let dY = offsets.y; return { x: Math.round( (cos * offsets.x) - (sin * offsets.y) + origin.x), y: Math.round( (sin * offsets.x) + (cos * offsets.y) + origin.y) }; }

test1-screenshot.png

 

 

Best Answer