06-17-2018 23:00 - edited 06-17-2018 23:14
06-17-2018 23:00 - edited 06-17-2018 23:14
(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.
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
06-18-2018 02:05
06-18-2018 02:05
06-18-2018 02:33
06-18-2018 02:33
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
06-18-2018 02:34
06-18-2018 02:34
@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.
06-18-2018 02:41
06-18-2018 02:41
06-18-2018 02:42 - edited 06-18-2018 02:48
06-18-2018 02:42 - edited 06-18-2018 02:48
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
06-18-2018 02:45
06-18-2018 02:45
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 🙂
06-18-2018 02:46
06-18-2018 02:46
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
06-18-2018 06:02
06-18-2018 06:02
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) }; }