Skip to content

Commit dee2425

Browse files
authored
Merge pull request #74 from RougeWare/feature/scaled-by
Added multiplicative scaling
2 parents cd266c1 + ee98045 commit dee2425

File tree

5 files changed

+1596
-27
lines changed

5 files changed

+1596
-27
lines changed

.github/workflows/watchOS.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ jobs:
1818
run: |
1919
xcodebuild test \
2020
-sdk watchsimulator \
21-
-destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' \
21+
-destination 'platform=watchOS Simulator,name=Any watchOS Simulator Device' \
2222
-scheme RectangleTools

Sources/RectangleTools/Synthesized Conveniences/scaled.swift

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ public enum ScaleMethod {
308308

309309

310310
/// Discard the aspect ratio, and simply set the size to be the same as the parent's
311+
///
312+
/// - When scaling direction is `.down`, then this might result in zero, two, or all four sides touching or passing parent sides.
313+
/// - When scaling direction is `.upOrDown`, then all four sides will **always** touch parent sides.
311314
case stretch
312315
}
313316

@@ -331,7 +334,7 @@ where Length: MultiplicativeArithmetic,
331334
Length: Comparable,
332335
Length: ExpressibleByIntegerLiteral
333336
{
334-
/// Scales this within the given parent, using the given scaling method
337+
/// Scales this within the given parent, using the given scaling method & direction
335338
///
336339
/// - Parameters:
337340
/// - parent: The parent within which to scale this
@@ -421,10 +424,35 @@ where Length: MultiplicativeArithmetic,
421424
return scaleToMatchWidth()
422425

423426
case .stretch:
424-
return .init(measurementX: parent.measurementX,
425-
measurementY: parent.measurementY)
427+
switch direction {
428+
case .down:
429+
return .init(measurementX: min(self.measurementX, parent.measurementX),
430+
measurementY: min(self.measurementY, parent.measurementY))
431+
432+
case .upOrDown:
433+
return .init(measurementX: parent.measurementX,
434+
measurementY: parent.measurementY)
435+
}
426436
}
427437
}
438+
439+
440+
/// Scales this by the given multiplier, using the given scaling method & direction.
441+
///
442+
/// The edges are scaled, not the area.
443+
///
444+
/// - Parameters:
445+
/// - multiplier: Scales the outer dimensions of this by this amount. So a `2x2` scaled by `0.5` becomes a `1x1`, or scaled by `3.0` becomes a `6x6`.
446+
/// - direction: _optional_ - Which direction to scale this rectangle. Defaults to `.down`
447+
///
448+
/// - Returns: A scaled version of this rectangle, relative to the given parent
449+
func scaling(dimensionsBy multiplier: Length, direction: ScaleDirection = .down) -> Self {
450+
scaled(
451+
within: self * multiplier,
452+
method: .stretch,
453+
direction: direction
454+
)
455+
}
428456
}
429457

430458

@@ -436,7 +464,7 @@ where Length: MultiplicativeArithmetic,
436464
Length: ExpressibleByIntegerLiteral
437465
{
438466

439-
/// Scales this rectangle within the given parent, using the given scaling method
467+
/// Scales this rectangle within the given parent, using the given scaling method & direction
440468
///
441469
/// - Parameters:
442470
/// - parent: The parent rectangle within which to scale this rectangle
@@ -456,6 +484,27 @@ where Length: MultiplicativeArithmetic,
456484
}
457485

458486

487+
/// Scales this rectangle by the given multiplier, using the given scaling method & direction
488+
///
489+
/// The resulting rectangle's center point is the same as this one's.
490+
///
491+
/// The edges are scaled, not the area.
492+
///
493+
/// - Parameters:
494+
/// - multiplier: Scales the outer dimensions of the rectangle by this amount. So a `2x2` rectangle scaled by `0.5` becomes a `1x1` rectangle, or scaled by `3.0` becomes a `6x6` (assuming the direction allows that).
495+
/// - direction: _optional_ - Which direction to scale this rectangle. Defaults to `.down`
496+
///
497+
/// - Returns: A scaled version of this rectangle, relative to the given parent
498+
func scaling(dimensionsBy multiplier: Length, direction: ScaleDirection = .down) -> Self {
499+
scaled(
500+
within: Self(origin: .zero, size: size * multiplier)
501+
.centered(within: self),
502+
method: .stretch,
503+
direction: direction
504+
)
505+
}
506+
507+
459508
/// Returns a version of this rectangle which is centered within the given other rectangle, so that their `.center` values are the same
460509
///
461510
/// - Returns: This rectangle, centered within the given other one

Tests/RectangleToolsTests/Testing convenience functions.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import RectangleTools
1010

1111

1212

13+
// MARK: - Semi-equality
14+
1315
infix operator &&= : AssignmentPrecedence
1416
infix operator ≈≈ : ComparisonPrecedence
1517

@@ -57,3 +59,32 @@ where Value: DualTwoDimensional,
5759
lhs.firstDimensionPair ≈≈ rhs.firstDimensionPair
5860
&& lhs.secondDimensionPair ≈≈ rhs.secondDimensionPair
5961
}
62+
63+
64+
65+
// MARK: - Randomization
66+
67+
68+
69+
extension CGFloat {
70+
static func random() -> Self {
71+
random(in: -1024...1024)
72+
}
73+
}
74+
75+
76+
77+
extension CGPoint {
78+
static func random() -> Self {
79+
.init(x: .random(), y: .random())
80+
}
81+
}
82+
83+
84+
85+
// MARK: - Enumerations
86+
87+
enum AspectRatioExpectation {
88+
case sameAsOriginal
89+
case sameAsParent
90+
}

0 commit comments

Comments
 (0)