moveCorner method
Implementation
Rect moveCorner({
required Offset delta,
required Corner corner,
required Size shortest,
required Size? longest,
required double? largest,
required Rect boundaries,
required double? aspectRatio,
}) {
double l = left, t = top, r = right, b = bottom;
lLarge([double? largest]) => [left + delta.dx, boundaries.left, if (longest != null) right - longest.width, ?largest].reduce(max);
lEnlarge([double? largest]) => l = lLarge(largest);
lShort() => min(left + delta.dx, right - shortest.width);
lShorten() => l = lShort();
tLarge([double? largest]) => [top + delta.dy, boundaries.top, if (longest != null) bottom - longest.height, ?largest].reduce(max);
tEnlarge([double? largest]) => t = tLarge(largest);
tShort() => min(top + delta.dy, bottom - shortest.height);
tShorten() => t = tShort();
rLarge([double? largest]) => [right + delta.dx, boundaries.right, if (longest != null) left + longest.width, ?largest].reduce(min);
rEnlarge([double? largest]) => r = rLarge(largest);
rShort() => max(right + delta.dx, left + shortest.width);
rShorten() => r = rShort();
bLarge([double? largest]) => [bottom + delta.dy, boundaries.bottom, if (longest != null) top + longest.height, ?largest].reduce(min);
bEnlarge([double? largest]) => b = bLarge(largest);
bShort() => max(bottom + delta.dy, top + shortest.height);
bShorten() => b = bShort();
if (aspectRatio != null) {
double boundaryX, boundaryY, overflowX, overflowY;
Function() boundByX, boundByY;
final denom = aspectRatio + 1.0;
switch (corner) {
case .topLeft:
final part = (delta.dx + delta.dy) / denom;
l = left + part * aspectRatio;
t = top + part;
if (t < top) {
boundaryX = longest == null ? boundaries.left : max(boundaries.left, right - longest.width);
boundaryY = longest == null ? boundaries.top : max(boundaries.top, bottom - longest.height);
overflowX = boundaryX - l;
overflowY = boundaryY - t;
} else {
boundaryX = right - shortest.width;
boundaryY = bottom - shortest.height;
overflowX = l - boundaryX;
overflowY = t - boundaryY;
}
boundByX = () {
l = boundaryX;
t = bottom - (right - l) / aspectRatio;
};
boundByY = () {
t = boundaryY;
l = right - (bottom - t) * aspectRatio;
};
case .topRight:
final part = (-delta.dx + delta.dy) / denom;
t = top + part;
r = right - part * aspectRatio;
if (t < top) {
boundaryX = longest == null ? boundaries.right : min(boundaries.right, left + longest.width);
boundaryY = longest == null ? boundaries.top : max(boundaries.top, bottom - longest.height);
overflowX = r - boundaryX;
overflowY = boundaryY - t;
} else {
boundaryX = left + shortest.width;
boundaryY = bottom - shortest.height;
overflowX = boundaryX - r;
overflowY = t - boundaryY;
}
boundByX = () {
r = boundaryX;
t = bottom - (r - left) / aspectRatio;
};
boundByY = () {
t = boundaryY;
r = left + (bottom - t) * aspectRatio;
};
case .bottomLeft:
final part = (-delta.dx + delta.dy) / denom;
l = left - part * aspectRatio;
b = bottom + part;
if (b > bottom) {
boundaryX = longest == null ? boundaries.left : max(boundaries.left, right - longest.width);
boundaryY = longest == null ? boundaries.bottom : min(boundaries.bottom, top + longest.height);
overflowX = boundaryX - l;
overflowY = b - boundaryY;
} else {
boundaryX = right - shortest.width;
boundaryY = top + shortest.height;
overflowX = l - boundaryX;
overflowY = boundaryY - b;
}
boundByX = () {
l = boundaryX;
b = top + (right - l) / aspectRatio;
};
boundByY = () {
b = boundaryY;
l = right - (b - top) * aspectRatio;
};
case .bottomRight:
final part = (delta.dx + delta.dy) / denom;
b = bottom + part;
r = right + part * aspectRatio;
if (b > bottom) {
boundaryX = longest == null ? boundaries.right : min(boundaries.right, left + longest.width);
boundaryY = longest == null ? boundaries.bottom : min(boundaries.bottom, top + longest.height);
overflowX = r - boundaryX;
overflowY = b - boundaryY;
} else {
boundaryX = left + shortest.width;
boundaryY = top + shortest.height;
overflowX = boundaryX - r;
overflowY = boundaryY - b;
}
boundByX = () {
r = boundaryX;
b = top + (r - left) / aspectRatio;
};
boundByY = () {
b = boundaryY;
r = left + (b - top) * aspectRatio;
};
}
if (overflowX > 0) {
if (overflowY > 0) {
if (overflowX > overflowY) {
boundByX();
} else {
boundByY();
}
} else {
boundByX();
}
} else if (overflowY > 0) {
boundByY();
}
} else if (largest != null) {
largeBound() {
final y = delta.dy.abs();
final x = delta.dx.abs();
double k = 1;
if (x != 0 && y != 0) {
/// k == largestDelta.distance / delta.distance
/// (kx + width)(ky + height) == largest --> Quadratic equation
k = -height/2/y -width/2/x + sqrt(pow(x * height + y * width, 2) - 4 * x * y * (width * height - largest)) / 2 / x / y;
} else if (x != 0) {
k = (largest/height - width) / x;
} else if (y != 0) {
k = (largest/width - height) / y;
}
if (k < 1) {
delta = delta * k;
}
}
/// first shorten then enlarge -> thus the enlarge can get more space
switch (corner) {
case .topLeft:
if (delta.dx > 0) {
lShorten();
if (delta.dy > 0) {
tShorten();
} else {
tEnlarge(bottom - largest/(right - l));
}
} else {
if (delta.dy > 0) {
tShorten();
lEnlarge(right - largest/(bottom - t));
} else {
delta = Offset(lLarge(), tLarge()) - topLeft;
largeBound();
l = left + delta.dx;
t = top + delta.dy;
}
}
case .topRight:
if (delta.dx < 0) {
rShorten();
if (delta.dy > 0) {
tShorten();
} else {
tEnlarge(bottom - largest/(r - left));
}
} else {
if (delta.dy > 0) {
tShorten();
rEnlarge(left + largest/(bottom - t));
} else {
delta = Offset(rLarge(), tLarge()) - topRight;
largeBound();
r = right + delta.dx;
t = top + delta.dy;
}
}
case .bottomLeft:
if (delta.dx > 0) {
lShorten();
if (delta.dy < 0) {
bShorten();
} else {
bEnlarge(top + largest/(right - l));
}
} else {
if (delta.dy < 0) {
bShorten();
lEnlarge(right - largest/(b - top));
} else {
delta = Offset(lLarge(), bLarge()) - bottomLeft;
largeBound();
l = left + delta.dx;
b = bottom + delta.dy;
}
}
case .bottomRight:
if (delta.dx < 0) {
rShorten();
if (delta.dy < 0) {
bShorten();
} else {
bEnlarge(top + largest/(r - left));
}
} else {
if (delta.dy < 0) {
bShorten();
rEnlarge(left + largest/(b - top));
} else {
delta = Offset(rLarge(), bLarge()) - bottomRight;
largeBound();
r = right + delta.dx;
b = bottom + delta.dy;
}
}
}
} else {
ll() => delta.dx < 0 ? lEnlarge() : lShorten();
tt() => delta.dy < 0 ? tEnlarge() : tShorten();
rr() => delta.dx > 0 ? rEnlarge() : rShorten();
bb() => delta.dy > 0 ? bEnlarge() : bShorten();
switch (corner) {
case .topLeft: tt(); ll();
case .topRight: tt(); rr();
case .bottomLeft: bb(); ll();
case .bottomRight: bb(); rr();
}
}
return Rect.fromLTRB(l, t, r, b);
}