Skip to content

Commit f2d1dc0

Browse files
Fixed animation for setBounds.
1 parent 567d30b commit f2d1dc0

File tree

5 files changed

+48
-19
lines changed

5 files changed

+48
-19
lines changed

docs/api/base-view.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,9 @@ Objects created with `new BaseView` have the following instance methods:
147147

148148
#### `view.setBounds(bounds[, options])` _Experimental_
149149

150-
* `bounds` [Rectangle](structures/rectangle.md) - The position and size of the view, relative to its parent.
150+
* `bounds` [Rectangle](structures/rectangle.md) - The target position and size of the view, relative to its parent.
151151
* `options` Object (optional)
152+
* `fromBounds` [Rectangle](structures/rectangle.md) (optional) - The initial position and size of the view, relative to its parent.
152153
* `duration` Float (optional) - A duration of the animation (in seconds). Default is 1.0.
153154
* `timingFunction` string (optional) - One of the following values: `linear`, `easeIn`, `easeOut`, `easeInEaseOut`, `default`. Default is `linear`.
154155
* `timingControlPoints` Object (optional)

docs/api/browser-view.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Objects created with `new BrowserView` have the following instance methods:
6565

6666
* `bounds` [Rectangle](structures/rectangle.md)
6767
* `options` Object (optional)
68+
* `fromBounds` [Rectangle](structures/rectangle.md) (optional) - The initial position and size of the view, relative to its parent.
6869
* `duration` Float (optional) - A duration of the animation (in seconds). Default is 1.0.
6970
* `timingFunction` string (optional) - One of the following values: `linear`, `easeIn`, `easeOut`, `easeInEaseOut`, `default`. Default is `linear`.
7071
* `timingControlPoints` Object (optional)

shell/browser/ui/cocoa/electron_native_view.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ struct NativeViewPrivate {
7373
@property(strong, nonatomic) NSColor* _tintColor;
7474

7575
//* To get more vibrant colors, a filter to increase the saturation of the
76-
//colors can be applied. The default value is 2.5.
76+
// colors can be applied. The default value is 2.5.
7777
@property(assign, nonatomic) float _saturationFactor;
7878

7979
//* The blur radius defines the strength of the Gaussian Blur filter. The
80-
//default value is 20.0.
80+
// default value is 20.0.
8181
@property(assign, nonatomic) float _blurRadius;
8282

8383
@end

shell/browser/ui/native_view_mac.mm

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,6 @@ EventType EventTypeFromNS(NSEvent* event) {
122122
void NativeView::SetBounds(const gfx::Rect& bounds,
123123
const gin_helper::Dictionary& options) {
124124
SetBoundsForView(view_, bounds, options);
125-
NSRect frame = bounds.ToCGRect();
126-
// Calling setFrame manually does not trigger resizeSubviewsWithOldSize.
127-
[view_ resizeSubviewsWithOldSize:frame.size];
128125
}
129126

130127
gfx::Rect NativeView::GetBounds() const {

shell/browser/ui/view_utils_mac.mm

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "base/strings/string_number_conversions.h"
99
#include "base/strings/string_util.h"
10+
#include "shell/common/gin_converters/gfx_converter.h"
1011
#include "shell/common/gin_helper/dictionary.h"
1112
#include "ui/gfx/geometry/rect.h"
1213

@@ -42,6 +43,7 @@ void SetBoundsForView(NSView* view,
4243
std::string tfunction_name;
4344
float cx1 = 0.0, cy1 = 0.0, cx2 = 1.0, cy2 = 1.0;
4445
bool use_control_points = false;
46+
gfx::Rect from_bounds;
4547
if (options.Get("duration", &duration))
4648
animation = true;
4749
if (options.Get("timingFunction", &tfunction_name)) {
@@ -63,16 +65,30 @@ void SetBoundsForView(NSView* view,
6365
auto* superview = view.superview;
6466
if (superview && ![superview isFlipped]) {
6567
const auto superview_height = superview.frame.size.height;
66-
frame =
67-
NSMakeRect(bounds.x(), superview_height - bounds.y() - bounds.height(),
68-
bounds.width(), bounds.height());
68+
frame.origin.y = superview_height - bounds.y() - bounds.height();
6969
}
7070

7171
if (!animation) {
72-
view.frame = frame;
72+
[view setFrame:frame];
73+
[view setNeedsDisplay:YES];
74+
// Calling setFrame manually does not trigger resizeSubviewsWithOldSize.
75+
[view resizeSubviewsWithOldSize:frame.size];
7376
return;
7477
}
7578

79+
NSRect fromFrame = view.frame;
80+
if (options.Get("fromBounds", &from_bounds)) {
81+
if (superview && ![superview isFlipped]) {
82+
const auto superview_height = superview.frame.size.height;
83+
fromFrame =
84+
NSMakeRect(from_bounds.x(),
85+
superview_height - from_bounds.y() - from_bounds.height(),
86+
from_bounds.width(), from_bounds.height());
87+
} else {
88+
fromFrame = from_bounds.ToCGRect();
89+
}
90+
}
91+
7692
CAMediaTimingFunction* timing_function = nil;
7793
if (!use_control_points) {
7894
CAMediaTimingFunctionName timing_function_name =
@@ -95,15 +111,29 @@ void SetBoundsForView(NSView* view,
95111
[[CAMediaTimingFunction alloc] initWithControlPoints:cx1:cy1:cx2:cy2];
96112
}
97113

98-
[NSAnimationContext
99-
runAnimationGroup:^(NSAnimationContext* context) {
100-
context.duration = duration;
101-
context.timingFunction = timing_function;
102-
// Trigger the animation
103-
view.animator.frame = frame;
104-
}
105-
completionHandler:^{
106-
}];
114+
CABasicAnimation* positionAnimation =
115+
[CABasicAnimation animationWithKeyPath:@"position"];
116+
positionAnimation.duration = duration;
117+
positionAnimation.timingFunction = timing_function;
118+
positionAnimation.fromValue = @(fromFrame.origin);
119+
positionAnimation.toValue = @(frame.origin);
120+
if (fromFrame.size.width == frame.size.width &&
121+
fromFrame.size.height == frame.size.height) {
122+
[view.layer addAnimation:positionAnimation forKey:@"position"];
123+
} else {
124+
CABasicAnimation* sizeAnimation =
125+
[CABasicAnimation animationWithKeyPath:@"bounds.size"];
126+
sizeAnimation.duration = duration;
127+
sizeAnimation.timingFunction = timing_function;
128+
sizeAnimation.fromValue = @(fromFrame.size);
129+
sizeAnimation.toValue = @(frame.size);
130+
CAAnimationGroup* group = [CAAnimationGroup animation];
131+
group.duration = duration;
132+
group.timingFunction = timing_function;
133+
group.animations = @[ positionAnimation, sizeAnimation ];
134+
[view.layer addAnimation:group forKey:@"allMyAnimations"];
135+
}
136+
[view setFrame:frame];
107137
}
108138

109139
void ResetScalingForView(NSView* view) {

0 commit comments

Comments
 (0)