Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Live Wallpapers in Processing

Live Wallpapers in Processing

Avatar for The Funtasty

The Funtasty

February 21, 2019
Tweet

More Decks by The Funtasty

Other Decks in Technology

Transcript

  1. Processing void setup() { // Run once at start }

    void draw() { // Loop forever }
  2. Processing void setup() { // Set color space colorMode(HSB, 360,

    100, 100); // Set window dimensions size(1280, 720); } void draw() { // Draw gray background background(0, 0, 15); // Draw 250x250px ellipse at center of the screen ellipse(width / 2, height / 2, 250, 250); }
  3. Processing void setup() { // Set color space colorMode(HSB, 360,

    100, 100); // Set window dimensions size(1280, 720); } void draw() { // Draw gray background background(0, 0, 15); // Set color attributes fill(30, 100, 100); stroke(0, 0, 100); strokeWeight(6); // Draw 250x250px ellipse at center of the screen ellipse(width / 2, height / 2, 250, 250); }
  4. Processing ... void draw() { background(0, 0, 15); fill(30, 100,

    100); stroke(0, 0, 100); strokeWeight(6); ellipse(mouseX, mouseY, 250, 250); }
  5. Processing ... float posX = 0; float posY = 0;

    void draw() { background(0, 0, 15); fill(30, 100, 100); stroke(0, 0, 100); strokeWeight(6); posX = lerp(posX, mouseX, 0.05); posY = lerp(posY, mouseY, 0.05); ellipse(posX, posY, 250, 250); ellipse(mouseX, mouseY, 50, 50); }
  6. Processing - Useful properties - width, height, frameRate, frameCount, mouseX,

    mouseY,
 mousePressed, keyPressed … - Useful functions - random, perlin noise, trigonometry, calculation (lerp, map, constrain),
 … - Vectors - https://processing.org/reference/
  7. Processing ... float posX = 0; float posY = 0;

    void draw() { background(0, 0, 15); fill(30, 100, 100); stroke(0, 0, 100); strokeWeight(6); posX = lerp(posX, mouseX, 0.05); posY = lerp(posY, mouseY, 0.05); ellipse(posX, posY, 250, 250); ellipse(mouseX, mouseY, 50, 50); }
  8. Processing - Bunch of jars + simple IDE + community

    made libraries - IntelliJ? - Kotlin?
  9. Processing -> IntelliJ + Kotlin class MainSketch : PApplet() {

    override fun settings() { size(800, 480, PConstants.P3D) } override fun setup() { colorMode(PConstants.HSB, 360f, 100f, 100f) } override fun draw() { background(0) noFill() strokeWeight(PApplet.map(sin(millis() / 1000f), -1f, 1f, 2f, 12f)) stroke( PApplet.map(sin(millis() / 1000f), -1f, 1f, 0f, 360f), // Hue 100f, // Sat 100f // Brightness ) translate(width / 2f, height / 2f) rotateY(millis() / 1200f) rotateZ(millis() / 2000f) box(width / 5f) } }
  10. class MainSketch : PApplet() { override fun settings() { size(800,

    480, PConstants.P3D) } override fun setup() { colorMode(PConstants.HSB, 360f, 100f, 100f) } override fun draw() { background(0) noFill() strokeWeight(PApplet.map(sin(millis() / 1000f), -1f, 1f, 2f, 12f)) stroke( PApplet.map(sin(millis() / 1000f), -1f, 1f, 0f, 360f), // Hue 100f, // Sat 100f // Brightness ) translate(width / 2f, height / 2f) rotateY(millis() / 1200f) rotateZ(millis() / 2000f) box(width / 5f) } } Processing -> IntelliJ + Kotlin Processing sketch = PApplet Window configuration in settings()
  11. Processing -> IntelliJ + Kotlin class MainSketch : PApplet() {

    override fun settings() { size(800, 480, PConstants.P3D) } override fun setup() { colorMode(PConstants.HSB, 360f, 100f, 100f) } override fun draw() { background(0) noFill() strokeWeight(PApplet.map(sin(millis() / 1000f), -1f, 1f, 2f, 12f)) stroke( PApplet.map(sin(millis() / 1000f), -1f, 1f, 0f, 360f), // Hue 100f, // Sat 100f // Brightness ) translate(width / 2f, height / 2f) rotateY(millis() / 1200f) rotateZ(millis() / 2000f) box(width / 5f) } } DEMO TIME
  12. Processing on Android - PApplet + Android stuff - Lifecycle

    callbacks - Context - Display density
  13. Processing on Android - Fragment - PFragment (extends Fragment) -

    No AndroidX - Live Wallpaper - PWallpaper (extends WallpaperService) - Watchface - PWatchFaceCanvas (extends WatchFaceService) - PWatchFaceGLES (extends WatchFaceService) - VR
  14. Processing on Android override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val

    frameLayout = FrameLayout(this).apply { id = View.generateViewId() } setContentView( frameLayout, ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) ) val sketch = SimpleSketch() val pFragment = PFragment(sketch).apply { setView(frameLayout, this@SimpleActivity) } }
  15. Live Wallpaper - WallpaperService - provide instances of WallpaperEngine -

    WallpaperEngine - wallpaper implementation - draw on surface - handle user input - handle surface changes - handle lifecycle events
  16. Live Wallpaper <!-- AndroidManifest.xml --> ... <service android:name=".service.ProcessingWallpaperService" android:permission="android.permission.BIND_WALLPAPER"> <intent-filter>

    <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper"/> </service> ...
  17. Live Wallpaper <!-- AndroidManifest.xml --> ... <service android:name=".service.ProcessingWallpaperService" android:permission="android.permission.BIND_WALLPAPER"> <intent-filter>

    <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper"/> </service> ...
  18. Live Wallpaper class BasicWallpaperService : WallpaperService() { override fun onCreateEngine():

    Engine = BasicEngine() private inner class BasicEngine : WallpaperService.Engine() { // Draw, handle stuff, do wallpaper magic... } }
  19. Basic wallpaper override fun draw() { background(bgColor) translate(width / 2f,

    height / 2f) for (x in 0 until numX) { for (y in 0 until numY) { val noise = noise(x / 10f, y / 10f + millis() / 1000f) * noiseGain val position = dotPositions[x][y] // Draw a line strokeWeight(lineWeight) stroke(fgColor) line(position.x, position.y, 0f, position.x, position.y, noise) // Draw dot pushMatrix() noStroke() fill(fgColor) translate(0f, 0f, noise) ellipse(dotPositions[x][y].x, dotPositions[x][y].y, dotSize, dotSize) popMatrix() } } }
  20. Interactivity private var sensorManager: SensorManager? = null private var gyroscope:

    Sensor? = null override fun setup() { ... sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager gyroscope = sensorManager?.getDefaultSensor(Sensor.TYPE_GYROSCOPE) sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onResume() { super.onResume() sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onPause() { super.onPause() sensorManager?.unregisterListener(gyroListener) }
  21. Interactivity private var sensorManager: SensorManager? = null private var gyroscope:

    Sensor? = null override fun setup() { ... sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager gyroscope = sensorManager?.getDefaultSensor(Sensor.TYPE_GYROSCOPE) sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onResume() { super.onResume() sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onPause() { super.onPause() sensorManager?.unregisterListener(gyroListener) }
  22. Interactivity private var sensorManager: SensorManager? = null private var gyroscope:

    Sensor? = null override fun setup() { ... sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager gyroscope = sensorManager?.getDefaultSensor(Sensor.TYPE_GYROSCOPE) sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onResume() { super.onResume() sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL) } override fun onPause() { super.onPause() sensorManager?.unregisterListener(gyroListener) }
  23. Interactivity override fun draw() { ... // rotation in radians

    rotateX(-rotation[0]) rotateY(rotation[1]) ... } DEMO TIME
  24. Homescreen Wallpaper Settings Store data class WallpaperConfig( val fgColor: HsvColor,

    val bgColor: HsvColor, val noiseGain: Float ) WallpaperSketch SettingsActivity WallpaperSketch load config, push config update, persist config observe config updates load persisted config data class HsvColor( // 0 to 360 val hue: Int, // 0 to 100 val saturation: Int, // 0 to 100 val brightness: Int )
  25. Wallpaper Settings override fun onResume() { super.onResume() sensorManager?.registerListener(gyroListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL)

    observeConfigObservabler.init().execute { config = it } getConfigSingler.init().execute { config = it } } override fun onPause() { super.onPause() sensorManager?.unregisterListener(gyroListener) observeConfigObservabler.dispose() getConfigSingler.dispose() } override fun draw() { background(config.bgColor.toColorInt()) ... }
  26. Wallpaper Settings // SettingsViewModel.kt fun onNoiseGainChanged(gain: Int) { config =

    config.copy(noiseGain = gain.toFloat()) previewConfigCompletabler .init(config) .execute { } } fun onSaveClick() { saveConfigCompletabler.init(config).execute { onSaveLiveData.value = true } }
  27. Q&A