Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
soywiz committed Dec 19, 2023
1 parent 823b51b commit 04acbec
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
7 changes: 4 additions & 3 deletions .obsidian/plugins/obsidian-icon-folder/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"emojiStyle": "twemoji",
"iconColor": null,
"recentlyUsedIcons": [
"TiBallBowling",
"FasDisplay",
"🖥",
"🗺",
"RiTreeLine",
"IbTreeMapDown1"
"RiTreeLine"
],
"recentlyUsedIconsSize": 5,
"rules": [],
Expand Down Expand Up @@ -132,5 +132,6 @@
"views/views.md": "IbTreeMapDown1",
"views/views-standard.md": "RiTreeLine",
"roadmap": "🗺",
"roadmap/targets.canvas": "FasDisplay"
"roadmap/targets.canvas": "FasDisplay",
"views/custom-effects.md": "TiBallBowling"
}
Binary file added i/motion-blur.webm
Binary file not shown.
61 changes: 61 additions & 0 deletions views/custom-effects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Implementing a Motion Blur effect

KorGE provides a `DirectionalBlurFilter` that allows to specify a direction and amplitude for the blurring. With a small decorator that detects and computes the view movement speed and angle creating and attaching an `addUpdater` to the view, it can determine which amount and direction for the filter to apply in every moment.

Demo preview:

![Motion Blur](/i/motion-blur.webm)

Demo code:

```kotlin
import korlibs.image.color.*
import korlibs.io.lang.*
import korlibs.korge.*
import korlibs.korge.scene.*
import korlibs.korge.tween.*
import korlibs.korge.view.*
import korlibs.korge.view.filter.*
import korlibs.math.*
import korlibs.math.geom.*
import korlibs.time.*
import kotlin.math.*

suspend fun main() = Korge { sceneContainer().changeTo { MyScene() } }

class MyScene : Scene() {
override suspend fun SContainer.sceneMain() {
val view = circle(16.0, fill = Colors.RED).xy(100, 100)
view.motionBlur(scale = 2.0, exp = 0.75)
while (true) {
tween(view::x[300], view::y[300], time = 1.seconds)
tween(view::x[100], view::y[300], time = 1.seconds)
tween(view::x[100], view::y[100], time = 1.seconds)
}
}
}

fun View.motionBlur(scale: Double = 5.0, exp: Double = 0.75, min: Double = 0.0, max: Double = 20.0): Cancellable {
val view = this
val filter = DirectionalBlurFilter()
this.addFilter(filter)
var now = Point()
var last = Point()
last = view.pos
val updater = addUpdater {
val timeScale = 16.milliseconds / it
now = view.pos
if (now != last) {
filter.angle = Angle.between(last, now)
filter.radius = (Point.distance(last, now) * scale * timeScale).pow(exp).clamp(min, max)
} else {
filter.radius = 0.0
}
last = now
}
return Cancellable {
this.removeFilter(filter)
updater.cancel()
}
}
```

0 comments on commit 04acbec

Please sign in to comment.