Add orx-image-fit

This commit is contained in:
Edwin Jakobs
2020-02-10 23:37:05 +01:00
parent ac9d0bb4f9
commit 77dee0c6af
2 changed files with 44 additions and 17 deletions

View File

@@ -2,11 +2,12 @@
Fits images in frames with two options, contain and cover. Similar to CSS object-fit (https://www.w3schools.com/css/css3_object-fit.asp) Fits images in frames with two options, contain and cover. Similar to CSS object-fit (https://www.w3schools.com/css/css3_object-fit.asp)
## usage `orx-image-fit` provides an extension function`imageFit` for `Drawer`.
## Usage
`imageFit(img: ColorBuffer, x: Double, y: Double, w: Double, h: Double, fitMethod, horizontalPosition:Double, verticalPosition:Double)` `imageFit(img: ColorBuffer, x: Double, y: Double, w: Double, h: Double, fitMethod, horizontalPosition:Double, verticalPosition:Double)`
fitMethod fitMethod
- `contain` - `contain`
- `cover` - `cover`
@@ -18,3 +19,20 @@ horizontal values
vertical values vertical values
- top ... bottom - top ... bottom
- `-1.0` ... `1.0` - `-1.0` ... `1.0`
## Example
A quick example that fits an image to the window rectangle with a 10 pixel margin. By default
`imageFit` uses the cover mode, which fills the target rectangle with an image.
```kotlin
fun main() = application {
program {
val image = loadImage("data/images/pm5544.png")
extend {
drawer.imageFit(10.0, 10.0, width - 20.0, height - 20.0)
}
}
}
```

View File

@@ -11,7 +11,16 @@ enum class FitMethod {
Contain Contain
} }
fun Drawer.imageFit(img: ColorBuffer, x: Double = 0.0, y: Double = 0.0, w: Double, h: Double, fitMethod:FitMethod = FitMethod.Cover, horizontalPosition:Double = 0.0, verticalPosition:Double = 0.0) { fun Drawer.imageFit(
img: ColorBuffer,
x: Double = 0.0,
y: Double = 0.0,
width: Double = img.width.toDouble(),
height: Double = img.height.toDouble(),
fitMethod: FitMethod = FitMethod.Cover,
horizontalPosition: Double = 0.0,
verticalPosition: Double = 0.0
) {
val sourceWidth = img.width.toDouble() val sourceWidth = img.width.toDouble()
val sourceHeight = img.height.toDouble() val sourceHeight = img.height.toDouble()
@@ -26,23 +35,23 @@ fun Drawer.imageFit(img: ColorBuffer, x: Double = 0.0, y: Double = 0.0, w: Doubl
when (fitMethod) { when (fitMethod) {
FitMethod.Contain -> { FitMethod.Contain -> {
targetWidth = w targetWidth = width
targetHeight = h targetHeight = height
if (w <= targetWidth) { if (width <= targetWidth) {
targetWidth = w targetWidth = width
targetHeight = (sourceHeight / sourceWidth) * w targetHeight = (sourceHeight / sourceWidth) * width
} }
if (h <= targetHeight) { if (height <= targetHeight) {
targetHeight = h targetHeight = height
targetWidth = (sourceWidth / sourceHeight) * h targetWidth = (sourceWidth / sourceHeight) * height
} }
val left = x val left = x
val right = x + w - targetWidth val right = x + width - targetWidth
val top = y val top = y
val bottom = y + h - targetHeight val bottom = y + height - targetHeight
targetX = map(-1.0, 1.0, left, right, horizontalPosition) targetX = map(-1.0, 1.0, left, right, horizontalPosition)
targetY = map(-1.0, 1.0, top, bottom, verticalPosition) targetY = map(-1.0, 1.0, top, bottom, verticalPosition)
@@ -57,12 +66,12 @@ fun Drawer.imageFit(img: ColorBuffer, x: Double = 0.0, y: Double = 0.0, w: Doubl
if (sourceWidth <= targetWidth) { if (sourceWidth <= targetWidth) {
targetWidth = sourceWidth targetWidth = sourceWidth
targetHeight = (h / w) * sourceWidth targetHeight = (height / width) * sourceWidth
} }
if (sourceHeight <= targetHeight) { if (sourceHeight <= targetHeight) {
targetHeight = sourceHeight targetHeight = sourceHeight
targetWidth = (w / h) * sourceHeight targetWidth = (width / height) * sourceHeight
} }
val left = 0.0 val left = 0.0
@@ -74,7 +83,7 @@ fun Drawer.imageFit(img: ColorBuffer, x: Double = 0.0, y: Double = 0.0, w: Doubl
targetY = map(-1.0, 1.0, top, bottom, verticalPosition) targetY = map(-1.0, 1.0, top, bottom, verticalPosition)
source = Rectangle(targetX, targetY, targetWidth, targetHeight) source = Rectangle(targetX, targetY, targetWidth, targetHeight)
target = Rectangle(x, y, w, h) target = Rectangle(x, y, width, height)
} }
} }