In iOS there is this animation of screen rotation when changing orientation:
According to my observations, the following happens here: the screen rotates at a right angle, at the same time the size of the visible area smoothly changes, which in my example is highlighted in red.
I need to understand how the size of this visible area is calculated during the animation process.
There are the following initial data:
duration – animation duration
targetWidth/targetHeight – screen dimensions after rotation
currentWidth/currentHeight – the size of the visible area at the current time
startTime – animation start time in milliseconds
Let’s say we have a function that will be launched as often as possible during the animation process (ideally 60 times per second, but not guaranteed – skipping frames is possible), in which we must calculate the size of the visible area at the current time. This function has a variable currentTime that stores the current time in milliseconds. First, we need to determine the current progress of the animation, let it be a floating point number from 0 to 1, we do it like this:
progress = (currentTime - startTime) / duration;
Next, you should implement the logic of how the size of the visible area will change relative to the current progress. I took linear interpolation here as an example:
lerp(start, end, t) {
return start * (1 - t) + end * t;
}
start – initial (current) value
end – final (target) value
t – progress (0..1)
This results in the following logic:
if (progress <= 1) {
currentWidth = lerp(currentWidth, targetWidth, progress);
currentHeight = lerp(currentHeight, targetHeight, progress);
} else {
// Stop execution
}
With this implementation, the following happens:
The dimensions of the visible area do not change as needed: in portrait orientation on the right, and in landscape orientation from below (in the example on the right), you can see how my animation is ahead of the iOS system animation.
The question is how to accurately calculate the size of the visible area.
UPD: For comparison, here are the sizes obtained during the iOS system animation ([self.view.layer.superlayer presentationLayer] frame]) using CADisplayLink in the simulator:
- Portrait 320x568 to Landscape 568x320:
width: 320.243 height: 567.757
width: 323.311 height: 564.689
width: 329.032 height: 558.968
width: 338.222 height: 549.778
width: 351.841 height: 536.159
width: 370.106 height: 517.894
width: 385.66 height: 502.34
width: 406.962 height: 481.038
width: 429.834 height: 458.166
width: 453.67 height: 434.33
width: 476.763 height: 411.237
width: 498.749 height: 389.251
width: 517.971 height: 370.029
width: 534.63 height: 353.37
width: 547.756 height: 340.244
width: 557.701 height: 330.299
width: 564.146 height: 323.854
width: 567.481 height: 320.519
width: 568 height: 320
- Landscape 568x320 to Portrait 320x568:
width: 567.768 height: 320.232
width: 564.667 height: 323.333
width: 559.113 height: 328.887
width: 547.701 height: 340.299
width: 535.637 height: 352.363
width: 520.4 height: 367.6
width: 502.572 height: 385.428
width: 481.624 height: 406.376
width: 458.583 height: 429.417
width: 433.508 height: 454.492
width: 411.361 height: 476.639
width: 389.772 height: 498.228
width: 370.197 height: 517.803
width: 353.67 height: 534.33
width: 340.18 height: 547.82
width: 330.549 height: 557.451
width: 323.93 height: 564.07
width: 320.563 height: 567.437
width: 320 height: 568
And similar figures from my calculations:
- Portrait 320x568 to Landscape 568x320:
width: 320 height: 568
width: 333.778 height: 554.222
width: 359.802 height: 528.198
width: 394.502 height: 493.498
width: 433.057 height: 454.943
width: 470.541 height: 417.459
width: 503.028 height: 384.972
width: 528.295 height: 359.705
width: 545.941 height: 342.059
width: 556.971 height: 331.029
width: 563.098 height: 324.902
width: 566.094 height: 321.906
width: 567.365 height: 320.635
width: 567.823 height: 320.177
width: 567.961 height: 320.039
width: 567.993 height: 320.007
width: 567.999 height: 320.001
width: 568 height: 320
width: 568 height: 320
- Landscape 568x320 to Portrait 320x568:
width: 568 height: 320
width: 554.222 height: 333.778
width: 528.198 height: 359.802
width: 493.498 height: 394.502
width: 454.943 height: 433.057
width: 417.459 height: 470.541
width: 384.972 height: 503.028
width: 359.705 height: 528.295
width: 342.059 height: 545.941
width: 331.029 height: 556.971
width: 324.902 height: 563.098
width: 321.906 height: 566.094
width: 320.635 height: 567.365
width: 320.177 height: 567.823
width: 320.039 height: 567.961
width: 320.007 height: 567.993
width: 320.001 height: 567.999
width: 320 height: 568
width: 320 height: 568






