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

Live Wallpapers in Processing

Live Wallpapers in Processing

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