master 8962cd7c2d6f cached
98 files
214.8 KB
53.9k tokens
452 symbols
2 requests
Download .txt
Showing preview only (241K chars total). Download the full file or copy to clipboard to get everything.
Repository: danielzeller/Depth-LIB-Android-
Branch: master
Commit: 8962cd7c2d6f
Files: 98
Total size: 214.8 KB

Directory structure:
gitextract_4xerzip3/

├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── no/
│       │           └── agens/
│       │               └── depth/
│       │                   └── ApplicationTest.java
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── no/
│           │       └── agens/
│           │           └── depth/
│           │               ├── BearSceneView.java
│           │               ├── Foam.java
│           │               ├── MenuAnimation.java
│           │               ├── PlayGroundActivity.java
│           │               ├── RenderableBear.java
│           │               ├── RenderableTree.java
│           │               ├── RootActivity.java
│           │               ├── SeekBarProgressChangeListener.java
│           │               ├── Smoke.java
│           │               ├── TransitionHelper.java
│           │               ├── Water.java
│           │               ├── WaterFragment.java
│           │               ├── WaterSceneView.java
│           │               └── WindFragment.java
│           └── res/
│               ├── drawable/
│               │   ├── bear_bg_gradient.xml
│               │   ├── circle.xml
│               │   ├── fab_bg.xml
│               │   ├── menu_btn.xml
│               │   ├── menu_btn2.xml
│               │   ├── menu_btn3.xml
│               │   └── menu_btn4.xml
│               ├── layout/
│               │   ├── activity_root.xml
│               │   ├── fragment_playground.xml
│               │   ├── fragment_water.xml
│               │   ├── fragment_wind.xml
│               │   └── menu_item.xml
│               ├── menu/
│               │   └── menu_root.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-w820dp/
│                   └── dimens.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── lib/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── no/
│       │           └── agens/
│       │               └── depth/
│       │                   └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── no/
│       │   │       └── agens/
│       │   │           └── depth/
│       │   │               └── lib/
│       │   │                   ├── CircularSplashView.java
│       │   │                   ├── ColorAnimator.java
│       │   │                   ├── CustomShadow.java
│       │   │                   ├── DepthLayout.java
│       │   │                   ├── DepthRendrer.java
│       │   │                   ├── MaterialMenuDrawable.java
│       │   │                   ├── MathHelper.java
│       │   │                   ├── RectEvaluator.java
│       │   │                   ├── RectFEvaluator.java
│       │   │                   ├── RippleHelper.java
│       │   │                   ├── headers/
│       │   │                   │   ├── AuraDrawable.java
│       │   │                   │   ├── NoiseEffect.java
│       │   │                   │   ├── Particle.java
│       │   │                   │   ├── ParticleSystem.java
│       │   │                   │   ├── PathBitmapMesh.java
│       │   │                   │   └── Renderable.java
│       │   │                   └── tween/
│       │   │                       ├── FrameRateCounter.java
│       │   │                       ├── TRectFEvaluator.java
│       │   │                       └── interpolators/
│       │   │                           ├── BackIn.java
│       │   │                           ├── BackInOut.java
│       │   │                           ├── BackOut.java
│       │   │                           ├── CircIn.java
│       │   │                           ├── CircInOut.java
│       │   │                           ├── CircOut.java
│       │   │                           ├── ElasticIn.java
│       │   │                           ├── ElasticInOut.java
│       │   │                           ├── ElasticOut.java
│       │   │                           ├── ExpoIn.java
│       │   │                           ├── ExpoInOut.java
│       │   │                           ├── ExpoOut.java
│       │   │                           ├── QuadIn.java
│       │   │                           ├── QuadInOut.java
│       │   │                           ├── QuadOut.java
│       │   │                           ├── QuartIn.java
│       │   │                           ├── QuartInOut.java
│       │   │                           ├── QuartOut.java
│       │   │                           ├── QuintIn.java
│       │   │                           ├── QuintInOut.java
│       │   │                           ├── QuintOut.java
│       │   │                           ├── SineIn.java
│       │   │                           ├── SineInOut.java
│       │   │                           └── SineOut.java
│       │   └── res/
│       │       └── values/
│       │           ├── dept_view.xml
│       │           └── values.xml
│       └── test/
│           └── java/
│               └── no/
│                   └── agens/
│                       └── depth/
│                           └── ExampleUnitTest.java
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.gradle
/local.properties
.DS_Store
/build
/captures
.idea
*.iml


================================================
FILE: .travis.yml
================================================
language: android

jdk:
    - oraclejdk7

android:
  components:
    - platform-tools
    - tools
    - build-tools-23.0.3
    - android-23
    - extra-android-support
    - extra-android-m2repository

# as per http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
sudo: false

before_install:
    - export JAVA7_HOME=/usr/lib/jvm/java-7-oracle
    - export JAVA_HOME=$JAVA7_HOME
script:
    - ./gradlew clean assemble check


================================================
FILE: LICENSE
================================================
Authors:
Daniel Zeller <daniel@agens.no>

The MIT License (MIT)
Copyright (c) 2016 Agens AS (http://agens.no/)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Depth-LIB-Android

This library adds depth/thickness to views. 

[<img src="https://cdn.dribbble.com/users/655449/screenshots/2179342/menu_dribble.gif" width="400"/>](https://youtu.be/d2H1z6bmD9w)

[See demo on youtube](https://youtu.be/d2H1z6bmD9w)

## Demo 
The demo code contains some examples of Canvas drawing techniques to create particle systems, waves and grain effect. I wasn't really happy with the default shadows in Android because they start misbehaving when they are rotated so I made my own shadow solution. The project also contains various tweening functions for animations, and uses the Facebook rebound lib for some tweens. Don't expect too much from this lib, it was written as a quick prototype, so the visuals look good but the code behind it could have been better.


## More Libraries
Make sure to also checkout Metaballs LIB:

[<img src="https://github.com/danielzeller/MetaBalls-LIB-Android/blob/master/Artwork/TwoClips.gif?raw=true" width="400"/>](https://github.com/danielzeller/MetaBalls-LIB-Android)

[LINK](https://github.com/danielzeller/MetaBalls-LIB-Android)

and Blur LIB:

[<img src="https://github.com/danielzeller/Blur-LIB-Android/blob/master/Artwork/Transition.gif?raw=true" width="400"/>](https://github.com/danielzeller/Blur-LIB-Android)

[LINK](https://github.com/danielzeller/Blur-LIB-Android)


## Contact

You can reach me on twitter as [@zellah](https://twitter.com/zellah) or [danielzeller.no](http://danielzeller.no/).


## Who's behind this?

Developed by [@zellah](https://twitter.com/zellah)


================================================
FILE: app/.gitignore
================================================
/build
app.iml

================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "no.agens.depth"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        abortOnError false
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation project(':lib')
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/danielzeller/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: app/src/androidTest/java/no/agens/depth/ApplicationTest.java
================================================
package no.agens.depth;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="no.agens.depth" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="no.agens.depth.PlayGroundActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="no.agens.depth.RootActivity"
            android:label="@string/title_activity_root" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


================================================
FILE: app/src/main/java/no/agens/depth/BearSceneView.java
================================================
package no.agens.depth;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import no.agens.depth.lib.MathHelper;
import no.agens.depth.lib.headers.AuraDrawable;
import no.agens.depth.lib.headers.NoiseEffect;
import no.agens.depth.lib.headers.ParticleSystem;
import no.agens.depth.lib.headers.Renderable;
import no.agens.depth.lib.tween.FrameRateCounter;

/**
 * Created by danielzeller on 01.10.14.
 */
public class BearSceneView extends View {


    public static final int WIND_RANDOMIZE_INTERVAL = 300;
    private Renderable[] renderables;

    public BearSceneView(Context context) {
        super(context);

    }

    private float wind = 10f;
    float windRanomizerTarget;
    float windRanomizerEased;

    ParticleSystem flames;
    ParticleSystem sparks;
    Smoke smoke;

    public BearSceneView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BearSceneView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (renderables == null) {
            init();
        }
    }

    private void init() {
        renderables = new Renderable[17];
        Bitmap treeB = BitmapFactory.decodeResource(getResources(), R.mipmap.tree);
        addTree(treeB,getMeasuredWidth() * 0.18f, getMeasuredHeight() * -0.65f, 0.28f, 0.46f);
        addTree(treeB,getMeasuredWidth() * 0.6f, getMeasuredHeight() * -0.65f, 0.33f, 0.46f);
        addTree(treeB,getMeasuredWidth() * 0.45f, getMeasuredHeight() * -0.45f, 0.5f, 0.8f);
        addTree(treeB,getMeasuredWidth() * 0.13f, getMeasuredHeight() * -0.65f, 0.3f, 0.46f);
        addTree(treeB,getMeasuredWidth() * 0.83f, getMeasuredHeight() * -0.2f, 0.5f, 1f);
        addTree(treeB,getMeasuredWidth() * 0.02f, getMeasuredHeight() * -0.1f, 0.8f, 1f);
        addTree(treeB,getMeasuredWidth() * 0.18f, getMeasuredHeight() * 0.15f, 0.8f, 1f);
        addTree(treeB,getMeasuredWidth() * 0.7f, getMeasuredHeight() * -0.1f, 0.8f, 1f);

        Bitmap bear1 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_1);
        Bitmap bear2 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_2);
        Bitmap bear3 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_white);
        Bitmap stones = BitmapFactory.decodeResource(getResources(), R.drawable.stones);
        Bitmap smoke = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);
        Bitmap grunge = BitmapFactory.decodeResource(getResources(), R.drawable.grunge);
        addFire(smoke, stones, getMeasuredWidth() * 0.61f, getMeasuredHeight() * 0.8f);
        addBear(getMeasuredWidth() * 0.636f, getMeasuredHeight() * 0.59f, bear1, bear2);
        addWhiteBear(getMeasuredWidth() * 0.44f, getMeasuredHeight() * 0.66f, bear3);
        setLayerType(View.LAYER_TYPE_HARDWARE, null);
        addGrunge(grunge);
    }

    private void addGrunge(Bitmap grunge) {
        NoiseEffect noise = new NoiseEffect(grunge, 100, 2.5f);
        renderables[index] = noise;
        noise.setNoiseIntensity(0.25f);
        index += 1;
    }

    private void addFire(Bitmap smoke, Bitmap stones, float x, float y) {

        renderables[index] = new AuraDrawable(getResources().getDrawable(R.drawable.aura_gradient), new Rect((int) (getMeasuredWidth() * 0.44f), (int) (getMeasuredHeight() * 0.4f), (int) (getMeasuredWidth() * 0.8f), (int) (getMeasuredHeight() * 1.1f)));
        index += 1;
        renderables[index] = new AuraDrawable(getResources().getDrawable(R.drawable.aura_gradient_inner), new Rect((int) (getMeasuredWidth() * 0.5f), (int) (getMeasuredHeight() * 0.6f), (int) (getMeasuredWidth() * 0.72f), (int) (getMeasuredHeight() * 1f)));
        index += 1;

        float density = getResources().getDisplayMetrics().density;
        float randomXPlacement = 5f * density;
        flames = new ParticleSystem(x, y, 30, -30f * density, randomXPlacement);
        sparks = new ParticleSystem(x, y, 600, -30f * density, randomXPlacement);

        renderables[index] = flames;
        flames.setParticleSize((int) (8f * density));
        flames.setRandomMovementX(20f * density);
        flames.setRandomMovementY(1.5f * density);
        flames.setColors(getResources().getColor(R.color.fire_start_color), getResources().getColor(R.color.fire_end_color));
        index += 1;

        renderables[index] = sparks;
        sparks.setParticleSize((int) (1f * density));
        sparks.setRandomMovementX(25f * density);
        sparks.setRandomMovementY(2.5f * density);
        sparks.setRandomMovementChangeInterval(900);
        sparks.setColors(getResources().getColor(R.color.fire_start_color), getResources().getColor(R.color.fire_start_color));
        sparks.setMinYCoord(0);
        index += 1;

        renderables[index] = new Renderable(stones, x - randomXPlacement * 2f, y);
        index += 1;
        this.smoke = new Smoke(smoke, x, getMeasuredHeight() * 0.68f, 110 * density, 60 * density, 8, density);
        renderables[index] = this.smoke;
        index += 1;

    }

    private void addWhiteBear(float v, float v1, Bitmap bear3) {
        renderables[index] = new Renderable(bear3, v, v1);
        index += 1;
    }

    private void addBear(float v, float v1, Bitmap bear1, Bitmap bear2) {
        renderables[index] = new RenderableBear(new Bitmap[]{bear1, bear2}, v, v1);
        index += 1;
    }

    int index = 0;

    void addTree(Bitmap bitmap, float x, float y, float scale, float alpha) {

        renderables[index] = new RenderableTree(bitmap, x, y, alpha);
        renderables[index].setScale(scale, scale);
        index += 1;
    }
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        destroyResources();
    }

    private void destroyResources() {

        for (Renderable renderable: renderables)
            renderable.destroy();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (renderables == null && getWidth() != 0)
            init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float deltaTime = FrameRateCounter.timeStep();
        windRanomizerEased += ((windRanomizerTarget - windRanomizerEased) * 4f) * deltaTime;
        for (Renderable renderable : renderables) {
            renderable.draw(canvas);
            if (renderable instanceof Smoke || renderable instanceof ParticleSystem)
                renderable.update(deltaTime, wind);
            else
                renderable.update(deltaTime, wind + windRanomizerEased);
        }
        if (lastWindRandomChange + WIND_RANDOMIZE_INTERVAL < System.currentTimeMillis()) {
            lastWindRandomChange = System.currentTimeMillis();
            float randomSpeedInterval = Math.max(wind / 2, 1);
            windRanomizerTarget = (float) MathHelper.rand.nextInt((int) randomSpeedInterval) - randomSpeedInterval / 2f;
        }
        if (!pause)
            invalidate();
    }

    public void setPause(boolean pause) {
        this.pause = pause;
        if (!pause) {
            FrameRateCounter.timeStep();
            invalidate();
            for (Renderable renderable : renderables)
                renderable.resume();
        } else {
            for (Renderable renderable : renderables)
                renderable.pause();
        }
    }

    private boolean pause = false;

    long lastWindRandomChange;


    public void setWind(int wind) {
        this.wind = wind;
    }

    float LOWEST_FLAMES_COORD = 0.8f;
    float HIGHEST_FLAMES_COORD = 0.4f;
    float HIGHEST_SMOKE_COORD = 0.6f;

    public void setFlamesHeight(int progress) {
        float flamesHeight = getYCoordByPercent(LOWEST_FLAMES_COORD - ((LOWEST_FLAMES_COORD - HIGHEST_FLAMES_COORD) * ((float) progress / 100f)));
        flames.setMinYCoord(flamesHeight);
        float smokeYCoord = getYCoordByPercent(LOWEST_FLAMES_COORD - ((LOWEST_FLAMES_COORD - HIGHEST_SMOKE_COORD) * ((float) progress / 100f)));
        smoke.setY(smokeYCoord);
    }


    private float getYCoordByPercent(float percent) {
        return getHeight() * percent;
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/Foam.java
================================================
package no.agens.depth;

import android.graphics.Bitmap;
import android.graphics.Path;
import android.graphics.PathMeasure;

import no.agens.depth.lib.MathHelper;
import no.agens.depth.lib.headers.PathBitmapMesh;

public class Foam extends PathBitmapMesh {
    private float verticalOffset;

    void update(float deltaTime) {

        for (int i = 0; i < foamCoords.length; i++) {
            easedFoamCoords[i] += ((foamCoords[i] - easedFoamCoords[i])) * deltaTime;
        }
    }

    float[] foamCoords;
    float[] easedFoamCoords;
    float minHeight, maxHeight;

    public Foam(int horizontalSlices, int verticalSlices, Bitmap bitmap, float minHeight, float maxHeight, int animDuration) {
        super(horizontalSlices, verticalSlices, bitmap,animDuration);
        setupFoam(horizontalSlices);
        this.minHeight = minHeight;
        this.maxHeight = maxHeight;

    }


    private void setupFoam(int verts) {
        foamCoords = new float[verts];
        easedFoamCoords = new float[verts];
        for (int i = 0; i < verts; i++) {
            foamCoords[i] = 0;
            easedFoamCoords[i] = 0;
        }
    }

    void calcWave() {
        for (int i = 0; i < foamCoords.length; i++) {
            foamCoords[i] = MathHelper.randomRange(minHeight, maxHeight);
        }
    }



    public void matchVertsToPath(Path path, float extraOffset) {
        PathMeasure pm = new PathMeasure(path, false);
        int index = 0;
        for (int i = 0; i < staticVerts.length / 2; i++) {

            float yIndexValue = staticVerts[i * 2 + 1];
            float xIndexValue = staticVerts[i * 2];


            float percentOffsetX = (0.000001f + xIndexValue) / bitmap.getWidth();
            float percentOffsetX2 = (0.000001f + xIndexValue) / (bitmap.getWidth() + extraOffset);
            percentOffsetX2 += pathOffsetPercent;
            pm.getPosTan(pm.getLength() * (1f - percentOffsetX), coords, null);
            pm.getPosTan(pm.getLength() * (1f - percentOffsetX2), coords2, null);

            if (yIndexValue == 0) {
                setXY(drawingVerts, i, coords[0], coords2[1] + verticalOffset);
            } else {
                float desiredYCoord = Math.max(coords2[1], coords2[1] + easedFoamCoords[Math.min(easedFoamCoords.length - 1, index)]);
                setXY(drawingVerts, i, coords[0], desiredYCoord + verticalOffset);

                index += 1;

            }
        }
    }

    public void setVerticalOffset(float verticalOffset) {
        this.verticalOffset = verticalOffset;
    }


}


================================================
FILE: app/src/main/java/no/agens/depth/MenuAnimation.java
================================================
package no.agens.depth;

public interface MenuAnimation {
      void animateTOMenu();
      void revertFromMenu();
      void exitFromMenu();
}


================================================
FILE: app/src/main/java/no/agens/depth/PlayGroundActivity.java
================================================
package no.agens.depth;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;

import no.agens.depth.lib.DepthLayout;
import no.agens.depth.lib.MaterialMenuDrawable;

public class PlayGroundActivity extends Activity {

    private DepthLayout depthView;
    private static final float MAX_ROTATION_X = 90;
    private static final float MAX_ROTATION_Y = 90;
    private static final float MAX_ROTATION_Z = 360;

    private static final float MAX_ELEVATION = 50;
    private static final float MAX_DEPTH = 20;
    private static final float CAMERA_DISTANCE = 6000f;
    private int seekBarColor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_playground);
        seekBarColor = getResources().getColor(R.color.fab);
        depthView = (DepthLayout) findViewById(R.id.depth_view);
        depthView.setCameraDistance((CAMERA_DISTANCE * getResources().getDisplayMetrics().density));
        setupSeekBars();
        makeAppFullscreen();
        setupMenuButton();
    }
    private void setupMenuButton() {
        ImageView menu = (ImageView) findViewById(R.id.menu);
        menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        MaterialMenuDrawable menuIcon = new MaterialMenuDrawable(this, Color.WHITE, MaterialMenuDrawable.Stroke.THIN, WaterFragment.TRANSFORM_DURATION);
        menu.setImageDrawable(menuIcon);
        menuIcon.setIconState(MaterialMenuDrawable.IconState.ARROW);
    }
    private void setupSeekBars() {
        setupRotationXSeekbar();
        setupRotationYSeekbar();
        setupRotationZSeekbar();
        setupElevationSeekbar();
        setupDepthSeekbar();

    }

    private void makeAppFullscreen() {
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }

    private void setupDepthSeekbar() {
        SeekBar depth = (SeekBar) findViewById(R.id.depth_seekbar);
        WindFragment.setProgressBarColor(depth, seekBarColor);
        depth.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                depthView.setDepth(MAX_DEPTH * getResources().getDisplayMetrics().density * ((float) progress / (float) seekBar.getMax()));
            }
        });
        depth.setProgress((int) (depth.getMax() * 0.1f));
    }

    private SeekBar setupRotationXSeekbar() {
        SeekBar rotationX = (SeekBar) findViewById(R.id.rotation_x_seekbar);
        WindFragment.setProgressBarColor(rotationX, seekBarColor);
        rotationX.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                depthView.setRotationX(-MAX_ROTATION_X + (MAX_ROTATION_X * 2f) * ((float) progress / (float) seekBar.getMax()));
            }
        });
        rotationX.setProgress((int) (rotationX.getMax() * 0.1f));
        return rotationX;

    }

    private void setupRotationYSeekbar() {
        SeekBar rotationY = (SeekBar) findViewById(R.id.rotation_y_seekbar);
        rotationY.setProgress((int) (rotationY.getMax() * 0.5f));
        WindFragment.setProgressBarColor(rotationY, seekBarColor);
        rotationY.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                depthView.setRotationY(-MAX_ROTATION_Y + (MAX_ROTATION_Y * 2f) * ((float) progress / (float) seekBar.getMax()));
            }
        });
    }

    private void setupRotationZSeekbar() {
        SeekBar rotation = (SeekBar) findViewById(R.id.rotation_z_seekbar);
        rotation.setProgress(0);
        WindFragment.setProgressBarColor(rotation, seekBarColor);
        rotation.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                depthView.setRotation(-MAX_ROTATION_Z * ((float) progress / (float) seekBar.getMax()));
            }
        });

    }

    private void setupElevationSeekbar() {
        SeekBar elevation = (SeekBar) findViewById(R.id.elevation_seekbar);
        elevation.setProgress(0);
        WindFragment.setProgressBarColor(elevation, seekBarColor);
        elevation.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                depthView.setCustomShadowElevation((MAX_ELEVATION * ((float) progress / (float) seekBar.getMax())) * getResources().getDisplayMetrics().density);
            }
        });
        elevation.setProgress((int) (elevation.getMax() * 0.5f));
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/RenderableBear.java
================================================
package no.agens.depth;

import android.graphics.Bitmap;
import android.graphics.Canvas;

import no.agens.depth.lib.headers.Renderable;

public class RenderableBear extends Renderable {

    public static final int FRAME_DELAY = 2500;
    long lastFrameChange;
    Bitmap[] bitmaps;
    int bitmapIndex = 0;

    public RenderableBear(Bitmap[] bitmaps, float x, float y) {
        super(null, x, y);
        lastFrameChange = System.currentTimeMillis();
        this.bitmaps = bitmaps;
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.save();

        canvas.drawBitmap(bitmaps[bitmapIndex], x + translationX / 2, y + translationY, null);
        canvas.restore();
    }

    @Override
    public void update(float deltaTime, float wind) {
        super.update(deltaTime, wind);
        if (lastFrameChange + FRAME_DELAY < System.currentTimeMillis()) {
            lastFrameChange = System.currentTimeMillis();
            bitmapIndex += 1;
            if (bitmapIndex == bitmaps.length)
                bitmapIndex = 0;
        }
    }

    public void destroy() {
        for (Bitmap bitmap : bitmaps) {
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }

    }
}


================================================
FILE: app/src/main/java/no/agens/depth/RenderableTree.java
================================================
package no.agens.depth;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;

import no.agens.depth.lib.headers.Renderable;

/**
 * Created by danielzeller on 01.10.14.
 */
public class RenderableTree extends Renderable {
    private final float[] drawingVerts = new float[TOTAL_SLICES_COUNT * 2];
    private final float[] staticVerts = new float[TOTAL_SLICES_COUNT * 2];
    private static final int HORIZONTAL_SLICES = 1;
    private static final int VERTICAL_SLICES = 95;
    private static final int TOTAL_SLICES_COUNT = (HORIZONTAL_SLICES + 1) * (VERTICAL_SLICES + 1);
    private Paint p = new Paint();
    private float offsetInPercent;

    private Path pathLeft = new Path();
    private Path pathRight = new Path();
    private boolean isBounceAnimatin = false;
    private Paint paint = new Paint();

    public RenderableTree(Bitmap bitmap, float x, float y, float alpha) {
        super(bitmap, x, y );
        p.setColor(Color.BLACK);
        p.setStrokeWidth(6);
        p.setStyle(Paint.Style.STROKE);
        createVerts();
        paint.setAlpha((int) (255*alpha));
    }

    public void setScale(float scaleX, float scaleY) {
        this.scaleX = scaleX;
        this.scaleY = scaleY;
    }

    private void createVerts() {

        float xDimesion = (float) bitmap.getWidth();
        float yDimesion = (float) bitmap.getHeight();

        int index = 0;

        for (int y = 0; y <= VERTICAL_SLICES; y++) {
            float fy = yDimesion * y / VERTICAL_SLICES;
            for (int x = 0; x <= HORIZONTAL_SLICES; x++) {
                float fx = xDimesion * x / HORIZONTAL_SLICES;
                setXY(drawingVerts, index, fx, fy);
                setXY(staticVerts, index, fx, fy);
                index += 1;
            }
        }
    }

    public void setXY(float[] array, int index, float x, float y) {
        array[index * 2 + 0] = x;
        array[index * 2 + 1] = y;
    }

    public void setXA(float[] array, int index, float x) {
        array[index * 2 + 0] = x;
    }

    public void setYA(float[] array, int index, float y) {
        array[index * 2 + 1] = staticVerts[index * 2 + 1] + y;
    }

    @Override
    public void draw(Canvas canvas) {
        createPath();
//        alphaCanvas.drawPath(pathLeft, debugPaint);
//        alphaCanvas.drawPath(pathRight, debugPaint);
        canvas.save();
        if (scaleX != 1.f || scaleY != 1f) {
            canvas.scale(scaleX, scaleY, x + bitmap.getWidth() / 2, y + bitmap.getHeight());
        }
        canvas.drawBitmapMesh(bitmap, HORIZONTAL_SLICES, VERTICAL_SLICES, drawingVerts, 0, null, 0, paint);
        canvas.restore();
    }


    private void createPath() {
        pathLeft.reset();
        pathLeft.moveTo(x, y + bitmap.getHeight());
        pathLeft.cubicTo(x, y + bitmap.getHeight(), x, y, x + bitmap.getWidth() * 1.5f * offsetInPercent, y);
        pathRight.reset();
        pathRight.moveTo(x + bitmap.getWidth(), y + bitmap.getHeight());
        pathRight.cubicTo(x + bitmap.getWidth(), y + bitmap.getHeight(), x + bitmap.getWidth(), y + bitmap.getWidth() * 0.3f * offsetInPercent, x + bitmap.getWidth() + bitmap.getWidth() / 2 * offsetInPercent, y + bitmap.getWidth() * 0.8f * offsetInPercent);
        matchVertsToPath();
    }

    private void matchVertsToPath() {
        PathMeasure pmLeft = new PathMeasure(pathLeft, false);
        PathMeasure pmRight = new PathMeasure(pathRight, false);
        float[] coords = new float[2];
        for (int i = 0; i < staticVerts.length / 2; i++) {

            float yIndexValue = staticVerts[i * 2 + 1];
            float xIndexValue = staticVerts[i * 2];
            if (xIndexValue == 0) {
                float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();
                pmLeft.getPosTan(pmLeft.getLength() * (1f - percentOffsetY), coords, null);
                setXY(drawingVerts, i, coords[0], coords[1]);
            } else {
                float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();
                pmRight.getPosTan(pmRight.getLength() * (1f - percentOffsetY), coords, null);
                setXY(drawingVerts, i, coords[0], coords[1]);

            }
        }
    }

    public void setOffsetPercent(float offset) {
        if (!isBounceAnimatin)
            offsetInPercent = offset ;
    }


    public boolean isBounceAnimatin() {
        return isBounceAnimatin;
    }

    public void cancelBounce() {
        isBounceAnimatin = false;
    }

    @Override
    public void update(float deltaTime, float wind) {
        super.update(deltaTime, wind);
        setOffsetPercent(wind/100f);
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/RootActivity.java
================================================
package no.agens.depth;

import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import no.agens.depth.lib.CircularSplashView;
import no.agens.depth.lib.tween.interpolators.ExpoIn;
import no.agens.depth.lib.tween.interpolators.QuintOut;


public class RootActivity extends Activity {

    public static final int WATER_SCREEN_MENU_INDEX = 0;
    public static final int WIND_SCREEN_MENU_INDEX = 1;
    public static final int PLAYGROUND_SCREEN_MENU_INDEX = 2;
    public static final int ABOUT_SCREEN_MENU_INDEX = 3;

    Fragment currentFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_root);
        makeAppFullscreen();
        if (savedInstanceState == null) {
            currentFragment = new WaterFragment();
            getFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment).commit();
        }
        setupMenu();
    }

    public void setCurrentMenuIndex(int currentMenuIndex) {
        this.currentMenuIndex = currentMenuIndex;
    }

    int currentMenuIndex = 0;

    private void makeAppFullscreen() {
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }

    boolean isMenuVisible = false;
    ViewGroup menu;

    @Override
    public void onBackPressed() {

        if (isMenuVisible) {
            hideMenu();
            ((MenuAnimation) currentFragment).revertFromMenu();
        } else
            super.onBackPressed();
    }

    public void showMenu() {
        isMenuVisible = true;
        ObjectAnimator translationY = ObjectAnimator.ofFloat(menu, View.TRANSLATION_Y, menu.getHeight(), 0);
        translationY.setDuration(1000);
        translationY.setInterpolator(new QuintOut());
        translationY.setStartDelay(150);
        translationY.start();
        selectMenuItem(currentMenuIndex, ((TextView) menu.getChildAt(currentMenuIndex).findViewById(R.id.item_text)).getCurrentTextColor());
        ((MenuAnimation) currentFragment).animateTOMenu();
    }

    public void hideMenu() {
        isMenuVisible = false;
        ObjectAnimator translationY = ObjectAnimator.ofFloat(menu, View.TRANSLATION_Y, menu.getHeight());
        translationY.setDuration(750);
        translationY.setInterpolator(new ExpoIn());
        translationY.start();
    }


    private void setupMenu() {
        menu = (ViewGroup) findViewById(R.id.menu_container);
        int color = getResources().getColor(R.color.splash1);
        addMenuItem(menu, "Water And Noise", R.drawable.splash1, color, R.drawable.menu_btn, WATER_SCREEN_MENU_INDEX);
        addMenuItem(menu, "Two Bears", R.drawable.splash2, getResources().getColor(R.color.splash2), R.drawable.menu_btn2, WIND_SCREEN_MENU_INDEX);
        addMenuItem(menu, "Depth Playground", R.drawable.splash3, getResources().getColor(R.color.splash3), R.drawable.menu_btn3, PLAYGROUND_SCREEN_MENU_INDEX);
        addMenuItem(menu, "About", R.drawable.splash4, getResources().getColor(R.color.splash4), R.drawable.menu_btn4, ABOUT_SCREEN_MENU_INDEX);
        selectMenuItem(WATER_SCREEN_MENU_INDEX, color);
        menu.setTranslationY(20000);
    }


    private void addMenuItem(ViewGroup menu, String text, int drawableResource, int splashColor, int menu_btn, int menuIndex) {
        ViewGroup item = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.menu_item, menu, false);
        ((TextView) item.findViewById(R.id.item_text)).setText(text);
        CircularSplashView ic = (CircularSplashView) item.findViewById(R.id.circle);
        ic.setSplash(BitmapFactory.decodeResource(getResources(), drawableResource));
        ic.setSplashColor(splashColor);
        item.setOnClickListener(getMenuItemCLick(menuIndex, splashColor));
        if (menuIndex == WATER_SCREEN_MENU_INDEX) {
            int padding = (int) getResources().getDimension(R.dimen.menu_item_height_padding);
            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height) + padding));
            item.setPadding(0, padding, 0, 0);
        } else if (menuIndex == ABOUT_SCREEN_MENU_INDEX) {
            int padding = (int) getResources().getDimension(R.dimen.menu_item_height_padding);
            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height) + padding));
            item.setPadding(0, 0, 0, padding);
        } else
            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height)));
        item.setBackground(getResources().getDrawable(menu_btn, null));

    }

    private View.OnClickListener getMenuItemCLick(final int menuIndex, final int color) {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (menuIndex == currentMenuIndex)
                    onBackPressed();
                else if (menuIndex == WATER_SCREEN_MENU_INDEX && !(currentFragment instanceof WaterFragment)) {
                    showWaterFragment(menuIndex, color);
                } else if (menuIndex == WIND_SCREEN_MENU_INDEX && !(currentFragment instanceof WindFragment)) {
                    showWindFragment(menuIndex, color);
                } else if (menuIndex == PLAYGROUND_SCREEN_MENU_INDEX) {
                    startActivity(new Intent(RootActivity.this, PlayGroundActivity.class));
                    onBackPressed();
                }
            }
        };
    }

    private void showWindFragment(int menuIndex, int color) {
        ((MenuAnimation) currentFragment).exitFromMenu();
        WindFragment windFragment = new WindFragment();
        windFragment.setIntroAnimate(true);
        goToFragment(windFragment);
        hideMenu();
        selectMenuItem(menuIndex, color);
    }

    private void showWaterFragment(int menuIndex, int color) {
        ((MenuAnimation) currentFragment).exitFromMenu();
        WaterFragment waterFragment = new WaterFragment();
        waterFragment.setIntroAnimate(true);
        goToFragment(waterFragment);
        hideMenu();
        selectMenuItem(menuIndex, color);
    }

    private void selectMenuItem(int menuIndex, int color) {
        for (int i = 0; i < menu.getChildCount(); i++) {
            View menuItem = menu.getChildAt(i);
            if (i == menuIndex)
                select(menuItem, color);
            else
                unSelect(menuItem);
        }
        currentMenuIndex = menuIndex;
    }

    private void unSelect(View menuItem) {
        final View circle = menuItem.findViewById(R.id.circle);
        circle.animate().scaleX(0).scaleY(0).setDuration(150).withEndAction(new Runnable() {
            @Override
            public void run() {
                circle.setVisibility(View.INVISIBLE);
            }
        }).start();
        fadeColorTo(Color.BLACK, (TextView) menuItem.findViewById(R.id.item_text));
    }

    private void fadeColorTo(int newColor, TextView view) {
        ObjectAnimator color = ObjectAnimator.ofObject(view, "TextColor", new ArgbEvaluator(), view.getCurrentTextColor(), newColor);
        color.setDuration(200);
        color.start();
    }

    private void select(View menuItem, int color) {
        final CircularSplashView circle = (CircularSplashView) menuItem.findViewById(R.id.circle);
        circle.setScaleX(1f);
        circle.setScaleY(1f);
        circle.setVisibility(View.VISIBLE);
        circle.introAnimate();
        fadeColorTo(color, (TextView) menuItem.findViewById(R.id.item_text));
    }

    public void goToFragment(final Fragment newFragment) {
        getFragmentManager().beginTransaction().add(R.id.fragment_container, newFragment).commit();
        final Fragment removeFragment = currentFragment;
        currentFragment = newFragment;
        getWindow().getDecorView().postDelayed(new Runnable() {
            @Override
            public void run() {
                getFragmentManager().beginTransaction().remove(removeFragment).commit();
            }
        }, 2000);
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/SeekBarProgressChangeListener.java
================================================
package no.agens.depth;

import android.widget.SeekBar;

public abstract class SeekBarProgressChangeListener implements SeekBar.OnSeekBarChangeListener {
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }
}

================================================
FILE: app/src/main/java/no/agens/depth/Smoke.java
================================================
package no.agens.depth;

import android.animation.ValueAnimator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import no.agens.depth.lib.headers.Renderable;

public class Smoke extends Renderable {
    public static final float WIND_SENSITIVITY = 7f;
    float height, width;
    int numberOfTurns;
    float density;
    private final float[] drawingVerts = new float[TOTAL_SLICES_COUNT * 2];
    private final float[] staticVerts = new float[TOTAL_SLICES_COUNT * 2];
    private static final int HORIZONTAL_SLICES = 1;
    private static final int VERTICAL_SLICES = 80;
    private static final int TOTAL_SLICES_COUNT = (HORIZONTAL_SLICES + 1) * (VERTICAL_SLICES + 1);


    private void createVerts() {

        float xDimesion = (float) bitmap.getWidth();
        float yDimesion = (float) bitmap.getHeight();

        int index = 0;

        for (int y = 0; y <= VERTICAL_SLICES; y++) {
            float fy = yDimesion * y / VERTICAL_SLICES;
            for (int x = 0; x <= HORIZONTAL_SLICES; x++) {
                float fx = xDimesion * x / HORIZONTAL_SLICES;
                setXY(drawingVerts, index, fx, fy);
                setXY(staticVerts, index, fx, fy);
                index += 1;
            }
        }
    }

    public void setXY(float[] array, int index, float x, float y) {
        array[index * 2 + 0] = x;
        array[index * 2 + 1] = y;
    }

    public Smoke(Bitmap bitmap, float x, float y, float height, float width, int numberOfTurns, float density) {
        super(bitmap, x, y);
        this.height = height;
        this.width = width;
        this.numberOfTurns = numberOfTurns;
        paint.setStyle(Paint.Style.STROKE);
        this.density = density;
        createVerts();
        createPath();

        pathPointOffsetAnim = ValueAnimator.ofFloat(0, ((bitmap.getHeight() / (float) numberOfTurns) * 2f) / bitmap.getHeight()).setDuration(1500);
        pathPointOffsetAnim.setRepeatCount(ValueAnimator.INFINITE);
        pathPointOffsetAnim.setRepeatMode(ValueAnimator.RESTART);
        pathPointOffsetAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                pathPointOffset = (float) animation.getAnimatedValue();
            }
        });
        pathPointOffsetAnim.setInterpolator(new LinearInterpolator());
        pathPointOffsetAnim.start();

        createPath();
    }

    ValueAnimator pathPointOffsetAnim;

    public void destroy() {
        super.destroy();
        pathPointOffsetAnim.cancel();
    }

    @Override
    public void pause() {
        super.pause();
        pathPointOffsetAnim.pause();
    }

    @Override
    public void resume() {
        super.resume();
        pathPointOffsetAnim.resume();
    }

    Path smokePath = new Path();
    Paint paint = new Paint();
    float pathPointOffset = 1;

    @Override
    public void draw(Canvas canvas) {


        //  alphaCanvas.drawPath(smokePath, paint);
        canvas.drawBitmapMesh(bitmap, HORIZONTAL_SLICES, VERTICAL_SLICES, drawingVerts, 0, null, 0, paint);
    }

    public void setY(float y) {
        this.y = y;
        createPath();
    }

    @Override
    public void update(float deltaTime, float wind) {
        matchVertsToPath(wind);
    }

    private void createPath() {
        smokePath.reset();
        smokePath.moveTo(x, y);

        int step = (int) (height / numberOfTurns);
        boolean goLeft = true;
        for (int i = 0; i < numberOfTurns; i++) {
            if (goLeft)
                smokePath.cubicTo(x, y - step * i, x + width, y - step * i - step / 2, x, y - step * i - step);
            else
                smokePath.cubicTo(x, y - step * i, x - width, y - step * i - step / 2, x, y - step * i - step);

            goLeft = !goLeft;
        }

    }

    float[] coords = new float[2];
    float[] coords2 = new float[2];

    private void matchVertsToPath(float wind) {
        PathMeasure pm = new PathMeasure(smokePath, false);

        for (int i = 0; i < staticVerts.length / 2; i++) {

            float yIndexValue = staticVerts[i * 2 + 1];
            float xIndexValue = staticVerts[i * 2];

            float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();
            float percentOffsetY2 = (0.000001f + yIndexValue) / (bitmap.getHeight() + ((bitmap.getHeight() / numberOfTurns) * 4f));
            percentOffsetY2 += pathPointOffset;
            pm.getPosTan(pm.getLength() * (1f - percentOffsetY), coords, null);
            pm.getPosTan(pm.getLength() * (1f - percentOffsetY2), coords2, null);

            if (xIndexValue == 0) {
                float desiredXCoord = coords2[0] - (bitmap.getWidth()) / 2;
                desiredXCoord -= (desiredXCoord - x) * percentOffsetY;
                desiredXCoord += (wind / 3f) * density + ((wind * WIND_SENSITIVITY) * (1f - smokeExponentionWindStuff.getInterpolation(percentOffsetY)));
                setXY(drawingVerts, i, desiredXCoord, coords[1]);
            } else {
                float desiredXCoord = coords2[0] + (bitmap.getWidth()) / 2;
                desiredXCoord -= (desiredXCoord - x) * percentOffsetY;
                desiredXCoord += (wind / 3f) * density + ((wind * WIND_SENSITIVITY) * (1f - smokeExponentionWindStuff.getInterpolation(percentOffsetY)));
                setXY(drawingVerts, i, desiredXCoord, coords[1]);

            }
        }
    }

    DecelerateInterpolator smokeExponentionWindStuff = new DecelerateInterpolator(1f);
}


================================================
FILE: app/src/main/java/no/agens/depth/TransitionHelper.java
================================================
package no.agens.depth;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.support.annotation.NonNull;
import android.view.View;

import no.agens.depth.lib.DepthLayout;
import no.agens.depth.lib.tween.interpolators.BackOut;
import no.agens.depth.lib.tween.interpolators.CircInOut;
import no.agens.depth.lib.tween.interpolators.ExpoIn;
import no.agens.depth.lib.tween.interpolators.ExpoOut;
import no.agens.depth.lib.tween.interpolators.QuadInOut;
import no.agens.depth.lib.tween.interpolators.QuintInOut;
import no.agens.depth.lib.tween.interpolators.QuintOut;

public class TransitionHelper {

    public static final float TARGET_SCALE = 0.5f;
    public static final float TARGET_ROTATION = -50f;
    public static final float TARGET_ROTATION_X = 60f;
    public static final int MOVE_Y_STEP = 15;
    public static final int DURATION = 1100;
    public static final QuintOut VALUEinterpolator = new QuintOut();

    public static final int FISRTDELAY = 300;

    public static void startIntroAnim(View root, AnimatorListenerAdapter introEndListener) {
        introAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 180);
        introAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170);
        introAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 190);
        introAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 200);
        introAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 210).addListener(introEndListener);
    }

    static ObjectAnimator introAnimate(final DepthLayout target, final float moveY, final float customElevation, long delay, int subtractDelay) {

        target.setPivotY(getDistanceToCenter(target));
        target.setPivotX(getDistanceToCenterX(target));
        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);

        ObjectAnimator translationY2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, target.getResources().getDisplayMetrics().heightPixels, -moveY * target.getResources().getDisplayMetrics().density).setDuration(800);
        translationY2.setInterpolator(new ExpoOut());
        translationY2.setStartDelay(700 + subtractDelay);
        translationY2.start();
        target.setTranslationY(target.getResources().getDisplayMetrics().heightPixels);

        ObjectAnimator translationX2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_X, -target.getResources().getDisplayMetrics().widthPixels, 0).setDuration(800);
        translationX2.setInterpolator(new ExpoOut());
        translationX2.setStartDelay(700 + subtractDelay);
        translationX2.start();
        target.setTranslationX(-target.getResources().getDisplayMetrics().widthPixels);

        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, 0).setDuration(700);
        translationY.setInterpolator(new BackOut());
        translationY.setStartDelay(700 + 800);
        translationY.start();


        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, TARGET_ROTATION_X, 0).setDuration(1000);
        rotationX.setInterpolator(new QuintInOut());
        rotationX.setStartDelay(700 + FISRTDELAY + subtractDelay);
        rotationX.start();
        target.setRotationX(TARGET_ROTATION_X);

        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, "CustomShadowElevation", customElevation * target.getResources().getDisplayMetrics().density, target.getCustomShadowElevation()).setDuration(1000);
        elevation.setInterpolator(new QuintInOut());
        elevation.setStartDelay(700 + FISRTDELAY + subtractDelay * 2);
        elevation.start();
        target.setCustomShadowElevation(customElevation * target.getResources().getDisplayMetrics().density);

        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, TARGET_SCALE, target.getScaleX()).setDuration(1000);
        scaleX.setInterpolator(new CircInOut());
        scaleX.setStartDelay(700 + FISRTDELAY + subtractDelay);
        scaleX.start();
        target.setScaleX(TARGET_SCALE);

        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, TARGET_SCALE, target.getScaleY()).setDuration(1000);
        scaleY.setInterpolator(new CircInOut());
        scaleY.setStartDelay(700 + FISRTDELAY + subtractDelay);
        scaleY.start();
        target.setScaleY(TARGET_SCALE);

        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, TARGET_ROTATION, 0).setDuration(1400);
        rotation.setInterpolator(new QuadInOut());
        rotation.setStartDelay(FISRTDELAY + subtractDelay);
        rotation.start();
        target.setRotation(TARGET_ROTATION);
        rotation.addListener(getShowStatusBarListener(target));
        return scaleY;
    }


    public static void startExitAnim(View root) {
        exitAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 190, true);
        exitAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170, true);
        exitAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 210, true);
        exitAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 230, true);
        exitAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 250, true);
        hideStatusBar(root);
    }

    private static void hideStatusBar(View root) {
//        View decorView = ((Activity) root.getContext()).getWindow().getDecorView();
//        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
//        decorView.setSystemUiVisibility(uiOptions);
    }


    static ValueAnimator exitAnimate(final DepthLayout target, final float moveY, final float customElevation, long delay, int subtractDelay, boolean continueOffscreen) {

        target.setPivotY(getDistanceToCenter(target));
        target.setPivotX(getDistanceToCenterX(target));
        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);

        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, TARGET_ROTATION_X).setDuration(DURATION);
        rotationX.setInterpolator(VALUEinterpolator);
        rotationX.setStartDelay(delay);
        rotationX.start();

        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, "CustomShadowElevation", target.getCustomShadowElevation(), customElevation * target.getResources().getDisplayMetrics().density).setDuration(DURATION);
        elevation.setInterpolator(VALUEinterpolator);
        elevation.setStartDelay(delay);
        elevation.start();

        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, TARGET_SCALE).setDuration(DURATION);
        scaleX.setInterpolator(new QuintOut());
        scaleX.setStartDelay(delay);
        scaleX.start();

        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, TARGET_SCALE).setDuration(DURATION);
        scaleY.setInterpolator(new QuintOut());
        scaleY.setStartDelay(delay);
        scaleY.start();

        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, TARGET_ROTATION).setDuration(1600);
        rotation.setInterpolator(VALUEinterpolator);
        rotation.setStartDelay(delay);
        rotation.start();

        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, -moveY * target.getResources().getDisplayMetrics().density).setDuration(subtractDelay);
        translationY.setInterpolator(VALUEinterpolator);
        translationY.setStartDelay(delay);
        translationY.start();
        if (continueOffscreen) {
            continueOutToRight(target, moveY, subtractDelay);
        }
        return scaleY;
    }

    private static void continueOutToRight(DepthLayout target, float moveY, int subtractDelay) {
        ObjectAnimator translationY2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, -moveY * target.getResources().getDisplayMetrics().density, -target.getResources().getDisplayMetrics().heightPixels).setDuration(900);
        translationY2.setInterpolator(new ExpoIn());
        translationY2.setStartDelay(0 + subtractDelay);

        translationY2.start();

        ObjectAnimator translationX2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_X, target.getTranslationX(), target.getResources().getDisplayMetrics().widthPixels).setDuration(900);
        translationX2.setInterpolator(new ExpoIn());
        translationX2.setStartDelay(0 + subtractDelay);
        translationX2.start();
    }

    public static float getDistanceToCenter(View target) {
        float viewCenter = target.getTop() + target.getHeight() / 2f;
        float rootCenter = ((View) target.getParent()).getHeight() / 2;
        return target.getHeight() / 2f + rootCenter - viewCenter;
    }

    public static float getDistanceToCenterX(View target) {
        float viewCenter = target.getLeft() + target.getWidth() / 2f;
        float rootCenter = ((View) target.getParent()).getWidth() / 2;
        return target.getWidth() / 2f + rootCenter - viewCenter;
    }

    public static void animateToMenuState(View root, AnimatorListenerAdapter onMenuAnimFinished) {
        hideStatusBar(root);
        exitAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 190, false);
        exitAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170, false);
        exitAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 210, false);
        exitAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 230, false);
        exitAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 250, false).addListener(onMenuAnimFinished);

        ObjectAnimator translationY = ObjectAnimator.ofFloat(root, View.TRANSLATION_Y, -90f * root.getResources().getDisplayMetrics().density).setDuration(DURATION);
        translationY.setInterpolator(VALUEinterpolator);
        translationY.start();
    }

    private static void makeAppFullscreen(View target) {
//        ((Activity) target.getContext()).getWindow().setStatusBarColor(Color.TRANSPARENT);
//        ((Activity) target.getContext()).getWindow().getDecorView().setSystemUiVisibility(
//                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
//                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }

    public static void animateMenuOut(View root) {
        continueOutToRight((DepthLayout) root.findViewById(R.id.root_dl), 0, 20);
        continueOutToRight((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 0);
        continueOutToRight((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 40);
        continueOutToRight((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 60);
        continueOutToRight((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 80);
    }

    public static void startRevertFromMenu(View root, AnimatorListenerAdapter animatorListenerAdapter) {

        revertFromMenu((DepthLayout) root.findViewById(R.id.root_dl), 30f, 10, 0);
        revertFromMenu((DepthLayout) root.findViewById(R.id.appbar), 20f, 0, 0);
        revertFromMenu((DepthLayout) root.findViewById(R.id.fab_container), 20f, 20, 6);
        revertFromMenu((DepthLayout) root.findViewById(R.id.dl2), 20f, 30, 1);
        revertFromMenu((DepthLayout) root.findViewById(R.id.dl3), 20f, 40, 2).addListener(animatorListenerAdapter);
        ObjectAnimator translationY = ObjectAnimator.ofFloat(root, View.TRANSLATION_Y, 0).setDuration(DURATION);
        translationY.setInterpolator(new QuintInOut());
        translationY.start();
    }


    static ObjectAnimator revertFromMenu(final DepthLayout target, final float customElevation, int subtractDelay, float targetElevation) {

        target.setPivotY(getDistanceToCenter(target));
        target.setPivotX(getDistanceToCenterX(target));
        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);


        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, 0).setDuration(700);
        translationY.setInterpolator(new BackOut());
        translationY.setStartDelay(250 + FISRTDELAY + subtractDelay);
        translationY.start();


        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, target.getRotationX(), 0).setDuration(1000);
        rotationX.setInterpolator(new QuintInOut());
        rotationX.setStartDelay(FISRTDELAY + subtractDelay);
        rotationX.start();
        target.setRotationX(TARGET_ROTATION_X);

        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, "CustomShadowElevation", target.getCustomShadowElevation(), targetElevation * target.getResources().getDisplayMetrics().density).setDuration(1000);
        elevation.setInterpolator(new QuintInOut());
        elevation.setStartDelay(FISRTDELAY + subtractDelay * 2);
        elevation.start();
        target.setCustomShadowElevation(customElevation * target.getResources().getDisplayMetrics().density);

        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, target.getScaleX(), 1f).setDuration(1000);
        scaleX.setInterpolator(new CircInOut());
        scaleX.setStartDelay(FISRTDELAY + subtractDelay);
        scaleX.start();
        target.setScaleX(TARGET_SCALE);

        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, target.getScaleY(), 1f).setDuration(1000);
        scaleY.setInterpolator(new CircInOut());
        scaleY.setStartDelay(FISRTDELAY + subtractDelay);
        scaleY.start();
        target.setScaleY(TARGET_SCALE);

        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, target.getRotation(), 0).setDuration(1100);
        rotation.setInterpolator(new QuintInOut());
        rotation.setStartDelay(subtractDelay);
        rotation.start();
        rotation.addListener(getShowStatusBarListener(target));
        return scaleY;
    }

    @NonNull
    private static AnimatorListenerAdapter getShowStatusBarListener(final DepthLayout target) {
        return new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                makeAppFullscreen(target);
            }
        };
    }

}


================================================
FILE: app/src/main/java/no/agens/depth/Water.java
================================================
package no.agens.depth;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;

import no.agens.depth.lib.headers.PathBitmapMesh;
import no.agens.depth.lib.headers.Renderable;

public class Water extends Renderable {

    public static final int VERTS = 6;
    private float height, width;

    Foam[] foams = new Foam[4];
    int numberOfWaves;
    PathBitmapMesh water;
    private float waveHeight;

    public Water(Bitmap bitmap, Bitmap foam, float y, float height, float width, int waves) {
        super(bitmap, 0, y);
        this.height = height;
        this.width = width;
        numberOfWaves = waves;

        debugPaint.setColor(Color.RED);
        debugPaint.setStyle(Paint.Style.STROKE);
        lastEmit = System.currentTimeMillis();
        water = new PathBitmapMesh(VERTS, 1, bitmap, 1500);
        foams[0] = new Foam(VERTS, 1, foam, 0, height / 12, 1500);
        foams[1] = new Foam(VERTS, 1, foam, -height / 5, height / 5, 1500);
        foams[1].setAlpha(100);
        foams[2] = new Foam(VERTS, 1, foam, -height / 12, height / 12, 1450);
        foams[2].setVerticalOffset(height / 7);
        foams[3] = new Foam(VERTS, 1, foam, -height / 12, height / 12, 1400);
        foams[3].setVerticalOffset(height / 4);
        waveHeight = height / 10;
        createPath();
    }

    @Override
    public void pause() {
        super.pause();
        water.pause();
        for (Foam foam : foams)
            foam.pause();
    }

    @Override
    public void resume() {
        super.resume();
        water.resume();
        for (Foam foam : foams)
            foam.resume();
    }

    @Override
    public void destroy() {
        super.destroy();
        for (Foam foam : foams)
            foam.destroy();
    }

    Paint debugPaint = new Paint();

    @Override
    public void draw(Canvas canvas) {

        water.draw(canvas);
        for (Foam foam : foams) {
            foam.draw(canvas);
        }
    }

    @Override
    public void update(float deltaTime, float wind) {
        super.update(deltaTime, wind);
        for (Foam foam : foams) {
            foam.update(deltaTime);
        }
        water.matchVertsToPath(waterPath, height, ((bitmap.getWidth() / numberOfWaves) * 4f));
        for (Foam foam : foams) {
            foam.matchVertsToPath(waterPath, foam.getBitmap().getWidth() / numberOfWaves * 4f);
        }
        if (lastEmit + emitInterWall < System.currentTimeMillis()) {
            for (Foam foam : foams) {
                foam.calcWave();
            }
            lastEmit = System.currentTimeMillis();
        }

    }

    private Path waterPath = new Path();

    private void createPath() {
        waterPath.reset();
        waterPath.moveTo(0, y);

        int step = (int) (width / numberOfWaves);
        boolean goLeft = true;
        for (int i = 0; i < numberOfWaves; i++) {
            if (goLeft)
                waterPath.cubicTo(x + step * i, y, x + step * i + step / 2f, y + waveHeight, x + step * i + step, y);
            else
                waterPath.cubicTo(x + step * i, y, x + step * i + step / 2f, y - waveHeight, x + step * i + step, y);

            goLeft = !goLeft;
        }

    }


    long lastEmit;
    private int emitInterWall = 1000;


    public void setWaveHeight(float waveHeight) {
        this.waveHeight = waveHeight;
        createPath();
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/WaterFragment.java
================================================
package no.agens.depth;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.SeekBar;

import no.agens.depth.lib.MaterialMenuDrawable;

public class WaterFragment extends Fragment implements MenuAnimation {

    public static final int TRANSFORM_DURATION = 900;
    private boolean introAnimate;

    public WaterFragment() {
    }

    public void setIntroAnimate(boolean introAnimate) {
        this.introAnimate = introAnimate;
    }

    View root;
    MaterialMenuDrawable menuIcon;
    WaterSceneView waterScene;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        root = inflater.inflate(R.layout.fragment_water, container, false);
        waterScene = (WaterSceneView) root.findViewById(R.id.water_scene);
        setupFab();
        introAnimate();
        setupSeekbars();
        setupMenuButton();
        ((RootActivity) getActivity()).setCurrentMenuIndex(RootActivity.WATER_SCREEN_MENU_INDEX);

        return root;
    }

    private void setupSeekbars() {
        SeekBar waveSeekBar = (SeekBar) root.findViewById(R.id.wave_seekbar);
        SeekBar noiseSeekBar = (SeekBar) root.findViewById(R.id.noise_seekbar);

        WindFragment.setProgressBarColor(waveSeekBar, getResources().getColor(R.color.fab));
        WindFragment.setProgressBarColor(noiseSeekBar, getResources().getColor(R.color.fab));

        noiseSeekBar.setProgress(50);
        waveSeekBar.setProgress(50);

        waveSeekBar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                waterScene.setWaveHeight(progress / 4f * getResources().getDisplayMetrics().density);
            }
        });
        noiseSeekBar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                waterScene.setNoiseIntensity((float) progress / 100f);
            }
        });
    }

    private void setupMenuButton() {
        ImageView menu = (ImageView) root.findViewById(R.id.menu);
        menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!((RootActivity) getActivity()).isMenuVisible)
                    ((RootActivity) getActivity()).showMenu();
                else
                    ((RootActivity) getActivity()).onBackPressed();
            }
        });
        menuIcon = new MaterialMenuDrawable(getActivity(), Color.WHITE, MaterialMenuDrawable.Stroke.THIN, TRANSFORM_DURATION);
        menu.setImageDrawable(menuIcon);
    }

    private void introAnimate() {
        if (introAnimate)
            root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    TransitionHelper.startIntroAnim(root, showShadowListener);
                    hideShadow();
                    waterScene.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            waterScene.setPause(true);
                        }
                    }, 10);
                }
            });
    }

    private void setupFab() {
        root.findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        TransitionHelper.startExitAnim(root);
                    }
                });
                WindFragment windFragment = new WindFragment();
                windFragment.setIntroAnimate(true);
                ((RootActivity) getActivity()).goToFragment(windFragment);
                if (((RootActivity) getActivity()).isMenuVisible)
                    ((RootActivity) getActivity()).hideMenu();
                hideShadow();
                waterScene.setPause(true);
            }
        });
    }

    AnimatorListenerAdapter showShadowListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            showShadow();
            waterScene.setPause(false);
        }
    };

    private void hideShadow() {
        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);
        actionbarShadow.setVisibility(View.GONE);
    }

    private void showShadow() {
        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);
        actionbarShadow.setVisibility(View.VISIBLE);
        ObjectAnimator.ofFloat(actionbarShadow, View.ALPHA, 0, 0.8f).setDuration(400).start();
    }

    @Override
    public void animateTOMenu() {
        TransitionHelper.animateToMenuState(root, new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                waterScene.setPause(false);
            }
        });
        menuIcon.animateIconState(MaterialMenuDrawable.IconState.ARROW);
        hideShadow();
        waterScene.setPause(true);
    }

    @Override
    public void revertFromMenu() {
        TransitionHelper.startRevertFromMenu(root, showShadowListener);
        menuIcon.animateIconState(MaterialMenuDrawable.IconState.BURGER);
        waterScene.setPause(true);
    }

    @Override
    public void exitFromMenu() {
        TransitionHelper.animateMenuOut(root);
        waterScene.setPause(true);
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/WaterSceneView.java
================================================
package no.agens.depth;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

import no.agens.depth.lib.headers.NoiseEffect;
import no.agens.depth.lib.headers.Renderable;
import no.agens.depth.lib.tween.FrameRateCounter;

/**
 * Created by danielzeller on 01.10.14.
 */
public class WaterSceneView extends View {


    private Renderable[] renderables;
    private Water water;
    private NoiseEffect noiseScratchEffect;
    private NoiseEffect noise;

    public WaterSceneView(Context context) {
        super(context);

    }

    public WaterSceneView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WaterSceneView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (renderables == null) {
            init();
        }
    }

    private void init() {
        renderables = new Renderable[4];
        Bitmap waterBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.water);
        Bitmap foam = BitmapFactory.decodeResource(getResources(), R.drawable.foam);
        setLayerType(View.LAYER_TYPE_HARDWARE, null);
        water = new Water(waterBitmap, foam, getYCoordByPercent(0.65f), getYCoordByPercent(1f), getXCoordByPercent(1f), 6);
        renderables[0] = water;
        Bitmap aura = BitmapFactory.decodeResource(getResources(), R.drawable.sun_aura);
        renderables[1] = new Renderable(aura, getXCoordByPercent(0.5f), getYCoordByPercent(0.35f));

        Bitmap noiseScratch = BitmapFactory.decodeResource(getResources(), R.drawable.noise_scratch);
        Bitmap noiseReg = BitmapFactory.decodeResource(getResources(), R.drawable.noise);

        noiseScratchEffect = new NoiseEffect(noiseScratch, 100, 2f);
        renderables[2] = noiseScratchEffect;
        noise = new NoiseEffect(noiseReg, 30, 1.5f);
        renderables[3] = noise;
        setNoiseIntensity(0.5f);
        setWaveHeight(50);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        destroyResources();
    }

    private void destroyResources() {
        for (Renderable renderable : renderables)
            renderable.destroy();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (renderables == null && getWidth() != 0)
            init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float deltaTime = FrameRateCounter.timeStep();

        for (Renderable renderable : renderables) {
            renderable.draw(canvas);
            renderable.update(deltaTime, 0);
        }
        if (!pasuse)
            invalidate();
    }

    public void setPause(boolean pause) {
//        this.pasuse = pause;
//        if (!pause) {
//            FrameRateCounter.timeStep();
//            invalidate();
//            for (Renderable renderable : renderables)
//                renderable.resume();
//        } else {
//            for (Renderable renderable : renderables)
//                renderable.pause();
//        }
    }

    private boolean pasuse = false;

    private float getYCoordByPercent(float percent) {
        return getHeight() * percent;
    }

    private float getXCoordByPercent(float percent) {
        return getWidth() * percent;
    }

    public void setWaveHeight(float height) {
        water.setWaveHeight(height);
    }

    public void setNoiseIntensity(float noiseAmount) {
        noiseScratchEffect.setNoiseIntensity(noiseAmount);
        noise.setNoiseIntensity(noiseAmount);
    }
}


================================================
FILE: app/src/main/java/no/agens/depth/WindFragment.java
================================================
package no.agens.depth;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Fragment;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.SeekBar;

import no.agens.depth.lib.MaterialMenuDrawable;


public class WindFragment extends Fragment implements MenuAnimation {


    public static final int FLAMES_INITIAL_HEIGHT = 50;
    private boolean introAnimate;

    public WindFragment() {
    }

    View root;
    MaterialMenuDrawable menuIcon;
    BearSceneView bearsScene;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        root = inflater.inflate(R.layout.fragment_wind, container, false);
        bearsScene = (BearSceneView) root.findViewById(R.id.water_scene);

        doIntroAnimation();
        setupFabButton();
        setupMenuButton();
        ((RootActivity) getActivity()).setCurrentMenuIndex(RootActivity.WIND_SCREEN_MENU_INDEX);
        setupSliders();
        return root;
    }

    private void setupSliders() {
        SeekBar windSeekbar = (SeekBar) root.findViewById(R.id.wind_seekbar);
        final SeekBar flamesSeekbar = (SeekBar) root.findViewById(R.id.flames_seekbar);
        setProgressBarColor(windSeekbar, getResources().getColor(R.color.fab2));
        setProgressBarColor(flamesSeekbar, getResources().getColor(R.color.fab2));

        windSeekbar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                bearsScene.setWind(progress);
            }
        });

        flamesSeekbar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                bearsScene.setFlamesHeight(progress);
            }
        });
        bearsScene.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                bearsScene.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                flamesSeekbar.setProgress(FLAMES_INITIAL_HEIGHT);
            }
        });

    }

    private void doIntroAnimation() {
        if (introAnimate)
            root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    TransitionHelper.startIntroAnim(root, showShadowListener);
                    hideShadow();
                    bearsScene.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            bearsScene.setPause(true);
                        }
                    }, 10);
                }
            });
    }

    private void setupFabButton() {
        root.findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        TransitionHelper.startExitAnim(root);
                    }
                });
                WaterFragment waterFragment = new WaterFragment();
                waterFragment.setIntroAnimate(true);
                ((RootActivity) getActivity()).goToFragment(waterFragment);
                if (((RootActivity) getActivity()).isMenuVisible)
                    ((RootActivity) getActivity()).hideMenu();
                hideShadow();
                bearsScene.setPause(true);
            }
        });
    }

    private void setupMenuButton() {
        ImageView menu = (ImageView) root.findViewById(R.id.menu);
        menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!((RootActivity) getActivity()).isMenuVisible)
                    ((RootActivity) getActivity()).showMenu();
                else
                    getActivity().onBackPressed();
            }
        });
        menuIcon = new MaterialMenuDrawable(getActivity(), Color.WHITE, MaterialMenuDrawable.Stroke.THIN, WaterFragment.TRANSFORM_DURATION);
        menu.setImageDrawable(menuIcon);
    }

    public static void setProgressBarColor(SeekBar progressBar, int newColor) {
        if (progressBar.getProgressDrawable() instanceof StateListDrawable) {
            StateListDrawable ld = (StateListDrawable) progressBar.getProgressDrawable();
            ld.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
            progressBar.getThumb().setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
        } else if (progressBar.getProgressDrawable() instanceof LayerDrawable) {
            LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();
            for (int i = 0; i < ld.getNumberOfLayers(); i++) {
                Drawable d1 = ld.getDrawable(i);
                d1.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
            }
            progressBar.getThumb().setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
        }

    }

    public void setIntroAnimate(boolean introAnimate) {
        this.introAnimate = introAnimate;
    }

    @Override
    public void animateTOMenu() {
        TransitionHelper.animateToMenuState(root, new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                bearsScene.setPause(false);
            }
        });
        menuIcon.animateIconState(MaterialMenuDrawable.IconState.ARROW);
        hideShadow();
        bearsScene.setPause(true);
    }

    private void hideShadow() {
        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);
        actionbarShadow.setVisibility(View.GONE);
    }

    @Override
    public void revertFromMenu() {
        TransitionHelper.startRevertFromMenu(root, showShadowListener);
        menuIcon.animateIconState(MaterialMenuDrawable.IconState.BURGER);
        bearsScene.setPause(true);
    }

    AnimatorListenerAdapter showShadowListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            showShadow();
            bearsScene.setPause(false);
        }
    };

    private void showShadow() {
        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);
        actionbarShadow.setVisibility(View.VISIBLE);
        ObjectAnimator.ofFloat(actionbarShadow, View.ALPHA, 0, 0.8f).setDuration(400).start();
    }

    @Override
    public void exitFromMenu() {
        TransitionHelper.animateMenuOut(root);
        bearsScene.setPause(true);
    }
}


================================================
FILE: app/src/main/res/drawable/bear_bg_gradient.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:startColor="#C68C94"
        android:centerColor="#3A5067"
        android:endColor="#3A5067"
        android:angle="315"/>
</shape>

================================================
FILE: app/src/main/res/drawable/circle.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/fab">
    <item>
        <shape android:shape="oval">
            <solid android:color="@color/fab_highlight" />
        </shape>
    </item>
</ripple>

================================================
FILE: app/src/main/res/drawable/fab_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/fab">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <solid android:color="@color/white" />
        </shape>
        <color android:color="@color/white" />
    </item>
</ripple>

================================================
FILE: app/src/main/res/drawable/menu_btn.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/splash1">
    <item android:drawable="@android:color/white"/>
</ripple>

================================================
FILE: app/src/main/res/drawable/menu_btn2.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/splash2">
    <item android:drawable="@android:color/white"/>
</ripple>

================================================
FILE: app/src/main/res/drawable/menu_btn3.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/splash3">
    <item android:drawable="@android:color/white"/>
</ripple>

================================================
FILE: app/src/main/res/drawable/menu_btn4.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/splash4">
    <item android:drawable="@android:color/white"/>
</ripple>

================================================
FILE: app/src/main/res/layout/activity_root.xml
================================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
    >

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >


    </FrameLayout>

    <LinearLayout
        android:id="@+id/menu_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="6dp"
        android:layout_alignParentBottom="true"
        android:layerType="hardware" >
    </LinearLayout>
</RelativeLayout>

================================================
FILE: app/src/main/res/layout/fragment_playground.xml
================================================
<no.agens.depth.lib.DepthRendrer xmlns:android="http://schemas.android.com/apk/res/android"
                                 xmlns:app="http://schemas.android.com/apk/res-auto"
                                 xmlns:tools="http://schemas.android.com/tools"
                                 android:layout_width="match_parent"
                                 android:layout_height="match_parent"
                                 android:background="#DCDCDC"
                                 tools:context=".MainActivity"
    >
    <RelativeLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/appbar_height"
        android:background="@color/green"
        android:layerType="hardware"
        app:edge_color="@color/statusbar2"
        >


        <ImageView

            android:id="@+id/staturbar_bg"
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="@color/statusbar2"
            />

        <ImageView
            android:id="@+id/menu"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_menu"
            android:scaleType="centerInside"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="65dp"
            android:text="Depth"
            android:textColor="@color/white"
            android:textSize="18sp"
            />
    </RelativeLayout>

    <ImageView
        android:id="@+id/actionbar_shadow"
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_below="@+id/appbar"
        android:background="@drawable/actionbar_shadow"
        />

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="324dp"

        >



            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                android:background="@color/white"
                android:orientation="vertical"
                >

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/default_subheading_margin_top"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:text="Depth"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    />

                <SeekBar
                    android:id="@+id/depth_seekbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/seekbar_margin_sides"
                    android:layout_marginRight="@dimen/seekbar_margin_sides"
                    android:layout_marginTop="@dimen/seekbar_margin_top"
                    android:padding="@dimen/seekbar_padding"
                    />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/divider_color"
                    />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/default_subheading_margin_top"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:text="Elevation"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    />

                <SeekBar
                    android:id="@+id/elevation_seekbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/seekbar_margin_sides"
                    android:layout_marginRight="@dimen/seekbar_margin_sides"
                    android:layout_marginTop="@dimen/seekbar_margin_top"
                    android:padding="@dimen/seekbar_padding"
                    />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/divider_color"
                    />


                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/default_subheading_margin_top"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:text="Rotation X"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    />

                <SeekBar
                    android:id="@+id/rotation_x_seekbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/seekbar_margin_sides"
                    android:layout_marginRight="@dimen/seekbar_margin_sides"
                    android:layout_marginTop="@dimen/seekbar_margin_top"
                    android:padding="@dimen/seekbar_padding"
                    />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/divider_color"
                    />


                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/default_subheading_margin_top"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:text="Rotation Y"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    />

                <SeekBar
                    android:id="@+id/rotation_y_seekbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/seekbar_margin_sides"
                    android:layout_marginRight="@dimen/seekbar_margin_sides"
                    android:layout_marginTop="@dimen/seekbar_margin_top"
                    android:padding="@dimen/seekbar_padding"
                    />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/divider_color"
                    />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/default_subheading_margin_top"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:text="Rotation Z"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    />

                <SeekBar
                    android:id="@+id/rotation_z_seekbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/seekbar_margin_sides"
                    android:layout_marginRight="@dimen/seekbar_margin_sides"
                    android:layout_marginTop="@dimen/seekbar_margin_top"
                    android:padding="@dimen/seekbar_padding"
                    />


            </LinearLayout>

    </ScrollView>


    <no.agens.depth.lib.DepthLayout
        android:id="@+id/depth_view"
        android:layout_width="140dp"
        android:layout_height="140dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="130dp"
        app:is_circle="false"
        >

        <ImageView

            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/sun"
            />
    </no.agens.depth.lib.DepthLayout>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="25dp"
        android:layout_marginTop="195dp"
        android:src="@drawable/x_y"
        />

</no.agens.depth.lib.DepthRendrer>


================================================
FILE: app/src/main/res/layout/fragment_water.xml
================================================
<no.agens.depth.lib.DepthRendrer xmlns:android="http://schemas.android.com/apk/res/android"
                                 xmlns:app="http://schemas.android.com/apk/res-auto"
                                 xmlns:tools="http://schemas.android.com/tools"
                                 android:layout_width="match_parent"
                                 android:layout_height="match_parent"
                                 tools:context=".sample.WaterFragment"
                                 android:layerType="hardware"

    >

    <no.agens.depth.lib.DepthLayout
        android:id="@+id/root_dl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:layerType="hardware"
        android:paddingTop="@dimen/appbar_height"
        >

        <no.agens.depth.WaterSceneView
            android:id="@+id/water_scene"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:background="@drawable/water_scene_background"
            />
    </no.agens.depth.lib.DepthLayout>


    <no.agens.depth.lib.DepthLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/appbar_height"
        android:background="@color/blue"
        android:layerType="hardware"
        app:edge_color="@color/black"
        >


        <ImageView

            android:id="@+id/staturbar_bg"
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="@color/statusbar"
            />
        <ImageView
            android:id="@+id/menu"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_alignParentBottom="true"

            android:src="@drawable/ic_menu"
            android:scaleType="centerInside"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="65dp"
            android:text="Depth"
            android:textColor="@color/white"
            android:textSize="18sp"
            android:fitsSystemWindows="true"
            />
    </no.agens.depth.lib.DepthLayout>
    <ImageView
        android:id="@+id/actionbar_shadow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/appbar"
        android:background="@drawable/actionbar_shadow"
        />
    <no.agens.depth.lib.DepthLayout
        android:id="@+id/dl2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="260dp"
        android:background="@color/white"
        app:custom_elevation="1dp"
        android:layerType="hardware"
        >

        <LinearLayout
            android:id="@+id/sliders_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/default_subheading_margin_top"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:text="Noise"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/blue"
                android:textSize="16sp"
                />

            <SeekBar
                android:id="@+id/noise_seekbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/seekbar_margin_sides"
                android:layout_marginRight="@dimen/seekbar_margin_sides"
                android:layout_marginTop="@dimen/seekbar_margin_top"
                android:padding="@dimen/seekbar_padding"
                />

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/divider_color"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/default_subheading_margin_top"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:text="Wave Strength"
                android:textColor="@color/blue"
                android:textSize="16sp"
                />

            <SeekBar
                android:id="@+id/wave_seekbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/seekbar_margin_sides"
                android:layout_marginRight="@dimen/seekbar_margin_sides"
                android:layout_marginTop="@dimen/seekbar_margin_top"
                android:padding="@dimen/seekbar_padding"
                />


        </LinearLayout>
    </no.agens.depth.lib.DepthLayout>

    <no.agens.depth.lib.DepthLayout
        android:id="@+id/dl3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="450dp"
        android:background="@color/white"
        app:custom_elevation="2dp"
        android:layerType="hardware"
        >

        <TextView
            android:id="@+id/about_heading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/default_subheading_margin_top"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="Water And Noise"
            android:textColor="@color/black"
            android:textSize="16sp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/about_heading"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="A water experiment developed
by Agens in 2015, as an example of how to draw
advanced canvas based graphics with the Android
SDK. "
            android:textColor="@color/text_primary"
            android:textSize="14sp"
            />

    </no.agens.depth.lib.DepthLayout>



    <no.agens.depth.lib.DepthLayout
        android:id="@+id/fab_container"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="@dimen/fab_margin"
        android:layout_marginTop="232dp"
        android:background="@drawable/circle"
        app:custom_elevation="6dp"
        android:layerType="hardware"
        app:edge_color="@color/fab"
        app:is_circle="true"
        >

        <ImageButton
            android:id="@+id/fab"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:src="@drawable/ic_forward"
            android:background="@drawable/fab_bg"
            android:layerType="hardware"
            />
    </no.agens.depth.lib.DepthLayout>
</no.agens.depth.lib.DepthRendrer>


================================================
FILE: app/src/main/res/layout/fragment_wind.xml
================================================
<no.agens.depth.lib.DepthRendrer xmlns:android="http://schemas.android.com/apk/res/android"
                                 xmlns:app="http://schemas.android.com/apk/res-auto"
                                 xmlns:tools="http://schemas.android.com/tools"
                                 android:layout_width="match_parent"
                                 android:layout_height="match_parent"
                                 tools:context=".sample.WaterFragment"

    >

    <no.agens.depth.lib.DepthLayout
        android:id="@+id/root_dl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:layerType="hardware"
        android:paddingTop="@dimen/appbar_height"
        >

        <no.agens.depth.BearSceneView
            android:id="@+id/water_scene"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:scaleType="centerCrop"
            android:background="@drawable/bear_bg_gradient"
            />
    </no.agens.depth.lib.DepthLayout>


    <no.agens.depth.lib.DepthLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/appbar_height"
        android:background="@color/green"
        android:layerType="hardware"
        app:edge_color="@color/statusbar2"
        >


        <ImageView

            android:id="@+id/staturbar_bg"
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="@color/statusbar2"
            />

        <ImageView
            android:id="@+id/menu"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_menu"
            android:scaleType="centerInside"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="65dp"
            android:text="Depth"
            android:textColor="@color/white"
            android:textSize="18sp"
            />
    </no.agens.depth.lib.DepthLayout>

    <ImageView
        android:id="@+id/actionbar_shadow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/appbar"
        android:background="@drawable/actionbar_shadow"
        />

    <no.agens.depth.lib.DepthLayout
        android:id="@+id/dl2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="260dp"
        android:background="@color/white"
        android:layerType="hardware"
        app:custom_elevation="1dp"
        >

        <LinearLayout
            android:id="@+id/sliders_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/default_subheading_margin_top"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:text="Wind Strength"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/black"
                android:textSize="16sp"
                />

            <SeekBar
                android:id="@+id/wind_seekbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/seekbar_margin_sides"
                android:layout_marginRight="@dimen/seekbar_margin_sides"
                android:layout_marginTop="@dimen/seekbar_margin_top"
                android:padding="@dimen/seekbar_padding"
                />

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/divider_color"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/default_subheading_margin_top"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:text="Flames Height"
                android:textColor="@color/black"
                android:textSize="16sp"
                />

            <SeekBar
                android:id="@+id/flames_seekbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/seekbar_margin_sides"
                android:layout_marginRight="@dimen/seekbar_margin_sides"
                android:layout_marginTop="@dimen/seekbar_margin_top"
                android:padding="@dimen/seekbar_padding"
                />


        </LinearLayout>
    </no.agens.depth.lib.DepthLayout>

    <no.agens.depth.lib.DepthLayout
        android:id="@+id/dl3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="450dp"
        android:background="@color/white"
        android:layerType="hardware"
        app:custom_elevation="2dp"
        >

        <TextView
            android:id="@+id/about_heading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/default_subheading_margin_top"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="Two Bears"
            android:textColor="@color/black"
            android:textSize="16sp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/about_heading"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="A particle experiment developed
by Agens in 2015, as an example of how to draw advanced
canvas based graphic´s with the Android
SDK. "
            android:textColor="@color/text_primary"
            android:textSize="14sp"
            />

    </no.agens.depth.lib.DepthLayout>


    <no.agens.depth.lib.DepthLayout
        android:id="@+id/fab_container"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="@dimen/fab_margin"
        android:layout_marginTop="232dp"
        android:background="@drawable/circle"
        android:layerType="hardware"
        app:custom_elevation="6dp"
        app:edge_color="#9A6A70"
        app:is_circle="true"
        >

        <ImageButton
            android:id="@+id/fab"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:src="@drawable/ic_forward"
            android:background="@drawable/fab_bg"
            android:layerType="hardware"
            />
    </no.agens.depth.lib.DepthLayout>
</no.agens.depth.lib.DepthRendrer>


================================================
FILE: app/src/main/res/layout/menu_item.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:orientation="horizontal"
    >

    <no.agens.depth.lib.CircularSplashView
        android:id="@+id/circle"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="25dp"
        />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="65dp"
        android:textColor="@color/black"
        android:textSize="16sp"
        />

</RelativeLayout>

================================================
FILE: app/src/main/res/menu/menu_root.xml
================================================
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".sample.RootActivity">
    <item android:id="@+id/action_settings"
          android:title="@string/action_settings"
          android:orderInCategory="100"
          app:showAsAction="never"/>
</menu>


================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="light_grey">#8C9CA4</color>
    <color name="white">#FFFFFF</color>
    <color name="divider_color">#DBDBDB</color>
    <color name="edge_color">#FFFFFF</color>
    <color name="fab">#f9aab0</color>
    <color name="fab_highlight">#CB747B</color>
    <color name="blue">#323453</color>
    <color name="green">#4E8186</color>

    <color name="statusbar">#282942</color>
    <color name="statusbar2">#3E676B</color>
    <color name="text_primary">#727272</color>
    <color name="black">#000000</color>
    <color name="fab2">#DC8F9A</color>
    <color name="splash1">#F19BA2</color>
    <color name="splash2">#323453</color>
    <color name="splash3">#649692</color>
    <color name="splash4">#C68C94</color>

    <color name="fire_end_color">#E89183</color>
    <color name="fire_start_color">#FCFBEB</color>
</resources>

================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
    <dimen name="appbar_height">80dp</dimen>

    <dimen name="seekbar_padding">10dp</dimen>
    <dimen name="seekbar_margin_top">11dp</dimen>
    <dimen name="default_subheading_margin_top">12dp</dimen>
    <dimen name="seekbar_margin_sides">8dp</dimen>
    <dimen name="menu_item_height">53dp</dimen>
    <dimen name="menu_item_height_padding">6dp</dimen>
</resources>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">Depth</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_root">Depth Demo</string>
</resources>


================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="colorAccent">@color/fab</item>
    </style>

</resources>


================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {

        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Oct 16 12:59:36 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip


================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: lib/.gitignore
================================================
/build


================================================
FILE: lib/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

android {
    compileSdkVersion 28

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
}


ext {
    bintrayRepo = 'maven'
    bintrayName = 'depth-lib-android'

    publishedGroupId = 'no.agens'
    libraryName = 'Depth-Lib-Android'
    artifact = 'depthlib'

    libraryDescription = 'This library adds depth/thickness to views.'

    siteUrl = 'https://github.com/danielzeller/Depth-LIB-Android-'
    gitUrl = 'https://github.com/danielzeller/Depth-LIB-Android-.git'

    libraryVersion = '1.0.1'

    developerId = 'danielzeller'
    developerName = 'Daniel Zeller'
    developerEmail = 'daniel@danielzeller.no'

    licenseName = 'The Apache Software License, Version 2.0'
    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
    allLicenses = ["Apache-2.0"]
}


group = publishedGroupId
version = libraryVersion

install {
    repositories.mavenInstaller {
        pom.project {
            packaging 'aar'
            groupId publishedGroupId
            artifactId artifact

            name libraryName
            description libraryDescription
            url siteUrl

            licenses {
                license {
                    name licenseName
                    url licenseUrl
                }
            }
            developers {
                developer {
                    id developerId
                    name developerName
                    email developerEmail
                }
            }
            scm {
                connection gitUrl
                developerConnection gitUrl
                url siteUrl
            }
        }
    }
}

task sourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

artifacts {
    archives javadocJar
    archives sourcesJar
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")

    configurations = ['archives']
    pkg {
        repo = bintrayRepo
        name = bintrayName
        desc = libraryDescription
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = allLicenses
        dryRun = false
        publish = true
        override = false
        publicDownloadNumbers = true
        version {
            desc = libraryDescription
        }
    }
}





================================================
FILE: lib/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\Jawn\Develop\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: lib/src/androidTest/java/no/agens/depth/ApplicationTest.java
================================================
package no.agens.depth;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: lib/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="no.agens.depth.lib">

    <application />

</manifest>


================================================
FILE: lib/src/main/java/no/agens/depth/lib/CircularSplashView.java
================================================
package no.agens.depth.lib;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import no.agens.depth.lib.tween.interpolators.QuintOut;


/**
 * Created by danielzeller on 03.09.14.
 */
public class CircularSplashView extends View {

    private final List<CircledDrawable> circles = new ArrayList<>();

    public CircularSplashView(Context context) {
        super(context);
    }

    public CircularSplashView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CircularSplashView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setSplash(Bitmap splash) {
        this.splash = splash;
    }

    public void setSplashColor(int splashColor) {
        this.splashColor = splashColor;
    }

    private Bitmap splash;
    private int splashColor;

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (circles.size() == 0) {
            introAnimate();
        }
    }

    public void introAnimate() {
        circles.clear();
        RectF expandedSizeFloat = new RectF(0, 0, getWidth(), getHeight());
        Rect expandedSizeInt = new Rect(0, 0, getWidth(), getHeight());
        RectF biggerRect = new RectF(-1, -1, getWidth() + 1, getHeight() + 1);
        circles.add(new CircleColorExpand(expandedSizeFloat, 0, 600, splashColor));
        circles.add(new CircleColorExpand(biggerRect, 70, 600, Color.WHITE));
        circles.add(new CircleBitmapExpand(expandedSizeInt, 130, 800, splash));
        for (CircledDrawable c : circles)
            c.startAnim();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (CircledDrawable circle : circles)
            circle.draw(canvas);
    }

    interface CircledDrawable {
        void startAnim();

        void draw(Canvas canvas);
    }

    public class CircleBitmapExpand implements CircledDrawable {
        Rect targetSize;
        Rect drawingRect;
        long startDelay;
        long animDuration;
        Bitmap bitmap;

        public CircleBitmapExpand(Rect targetSize, long startDelay, long animDuration, Bitmap inBitmap) {
            this.targetSize = targetSize;
            this.startDelay = startDelay;
            this.animDuration = animDuration;
            bitmap = inBitmap;

        }

        public Bitmap GetBitmapClippedCircle(Bitmap bitmap) {

            final int width = bitmap.getWidth();
            final int height = bitmap.getHeight();
            final Bitmap outputBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

            final Path path = new Path();
            path.addCircle(
                    (float) (width / 2)
                    , (float) (height / 2)
                    , (float) Math.min(width, (height / 2))
                    , Path.Direction.CCW);

            final Canvas canvas = new Canvas(outputBitmap);
            canvas.clipPath(path);
            canvas.drawBitmap(bitmap, 0, 0, null);
            bitmap.recycle();
            return outputBitmap;
        }

        public void startAnim() {
            Rect startRect = new Rect(targetSize.centerX(), targetSize.centerY(), targetSize.centerX(), targetSize.centerY());
            drawingRect = startRect;
            ValueAnimator rectSize = ValueAnimator.ofObject(new RectEvaluator(), startRect, targetSize);
            rectSize.setDuration(animDuration);
            rectSize.setInterpolator(new QuintOut());
            rectSize.setStartDelay(startDelay);
            rectSize.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    drawingRect = (Rect) animation.getAnimatedValue();
                    invalidate();
                }
            });
            rectSize.start();
        }

        public void draw(Canvas canvas) {
            if (drawingRect != null)
                canvas.drawBitmap(bitmap, null, drawingRect, null);
        }
    }

    public class CircleColorExpand implements CircledDrawable {
        private Paint paint = new Paint(Color.BLACK);
        RectF targetSize;
        RectF drawingRect;
        long startDelay;
        long animDuration;

        public CircleColorExpand(RectF targetSize, long startDelay, long animDuration, int paintColor) {
            this.targetSize = targetSize;
            this.startDelay = startDelay;
            this.animDuration = animDuration;
            paint.setColor(paintColor);
            paint.setAntiAlias(true);
            paint.setDither(true);
        }

        public void startAnim() {
            RectF startRect = new RectF(targetSize.centerX(), targetSize.centerY(), targetSize.centerX(), targetSize.centerY());
            ValueAnimator rectSize = ValueAnimator.ofObject(new RectFEvaluator(), startRect, targetSize);
            rectSize.setDuration(animDuration);
            rectSize.setInterpolator(new QuintOut());
            rectSize.setStartDelay(startDelay);
            rectSize.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    drawingRect = (RectF) animation.getAnimatedValue();
                    invalidate();
                }
            });
            rectSize.start();
        }

        public void draw(Canvas canvas) {
            if (drawingRect != null)
                canvas.drawOval(drawingRect, paint);
        }
    }
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/ColorAnimator.java
================================================

package no.agens.depth.lib;

import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.View;

public class ColorAnimator {

    public static ObjectAnimator ofColor(Object target, String propertyName, int from, int to) {
		return ObjectAnimator.ofObject(target, propertyName, new ColorEvaluator(), from, to);
	}

	public static ObjectAnimator ofColor(Object target, String propertyName, int to) {
		return ObjectAnimator.ofObject(target, propertyName, new ColorEvaluator(), to);
	}
	
	public static ObjectAnimator ofBackgroundColor(View target, int from, int to) {
		return ObjectAnimator.ofObject(new ViewBackgroundWrapper(target), "backgroundColor", new ColorEvaluator(), from, to);
	}
	
	public static ObjectAnimator ofBackgroundColor(View target, int to) {
		return ObjectAnimator.ofObject(new ViewBackgroundWrapper(target), "backgroundColor", new ColorEvaluator(), to);
	}

	private static class ColorEvaluator implements TypeEvaluator<Integer> {

		@Override
		public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
			int startA, startR, startG, startB;
			int aDelta = (int) ((Color.alpha(endValue) - (startA = Color.alpha(startValue))) * fraction);
			int rDelta = (int) ((Color.red(endValue) - (startR = Color.red(startValue))) * fraction);
			int gDelta = (int) ((Color.green(endValue) - (startG = Color.green(startValue))) * fraction);
			int bDelta = (int) ((Color.blue(endValue) - (startB = Color.blue(startValue))) * fraction);
			return Color.argb(startA + aDelta, startR + rDelta, startG + gDelta, startB + bDelta);
		}
	}

	/**
	 * Helper class which allows retrieval of a {@link View}'s background as a color.
	 */
	public static class ViewBackgroundWrapper {

		private final View mView;

		public ViewBackgroundWrapper(View v) {
			mView = v;
		}

		public int getBackgroundColor() {
			try {
				return ((ColorDrawable) mView.getBackground()).getColor();
			} catch (ClassCastException cce) {
				// The background isn't a ColorDrawable (could be BitmapDrawable etc.) - throw a more descriptive error
				throw new IllegalStateException(
						String.format("Attempt to read View background color when background isn't a ColorDrawable (is %s instead)",
								mView.getBackground().getClass().getSimpleName()));
			}
		}

		public void setBackgroundColor(int color) {
			mView.setBackgroundColor(color);
		}
	}
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/CustomShadow.java
================================================
package no.agens.depth.lib;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

/**
 * A rounded rectangle drawable which also includes a shadow around.
 */
public class CustomShadow extends Drawable {
    final static double COS_45 = Math.cos(Math.toRadians(45));

    final static float SHADOW_MULTIPLIER = 1.5f;

    final int mInsetShadow; // extra shadow to avoid gaps between card and shadow

    /*
    * This helper is set by CardView implementations.
    * <p>
    * Prior to API 17, canvas.drawRoundRect is expensive; which is why we need this interface
    * to draw efficient rounded rectangles before 17.
    * */
    static RoundRectHelper sRoundRectHelper;

    final Paint mPaint;

    Paint mCornerShadowPaint;

    Paint mEdgeShadowPaint;

    final RectF mCardBounds;

    float mCornerRadius;

    Path mCornerShadowPath;

    // updated value with inset
    float mMaxShadowSize;

    // actual value set by developer
    float mRawMaxShadowSize;

    // multiplied value to account for shadow offset
    float mShadowSize;

    // actual value set by developer
    float mRawShadowSize;

    private boolean mDirty = true;

    private final int mShadowStartColor;

    private final int mShadowEndColor;

    private boolean mAddPaddingForCorners = true;

    /**
     * If shadow size is set to a value above max shadow, we print a warning
     */
    private boolean mPrintedShadowClipWarning = false;

    public CustomShadow(
            Resources resources, int backgroundColor, float radius,
            float shadowSize, float maxShadowSize
    ) {
        mShadowStartColor = resources.getColor(R.color.cardview_shadow_start_color);
        mShadowEndColor = resources.getColor(R.color.cardview_shadow_end_color);
        mInsetShadow = resources.getDimensionPixelSize(R.dimen.cardview_compat_inset_shadow);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mPaint.setColor(backgroundColor);
        mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mCornerShadowPaint.setStyle(Paint.Style.FILL);
        mCornerRadius = (int) (radius + .5f);
        mCardBounds = new RectF();
        mEdgeShadowPaint = new Paint(mCornerShadowPaint);
        mEdgeShadowPaint.setAntiAlias(false);
        setShadowSize(shadowSize, maxShadowSize);

        CustomShadow.sRoundRectHelper = new CustomShadow.RoundRectHelper() {
            @Override
            public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius,
                                      Paint paint) {
                canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint);
            }
        };
    }

    /**
     * Casts the value to an even integer.
     */
    private int toEven(float value) {
        int i = (int) (value + .5f);
        if (i % 2 == 1) {
            return i - 1;
        }
        return i;
    }

    public void setAddPaddingForCorners(boolean addPaddingForCorners) {
        mAddPaddingForCorners = addPaddingForCorners;
        invalidateSelf();
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        mCornerShadowPaint.setAlpha(alpha);
        mEdgeShadowPaint.setAlpha(alpha);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mDirty = true;
    }

    void setShadowSize(float shadowSize, float maxShadowSize) {
        if (shadowSize < 0 || maxShadowSize < 0) {
            throw new IllegalArgumentException("invalid shadow size");
        }
        shadowSize = toEven(shadowSize);
        maxShadowSize = toEven(maxShadowSize);
        if (shadowSize > maxShadowSize) {
            shadowSize = maxShadowSize;
            if (!mPrintedShadowClipWarning) {
                mPrintedShadowClipWarning = true;
            }
        }
        if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) {
            return;
        }
        mRawShadowSize = shadowSize;
        mRawMaxShadowSize = maxShadowSize;
        mShadowSize = (int) (shadowSize * SHADOW_MULTIPLIER + mInsetShadow + .5f);
        mMaxShadowSize = maxShadowSize + mInsetShadow;
        mDirty = true;
        invalidateSelf();
    }

    @Override
    public boolean getPadding(Rect padding) {
        int vOffset = (int) Math.ceil(calculateVerticalPadding(mRawMaxShadowSize, mCornerRadius,
                mAddPaddingForCorners));
//        int hOffset = (int) Math.ceil(calculateHorizontalPadding(mRawMaxShadowSize, mCornerRadius,
//                mAddPaddingForCorners));
//        padding.set(hOffset, vOffset, hOffset, vOffset);
        padding.set(0, vOffset, 0, 0);
        return true;
    }

    static float calculateVerticalPadding(float maxShadowSize, float cornerRadius,
                                          boolean addPaddingForCorners) {
        if (addPaddingForCorners) {
            return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius);
        } else {
            return maxShadowSize * SHADOW_MULTIPLIER;
        }
    }

    static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius,
                                            boolean addPaddingForCorners) {
        if (addPaddingForCorners) {
            return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);
        } else {
            return maxShadowSize;
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
        mCornerShadowPaint.setColorFilter(cf);
        mEdgeShadowPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    void setCornerRadius(float radius) {
        radius = (int) (radius + .5f);
        if (mCornerRadius == radius) {
            return;
        }
        mCornerRadius = radius;
        mDirty = true;
        invalidateSelf();
    }

    @Override
    public void draw(Canvas canvas) {
        if (mDirty) {
            buildComponents(getBounds());
            mDirty = false;
        }
        canvas.translate(0, -mRawShadowSize / 2);
        drawShadow(canvas);
        canvas.translate(0, +mRawShadowSize / 2);
        sRoundRectHelper.drawRoundRect(canvas, mCardBounds, mCornerRadius, mPaint);
    }

    private void drawShadow(Canvas canvas) {
        final float edgeShadowTop = -mCornerRadius - mShadowSize;
        final float insetVertical = mCornerRadius + mInsetShadow + mRawShadowSize / 2;
        final float insetHorizontal = -mInsetShadow;
        // LT top
        int saved = canvas.save();
        canvas.translate(mCardBounds.left + insetHorizontal, mCardBounds.top + insetVertical);
        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
        canvas.drawRect(0, edgeShadowTop,    mCardBounds.width() - 2 * insetHorizontal, -mCornerRadius + mShadowSize,  mEdgeShadowPaint);
        canvas.restoreToCount(saved);

        // RT right
        saved = canvas.save();
        canvas.translate(mCardBounds.right - insetHorizontal, mCardBounds.top + insetVertical);
        canvas.rotate(90f);
        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
        canvas.restoreToCount(saved);
    }

    private void buildShadowCorners() {
        RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);
        RectF outerBounds = new RectF(innerBounds);
        outerBounds.inset(-mShadowSize, -mShadowSize);

        if (mCornerShadowPath == null) {
            mCornerShadowPath = new Path();
        } else {
            mCornerShadowPath.reset();
        }
        mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD);
        mCornerShadowPath.moveTo(-mCornerRadius, 0);
        mCornerShadowPath.rLineTo(-mShadowSize, 0);
        // outer arc
        mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false);
        // inner arc
        mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false);
        mCornerShadowPath.close();
        float startRatio = mCornerRadius / (mCornerRadius + mShadowSize);
        mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize,
                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
                new float[]{0f, startRatio, 1f}
                , Shader.TileMode.CLAMP));

        // we offset the content shadowSize/2 pixels up to make it more realistic.
        // this is why edge shadow shader has some extra space
        // When drawing bottom edge shadow, we use that extra space.
        mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0,
                -mCornerRadius - mShadowSize,
                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
                new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP));
        mEdgeShadowPaint.setAntiAlias(false);
    }

    private void buildComponents(Rect bounds) {
        // Card is offset SHADOW_MULTIPLIER * maxShadowSize to account for the shadow shift.
        // We could have different top-bottom offsets to avoid extra gap above but in that case
        // center aligning Views inside the CardView would be problematic.
        final float verticalOffset = mRawMaxShadowSize * SHADOW_MULTIPLIER;
        mCardBounds.set(bounds.left + mRawMaxShadowSize, bounds.top + verticalOffset,
                bounds.right - mRawMaxShadowSize, bounds.bottom - verticalOffset);
        buildShadowCorners();
    }

    float getCornerRadius() {
        return mCornerRadius;
    }

    void getMaxShadowAndCornerPadding(Rect into) {
        getPadding(into);
    }

    void setShadowSize(float size) {
        setShadowSize(size, mRawMaxShadowSize);
    }

    void setMaxShadowSize(float size) {
        setShadowSize(mRawShadowSize, size);
    }

    float getShadowSize() {
        return mRawShadowSize;
    }

    float getMaxShadowSize() {
        return mRawMaxShadowSize;
    }

    float getMinWidth() {
        final float content = 2 *
                Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow + mRawMaxShadowSize / 2);
        return content + (mRawMaxShadowSize + mInsetShadow) * 2;
    }

    float getMinHeight() {
        final float content = 2 * Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow
                + mRawMaxShadowSize * SHADOW_MULTIPLIER / 2);
        return content + (mRawMaxShadowSize * SHADOW_MULTIPLIER + mInsetShadow) * 2;
    }

    public void setColor(int color) {
        mPaint.setColor(color);
        invalidateSelf();
    }

    interface RoundRectHelper {
        void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, Paint paint);
    }
}

================================================
FILE: lib/src/main/java/no/agens/depth/lib/DepthLayout.java
================================================
package no.agens.depth.lib;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.RelativeLayout;

public class DepthLayout extends RelativeLayout {


    public static final int DEFAULT_EDGE_COLOR = Color.WHITE;
    public static final int DEFAULT_THICKNESS = 2;
    Paint edgePaint = new Paint();

    public DepthLayout(Context context) {
        super(context);
        initView(null);

    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    public Paint getEdgePaint() {
        return edgePaint;
    }


    public void setEdgePaint(Paint edgePaint) {
        this.edgePaint = edgePaint;
    }

    private void initView(AttributeSet attrs) {

        edgePaint.setColor(DEFAULT_EDGE_COLOR);
        edgePaint.setAntiAlias(true);
        TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.DepthView);
        if (attrs != null) {
            try {
                edgePaint.setColor(arr.getInt(R.styleable.DepthView_edge_color, DEFAULT_EDGE_COLOR));
                setIsCircle(arr.getBoolean(R.styleable.DepthView_is_circle, false));
                depth = arr.getDimension(R.styleable.DepthView_depth, DEFAULT_THICKNESS * getResources().getDisplayMetrics().density);
                customShadowElevation = arr.getDimension(R.styleable.DepthView_custom_elevation, 0);
            } finally {
                arr.recycle();
            }

        } else {
            edgePaint.setColor(DEFAULT_EDGE_COLOR);
            depth = DEFAULT_THICKNESS * getResources().getDisplayMetrics().density;
        }
        setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {

            }
        });
    }


    public DepthLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);

    }

    public DepthLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }


    private float depth;


    public float getDepth() {
        return depth;
    }

    public void setDepth(float depth) {
        this.depth = depth;
        ((View) getParent()).invalidate();
    }

    public boolean isCircle() {
        return isCircle;
    }

    public void setIsCircle(boolean isCircle) {
        this.isCircle = isCircle;
    }

    private boolean isCircle = false;

    float[] prevSrc = new float[8];

    public boolean calculateBounds() {

        float[] src = new float[8];
        float[] dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};
        Matrix matrix = getMatrix();

        matrix.mapPoints(src, dst);
        topLeft.x = src[0] + getLeft();
        topLeft.y = src[1] + getTop();
        topRight.x = src[2] + getLeft();
        topRight.y = src[3] + getTop();

        bottomLeft.x = src[4] + getLeft();
        bottomLeft.y = src[5] + getTop();
        bottomRight.x = src[6] + getLeft();
        bottomRight.y = src[7] + getTop();
        boolean returnValue = hasMatrixChanged(src);
        prevSrc = src;
        float percentFrom90X = (getRotationX()) / 90f;
        float percentFrom90Y = (-getRotationY()) / 90f;


        matrix.postTranslate(percentFrom90Y * getDepth(), percentFrom90X * getDepth());
        src = new float[8];
        dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};
        matrix.mapPoints(src, dst);

        topLeftBack.x = src[0] + getLeft();
        topLeftBack.y = src[1] + getTop();
        topRightBack.x = src[2] + getLeft();
        topRightBack.y = src[3] + getTop();

        bottomLeftBack.x = src[4] + getLeft();
        bottomLeftBack.y = src[5] + getTop();
        bottomRightBack.x = src[6] + getLeft();
        bottomRightBack.y = src[7] + getTop();
        customShadow.calculateBounds(this);

        return returnValue;
    }

    boolean hasMatrixChanged(float[] newSrc) {
        for (int i = 0; i < 8; i++) {
            if (newSrc[i] != prevSrc[i])
                return true;
        }
        return false;
    }

    public PointF getTopLeft() {
        return topLeft;
    }

    public PointF getTopRight() {
        return topRight;
    }

    public PointF getBottomLeft() {
        return bottomLeft;
    }

    public PointF getBottomRight() {
        return bottomRight;
    }

    public PointF getTopLeftBack() {
        return topLeftBack;
    }

    public PointF getTopRightBack() {
        return topRightBack;
    }

    public PointF getBottomLeftBack() {
        return bottomLeftBack;
    }

    public PointF getBottomRightBack() {
        return bottomRightBack;
    }

    final PointF topLeft = new PointF(0, 0);
    PointF topRight = new PointF(0, 0);
    PointF bottomLeft = new PointF(0, 0);
    PointF bottomRight = new PointF(0, 0);


    PointF topLeftBack = new PointF(0, 0);
    PointF topRightBack = new PointF(0, 0);
    PointF bottomLeftBack = new PointF(0, 0);
    PointF bottomRightBack = new PointF(0, 0);


    private CustomShadow customShadow = new CustomShadow();

    public CustomShadow getCustomShadow() {
        return customShadow;
    }

    public void setCustomShadowElevation(float customShadowElevation) {
        this.customShadowElevation = customShadowElevation;
        ((View) getParent()).invalidate();
    }

    public float getCustomShadowElevation() {
        return customShadowElevation;
    }

    float customShadowElevation;

    class CustomShadow {

        public static final float DEFAULT_SHADOW_PADDING = 10f;
        PointF topLeftBack = new PointF(0, 0);
        PointF topRightBack = new PointF(0, 0);
        PointF bottomLeftBack = new PointF(0, 0);
        PointF bottomRightBack = new PointF(0, 0);
        int padding;

        public void calculateBounds(DepthLayout target) {
            float[] src = new float[8];
            float density = getResources().getDisplayMetrics().density;
            float offsetY = customShadowElevation;
            float offsetX = customShadowElevation / 5;
            padding = (int) (customShadowElevation / 4f + DEFAULT_SHADOW_PADDING * density);

            float[] dst = new float[]{-padding, -padding, target.getWidth() + padding, -padding, -padding, target.getHeight() + padding, target.getWidth() + padding, target.getHeight() + padding};
            Matrix matrix = getMatrix();
            matrix.mapPoints(src, dst);

            topLeftBack.x = src[0] + target.getLeft() + offsetX;
            topLeftBack.y = src[1] + target.getTop() + offsetY;
            topRightBack.x = src[2] + target.getLeft() + offsetX;
            topRightBack.y = src[3] + target.getTop() + offsetY;

            bottomLeftBack.x = src[4] + target.getLeft() + offsetX;
            bottomLeftBack.y = src[5] + target.getTop() + offsetY;
            bottomRightBack.x = src[6] + target.getLeft() + offsetX;
            bottomRightBack.y = src[7] + target.getTop() + offsetY;

        }

        Matrix matrix = new Matrix();

        public void drawShadow(Canvas canvas, DepthLayout dl, Drawable shadow) {

            shadow.setBounds(-padding, -padding, dl.getWidth() + padding, dl.getHeight() + padding);
            float[] src = new float[]{0, 0, dl.getWidth(), 0, dl.getWidth(), dl.getHeight(), 0, dl.getHeight()};
            float[] dst = new float[]{topLeftBack.x, topLeftBack.y, topRightBack.x, topRightBack.y, bottomRightBack.x, bottomRightBack.y, bottomLeftBack.x, bottomLeftBack.y};
            int count = canvas.save();
            matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
            canvas.concat(matrix);
            shadow.draw(canvas);
            canvas.restoreToCount(count);
        }
    }
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/DepthRendrer.java
================================================
package no.agens.depth.lib;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;


public class DepthRendrer extends RelativeLayout {

    private final Paint shadowPaint = new Paint();
    private NinePatchDrawable softShadow;
    private Drawable roundSoftShadow;

    private Path edgePath = new Path();

    public DepthRendrer(Context context) {
        super(context);
        setup();

    }

    public DepthRendrer(Context context, AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    public DepthRendrer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setup();
    }

    public DepthRendrer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setup();
    }

    public float getTopEdgeLength(DepthLayout dl) {
        return getDistance(dl.getTopLeftBack(), dl.getTopRightBack());
    }

    float getDistance(PointF p1, PointF p2) {
        return (float) Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
    }

    public float getShadowAlpha() {
        return shadowAlpha;
    }

    public void setShadowAlpha(float shadowAlpha) {
        this.shadowAlpha = Math.min(1f, Math.max(0, shadowAlpha));
    }

    private float shadowAlpha = 0.3f;

    void setup() {
        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                for (int i = 0; i < getChildCount(); i++) {
                    View child = getChildAt(i);
                    if (child instanceof DepthLayout) {
                        boolean hasChangedBounds = ((DepthLayout) child).calculateBounds();
                        if (hasChangedBounds)
                            invalidate();
                    }
                }
                return true;
            }
        });

        shadowPaint.setColor(Color.BLACK);
        shadowPaint.setAntiAlias(true);
        softShadow = (NinePatchDrawable) getResources().getDrawable(R.drawable.shadow, null);
        roundSoftShadow = getResources().getDrawable(R.drawable.round_soft_shadow, null);
    }

    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        if (child instanceof DepthLayout && !isInEditMode()) {
            DepthLayout dl = (DepthLayout) child;


            float[] src = new float[]{0, 0, dl.getWidth(), 0, dl.getWidth(), dl.getHeight(), 0, dl.getHeight()};
            if (dl.isCircle()) {
                dl.getCustomShadow().drawShadow(canvas, dl, roundSoftShadow);
                if (Math.abs(dl.getRotationX()) > 1 || Math.abs(dl.getRotationY()) > 1)
                    drawCornerBaseShape(dl, canvas, src);
            } else {
                dl.getCustomShadow().drawShadow(canvas, dl, softShadow);
                if (dl.getRotationX() != 0 || dl.getRotationY() != 0) {
                    if (getLongestHorizontalEdge(dl) > getLongestVerticalEdge(dl))
                        drawVerticalFirst(dl, canvas, src);
                    else
                        drawHorizontalFist(dl, canvas, src);
                }
            }
        }
        return super.drawChild(canvas, child, drawingTime);
    }

    private void drawCornerBaseShape(DepthLayout dl, Canvas canvas, float[] src) {
        float[] dst = new float[]{dl.getTopLeftBack().x, dl.getTopLeftBack().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y};
        int count = canvas.save();
        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
        canvas.concat(matrix);
        edgePath.reset();
        edgePath.addRoundRect(0, 0, dl.getWidth(), dl.getHeight(), dl.getWidth() / 2f, dl.getHeight() / 2f, Path.Direction.CCW);

        canvas.drawPath(edgePath, dl.getEdgePaint());
        shadowPaint.setAlpha((int) (shadowAlpha * 0.5f * 255));
        canvas.drawPath(edgePath, shadowPaint);

        canvas.restoreToCount(count);
    }


    private void drawHorizontalFist(DepthLayout dl, Canvas canvas, float[] src) {
        if (getLeftEdgeLength(dl) <= getRightEdgeLength(dl)) {
            drawLeftEdge(dl, canvas, src);
        } else {
            drawRightEdge(dl, canvas, src);
        }

        drawTopEdge(dl, canvas, src);
        drawBottomEdge(dl, canvas, src);

        if (getLeftEdgeLength(dl) >= getRightEdgeLength(dl)) {
            drawLeftEdge(dl, canvas, src);
        } else {
            drawRightEdge(dl, canvas, src);
        }
    }

    private void drawVerticalFirst(DepthLayout dl, Canvas canvas, float[] src) {

        if (getTopEdgeLength(dl) <= getBottomEdgeLength(dl)) {
            drawTopEdge(dl, canvas, src);
        } else {
            drawBottomEdge(dl, canvas, src);
        }

        drawLeftEdge(dl, canvas, src);
        drawRightEdge(dl, canvas, src);


        if (getTopEdgeLength(dl) >= getBottomEdgeLength(dl)) {
            drawTopEdge(dl, canvas, src);
        } else {
            drawBottomEdge(dl, canvas, src);
        }

    }

    float getLongestHorizontalEdge(DepthLayout dl) {
        float topEdgeLength = getTopEdgeLength(dl);
        float bottomEdgeLength = getBottomEdgeLength(dl);
        if (topEdgeLength > bottomEdgeLength) {
            return topEdgeLength;
        } else {
            return bottomEdgeLength;
        }
    }

    float getLongestVerticalEdge(DepthLayout dl) {
        float leftEdgeLength = getLeftEdgeLength(dl);
        float rightEdgeLength = getRightEdgeLength(dl);
        if (leftEdgeLength > rightEdgeLength) {
            return leftEdgeLength;
        } else {
            return rightEdgeLength;
        }
    }

    private float getRightEdgeLength(DepthLayout dl) {
        return getDistance(dl.getTopRightBack(), dl.getBottomRightBack());
    }

    private float getLeftEdgeLength(DepthLayout dl) {
        return getDistance(dl.getTopLeftBack(), dl.getBottomLeftBack());
    }


    private float getBottomEdgeLength(DepthLayout dl) {
        return getDistance(dl.getBottomLeftBack(), dl.getBottomRightBack());
    }


    void drawShadow(PointF point1, PointF point2, float correctionValue, Canvas canvas, DepthLayout dl) {
        float angle = Math.abs(Math.abs(getAngle(point1, point2)) + correctionValue);
        float alpha = angle / 180f;
        shadowPaint.setAlpha((int) (alpha * 255f * shadowAlpha));

        canvas.drawRect(0, 0, dl.getWidth(), dl.getHeight(), shadowPaint);
    }


    private void drawRectancle(DepthLayout dl, Canvas canvas) {
        canvas.drawRect(0, 0, dl.getWidth(), dl.getHeight(), dl.getEdgePaint());
    }

    public float getAngle(PointF point1, PointF point2) {

        return (float) Math.toDegrees(Math.atan2(point1.y - point2.y, point1.x - point2.x));
    }

    private void drawLeftEdge(DepthLayout dl, Canvas canvas, float[] src) {
        float[] dst = new float[]{dl.getTopLeft().x, dl.getTopLeft().y, dl.getTopLeftBack().x, dl.getTopLeftBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y, dl.getBottomLeft().x, dl.getBottomLeft().y};
        int count = canvas.save();
        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
        canvas.concat(matrix);
        drawRectancle(dl, canvas);
        drawShadow(dl.getTopLeft(), dl.getBottomLeft(), 0, canvas, dl);

        canvas.restoreToCount(count);

    }

    private void drawRightEdge(DepthLayout dl, Canvas canvas, float[] src) {
        float[] dst = new float[]{dl.getTopRight().x, dl.getTopRight().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomRight().x, dl.getBottomRight().y};
        int count = canvas.save();
        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
        canvas.concat(matrix);
        drawRectancle(dl, canvas);
        drawShadow(dl.getTopRight(), dl.getBottomRight(), -180f, canvas, dl);
        canvas.restoreToCount(count);
    }

    android.graphics.Matrix matrix = new android.graphics.Matrix();

    private void drawTopEdge(DepthLayout dl, Canvas canvas, float[] src) {

        float[] dst = new float[]{dl.getTopLeft().x, dl.getTopLeft().y, dl.getTopRight().x, dl.getTopRight().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getTopLeftBack().x, dl.getTopLeftBack().y};
        int count = canvas.save();
        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
        canvas.concat(matrix);
        drawRectancle(dl, canvas);
        drawShadow(dl.getTopLeft(), dl.getTopRight(), -180f, canvas, dl);
        canvas.restoreToCount(count);
    }

    private void drawBottomEdge(DepthLayout dl, Canvas canvas, float[] src) {

        float[] dst = new float[]{dl.getBottomLeft().x, dl.getBottomLeft().y, dl.getBottomRight().x, dl.getBottomRight().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y};
        int count = canvas.save();
        matrix.setPolyToPoly(src, 0, dst, 0, dst.length >> 1);
        canvas.concat(matrix);
        drawRectancle(dl, canvas);
        drawShadow(dl.getBottomLeft(), dl.getBottomRight(), 0, canvas, dl);
        canvas.restoreToCount(count);
    }
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/MaterialMenuDrawable.java
================================================
package no.agens.depth.lib;
        import android.animation.Animator;
        import android.animation.AnimatorListenerAdapter;
        import android.animation.ObjectAnimator;
        import android.content.Context;
        import android.content.res.Resources;
        import android.graphics.Canvas;
        import android.graphics.Color;
        import android.graphics.ColorFilter;
        import android.graphics.Paint;
        import android.graphics.PixelFormat;
        import android.graphics.drawable.Animatable;
        import android.graphics.drawable.Drawable;
        import android.util.Property;
        import android.util.TypedValue;
        import android.view.animation.DecelerateInterpolator;
        import android.view.animation.Interpolator;

        import static android.graphics.Paint.Style;

public class MaterialMenuDrawable extends Drawable implements Animatable {

    public enum IconState {
        BURGER, ARROW, X, CHECK
    }

    public enum AnimationState {
        BURGER_ARROW, BURGER_X, ARROW_X, ARROW_CHECK, BURGER_CHECK, X_CHECK;

        public IconState getFirstState() {
            switch (this) {
                case BURGER_ARROW:
                    return IconState.BURGER;
                case BURGER_X:
                    return IconState.BURGER;
                case ARROW_X:
                    return IconState.ARROW;
                case ARROW_CHECK:
                    return IconState.ARROW;
                case BURGER_CHECK:
                    return IconState.BURGER;
                case X_CHECK:
                    return IconState.X;
                default:
                    return null;
            }
        }

        public IconState getSecondState() {
            switch (this) {
                case BURGER_ARROW:
                    return IconState.ARROW;
                case BURGER_X:
                    return IconState.X;
                case ARROW_X:
                    return IconState.X;
                case ARROW_CHECK:
                    return IconState.CHECK;
                case BURGER_CHECK:
                    return IconState.CHECK;
                case X_CHECK:
                    return IconState.CHECK;
                default:
                    return null;
            }
        }
    }

    public enum Stroke {
        /**
         * 3 dip
         */
        REGULAR(3),
        /**
         * 2 dip
         */
        THIN(2),
        /**
         * 1 dip
         */
        EXTRA_THIN(1);

        private final int strokeWidth;

        Stroke(int strokeWidth) {
            this.strokeWidth = strokeWidth;
        }

        protected static Stroke valueOf(int strokeWidth) {
            switch (strokeWidth) {
                case 3:
                    return REGULAR;
                case 2:
                    return THIN;
                case 1:
                    return EXTRA_THIN;
                default:
                    return THIN;
            }
        }
    }

    public static final int     DEFAULT_COLOR              = Color.WHITE;
    public static final int     DEFAULT_SCALE              = 1;
    public static final int     DEFAULT_TRANSFORM_DURATION = 800;
    public static final boolean DEFAULT_VISIBLE            = true;

    private static final int BASE_DRAWABLE_WIDTH  = 40;
    private static final int BASE_DRAWABLE_HEIGHT = 40;
    private static final int BASE_ICON_WIDTH      = 20;
    private static final int BASE_CIRCLE_RADIUS   = 18;

    private static final float ARROW_MID_LINE_ANGLE = 180;
    private static final float ARROW_TOP_LINE_ANGLE = 135;
    private static final float ARROW_BOT_LINE_ANGLE = 225;
    private static final float X_TOP_LINE_ANGLE     = 44;
    private static final float X_BOT_LINE_ANGLE     = -44;
    private static final float X_ROTATION_ANGLE     = 90;
    private static final float CHECK_MIDDLE_ANGLE   = 135;
    private static final float CHECK_BOTTOM_ANGLE   = -90;

    private static final float TRANSFORMATION_START = 0;
    private static final float TRANSFORMATION_MID   = 1.0f;
    private static final float TRANSFORMATION_END   = 2.0f;

    private static final int DEFAULT_CIRCLE_ALPHA = 200;

    private final float diph;
    private final float dip1;
    private final float dip2;
    private final float dip3;
    private final float dip4;
    private final float dip8;

    private final int   width;
    private final int   height;
    private final float strokeWidth;
    private final float iconWidth;
    private final float topPadding;
    private final float sidePadding;
    private final float circleRadius;

    private final Stroke stroke;

    private final Object lock = new Object();

    private final Paint iconPaint   = new Paint();
    private final Paint circlePaint = new Paint();

    private float   transformationValue   = 0f;
    private boolean transformationRunning = false;

    private IconState      currentIconState = IconState.BURGER;
    private AnimationState animationState   = AnimationState.BURGER_ARROW;

    private IconState animatingIconState;
    private boolean   visible;
    private boolean   rtlEnabled;

    private ObjectAnimator transformation;
    private Animator.AnimatorListener animatorListener;

    private MaterialMenuState materialMenuState;

    public MaterialMenuDrawable(Context context, int color, Stroke stroke) {
        this(context, color, stroke, DEFAULT_SCALE, DEFAULT_TRANSFORM_DURATION);
    }

    public MaterialMenuDrawable(Context context, int color, Stroke stroke, int transformDuration) {
        this(context, color, stroke, DEFAULT_SCALE, transformDuration);
    }

    public MaterialMenuDrawable(Context context, int color, Stroke stroke, int scale, int transformDuration) {
        Resources resources = context.getResources();
        // convert each separately due to various densities
        this.dip1 = dpToPx(resources, 1) * scale;
        this.dip2 = dpToPx(resources, 2) * scale;
        this.dip3 = dpToPx(resources, 3) * scale;
        this.dip4 = dpToPx(resources, 4) * scale;
        this.dip8 = dpToPx(resources, 8) * scale;
        this.diph = dip1 / 2;

        this.stroke = stroke;
        this.visible = DEFAULT_VISIBLE;
        this.width = (int) (dpToPx(resources, BASE_DRAWABLE_WIDTH) * scale);
        this.height = (int) (dpToPx(resources, BASE_DRAWABLE_HEIGHT) * scale);
        this.iconWidth = dpToPx(resources, BASE_ICON_WIDTH) * scale;
        this.circleRadius = dpToPx(resources, BASE_CIRCLE_RADIUS) * scale;
        this.strokeWidth = dpToPx(resources, stroke.strokeWidth) * scale;

        this.sidePadding = (width - iconWidth) / 2;
        this.topPadding = (height - 5 * dip3) / 2;

        initPaint(color);
        initAnimations(transformDuration);

        materialMenuState = new MaterialMenuState();
    }

    private MaterialMenuDrawable(int color, Stroke stroke, long transformDuration, int width, int height,
                                 float iconWidth, float circleRadius, float strokeWidth, float dip1
    ) {
        this.dip1 = dip1;
        this.dip2 = dip1 * 2;
        this.dip3 = dip1 * 3;
        this.dip4 = dip1 * 4;
        this.dip8 = dip1 * 8;
        this.diph = dip1 / 2;
        this.stroke = stroke;
        this.width = width;
        this.height = height;
        this.iconWidth = iconWidth;
        this.circleRadius = circleRadius;
        this.strokeWidth = strokeWidth;
        this.sidePadding = (width - iconWidth) / 2;
        this.topPadding = (height - 5 * dip3) / 2;

        initPaint(color);
        initAnimations((int) transformDuration);

        materialMenuState = new MaterialMenuState();
    }

    private void initPaint(int color) {
        iconPaint.setAntiAlias(true);
        iconPaint.setStyle(Style.STROKE);
        iconPaint.setStrokeWidth(strokeWidth);
        iconPaint.setColor(color);

        circlePaint.setAntiAlias(true);
        circlePaint.setStyle(Style.FILL);
        circlePaint.setColor(color);
        circlePaint.setAlpha(DEFAULT_CIRCLE_ALPHA);

        setBounds(0, 0, width, height);
    }

    /*
     * Drawing
     */

    @Override public void draw(Canvas canvas) {
        if (!visible) return;

        final float ratio = transformationValue <= 1 ? transformationValue : 2 - transformationValue;

        if (rtlEnabled) {
            canvas.save();
            canvas.scale(-1, 1, 0, 0);
            canvas.translate(-getIntrinsicWidth(), 0);
        }

        drawTopLine(canvas, ratio);
        drawMiddleLine(canvas, ratio);
        drawBottomLine(canvas, ratio);

        if (rtlEnabled) {
            canvas.restore();
        }
    }

    private void drawMiddleLine(Canvas canvas, float ratio) {
        canvas.restore();
        canvas.save();

        float rotation = 0;
        float pivotX = width / 2;
        float pivotY = width / 2;
        float startX = sidePadding;
        float startY = topPadding + dip3 / 2 * 5;
        float stopX = width - sidePadding;
        float stopY = topPadding + dip3 / 2 * 5;
        int alpha = 255;

        switch (animationState) {
            case BURGER_ARROW:
                // rotate by 180
                if (isMorphingForward()) {
                    rotation = ratio * ARROW_MID_LINE_ANGLE;
                } else {
                    rotation = ARROW_MID_LINE_ANGLE + (1 - ratio) * ARROW_MID_LINE_ANGLE;
                }
                // shorten one end
                stopX -= ratio * resolveStrokeModifier(ratio) / 2;
                break;
            case BURGER_X:
                // fade out
                alpha = (int) ((1 - ratio) * 255);
                break;
            case ARROW_X:
                // fade out and shorten one end
                alpha = (int) ((1 - ratio) * 255);
                startX += (1 - ratio) * dip2;
                break;
            case ARROW_CHECK:
                if (isMorphingForward()) {
                    // rotate until required angle
                    rotation = ratio * CHECK_MIDDLE_ANGLE;
                } else {
                    // rotate back to starting angle
                    rotation = CHECK_MIDDLE_ANGLE - CHECK_MIDDLE_ANGLE * (1 - ratio);
                }
                // shorten one end and lengthen the other
                startX += dip3 / 2 + dip4 - (1 - ratio) * dip2;
                stopX += ratio * dip1;
                pivotX = width / 2 + dip3 + diph;
                break;
            case BURGER_CHECK:
                // rotate until required angle
                rotation = ratio * CHECK_MIDDLE_ANGLE;
                // lengthen both ends
                startX += ratio * (dip4 + dip3 / 2);
                stopX += ratio * dip1;
                pivotX = width / 2 + dip3 + diph;
                break;
            case X_CHECK:
                // fade in
                alpha = (int) (ratio * 255);
                // rotation to check angle
                rotation = ratio * CHECK_MIDDLE_ANGLE;
                // lengthen both ends
                startX += ratio * (dip4 + dip3 / 2);
                stopX += ratio * dip1;
                pivotX = width / 2 + dip3 + diph;
                break;
        }

        iconPaint.setAlpha(alpha);
        canvas.rotate(rotation, pivotX, pivotY);
        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
        iconPaint.setAlpha(255);
    }

    private void drawTopLine(Canvas canvas, float ratio) {
        canvas.save();

        float rotation = 0, pivotX = 0, pivotY = 0;
        float rotation2 = 0;
        // pivot at center of line
        float pivotX2 = width / 2 + dip3 / 2;
        float pivotY2 = topPadding + dip2;

        float startX = sidePadding;
        float startY = topPadding + dip2;
        float stopX = width - sidePadding;
        float stopY = topPadding + dip2;
        int alpha = 255;

        switch (animationState) {
            case BURGER_ARROW:
                if (isMorphingForward()) {
                    // rotate until required angle
                    rotation = ratio * ARROW_BOT_LINE_ANGLE;
                } else {
                    // rotate back to start doing a 360
                    rotation = ARROW_BOT_LINE_ANGLE + (1 - ratio) * ARROW_TOP_LINE_ANGLE;
                }
                // rotate by middle
                pivotX = width / 2;
                pivotY = height / 2;

                // shorten both ends
                stopX -= resolveStrokeModifier(ratio);
                startX += dip3 * ratio;

                break;
            case BURGER_X:
                // rotate until required angles
                rotation = X_TOP_LINE_ANGLE * ratio;
                rotation2 = X_ROTATION_ANGLE * ratio;

                // pivot at left corner of line
                pivotX = sidePadding + dip4;
                pivotY = topPadding + dip3;

                // shorten one end
                startX += dip3 * ratio;
                break;
            case ARROW_X:
                // rotate from ARROW angle to x angle
                rotation = ARROW_BOT_LINE_ANGLE + (X_TOP_LINE_ANGLE - ARROW_BOT_LINE_ANGLE) * ratio;
                rotation2 = X_ROTATION_ANGLE * ratio;

                // move pivot from ARROW pivot to x pivot
                pivotX = width / 2 + (sidePadding + dip4 - width / 2) * ratio;
                pivotY = height / 2 + (topPadding + dip3 - height / 2) * ratio;

                // lengthen both ends
                stopX -= resolveStrokeModifier(ratio);
                startX += dip3;
                break;
            case ARROW_CHECK:
                // fade out
                alpha = (int) ((1 - ratio) * 255);
                // retain starting arrow configuration
                rotation = ARROW_BOT_LINE_ANGLE;
                pivotX = width / 2;
                pivotY = height / 2;

                // shorted both ends
                stopX -= resolveStrokeModifier(1);
                startX += dip3;
                break;
            case BURGER_CHECK:
                // fade out
                alpha = (int) ((1 - ratio) * 255);
                break;
            case X_CHECK:
                // retain x configuration
                rotation = X_TOP_LINE_ANGLE;
                rotation2 = X_ROTATION_ANGLE;
                pivotX = sidePadding + dip4;
                pivotY = topPadding + dip3;
                stopX += dip3 - dip3 * (1 - ratio);
                startX += dip3;

                // fade out
                alpha = (int) ((1 - ratio) * 255);
                break;
        }

        iconPaint.setAlpha(alpha);
        canvas.rotate(rotation, pivotX, pivotY);
        canvas.rotate(rotation2, pivotX2, pivotY2);
        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
        iconPaint.setAlpha(255);
    }

    private void drawBottomLine(Canvas canvas, float ratio) {
        canvas.restore();
        canvas.save();

        float rotation = 0, pivotX = 0, pivotY = 0;
        float rotation2 = 0;
        // pivot at center of line
        float pivotX2 = width / 2 + dip3 / 2;
        float pivotY2 = height - topPadding - dip2;

        float startX = sidePadding;
        float startY = height - topPadding - dip2;
        float stopX = width - sidePadding;
        float stopY = height - topPadding - dip2;

        switch (animationState) {
            case BURGER_ARROW:
                if (isMorphingForward()) {
                    // rotate to required angle
                    rotation = ARROW_TOP_LINE_ANGLE * ratio;
                } else {
                    // rotate back to start doing a 360
                    rotation = ARROW_TOP_LINE_ANGLE + (1 - ratio) * ARROW_BOT_LINE_ANGLE;
                }
                // pivot center of canvas
                pivotX = width / 2;
                pivotY = height / 2;

                // shorten both ends
                stopX = width - sidePadding - resolveStrokeModifier(ratio);
                startX = sidePadding + dip3 * ratio;
                break;
            case BURGER_X:
                if (isMorphingForward()) {
                    // rotate around
                    rotation2 = -X_ROTATION_ANGLE * ratio;
                } else {
                    // rotate directly
                    rotation2 = X_ROTATION_ANGLE * ratio;
                }
                // rotate to required angle
                rotation = X_BOT_LINE_ANGLE * ratio;

                // pivot left corner of line
                pivotX = sidePadding + dip4;
                pivotY = height - topPadding - dip3;

                // shorten one end
                startX += dip3 * ratio;
                break;
            case ARROW_X:
                // rotate from ARROW angle to x angle
                rotation = ARROW_TOP_LINE_ANGLE + (360 + X_BOT_LINE_ANGLE - ARROW_TOP_LINE_ANGLE) * ratio;
                rotation2 = -X_ROTATION_ANGLE * ratio;

                // move pivot from ARROW pivot to x pivot
                pivotX = width / 2 + (sidePadding + dip4 - width / 2) * ratio;
                pivotY = height / 2 + (height / 2 - topPadding - dip3) * ratio;

                // lengthen both ends
                stopX -= resolveStrokeModifier(ratio);
                startX += dip3;
                break;
            case ARROW_CHECK:
                // rotate from ARROW angle to CHECK angle
                rotation = ARROW_TOP_LINE_ANGLE + ratio * CHECK_BOTTOM_ANGLE;

                // move pivot from ARROW pivot to CHECK pivot
                pivotX = width / 2 + dip3 * ratio;
                pivotY = height / 2 - dip3 * ratio;

                // length stays same as ARROW
                stopX -= resolveStrokeModifier(1);
                startX += dip3 + (dip4 + dip1) * ratio;
                break;
            case BURGER_CHECK:
                // rotate from ARROW angle to CHECK angle
                rotation = ratio * (CHECK_BOTTOM_ANGLE + ARROW_TOP_LINE_ANGLE);

                // move pivot from BURGER pivot to CHECK pivot
                pivotX = width / 2 + dip3 * ratio;
                pivotY = height / 2 - dip3 * ratio;

                // length stays same as BURGER
                startX += dip8 * ratio;
                stopX -= resolveStrokeModifier(ratio);
                break;
            case X_CHECK:
                // rotate from x to CHECK angles
                rotation2 = -X_ROTATION_ANGLE * (1 - ratio);
                rotation = X_BOT_LINE_ANGLE + (CHECK_BOTTOM_ANGLE + ARROW_TOP_LINE_ANGLE - X_BOT_LINE_ANGLE) * ratio;

                // move pivot from x to CHECK
                pivotX = sidePadding + dip4 + (width / 2 + dip3 - sidePadding - dip4) * ratio;
                pivotY = height - topPadding - dip3 + (topPadding + height / 2 - height) * ratio;

                // shorten both ends
                startX += dip8 - (dip4 + dip1) * (1 - ratio);
                stopX -= resolveStrokeModifier(1 - ratio);
                break;
        }

        canvas.rotate(rotation, pivotX, pivotY);
        canvas.rotate(rotation2, pivotX2, pivotY2);
        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);
    }

    private boolean isMorphingForward() {
        return transformationValue <= TRANSFORMATION_MID;
    }

    private float resolveStrokeModifier(float ratio) {
        switch (stroke) {
            case REGULAR:
                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {
                    return dip3 - (dip3 * ratio);
                }
                return ratio * dip3;
            case THIN:
                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {
                    return dip3 + diph - (dip3 + diph) * ratio;
                }
                return ratio * (dip3 + diph);
            case EXTRA_THIN:
                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {
                    return dip4 - ((dip3 + dip1) * ratio);
                }
                return ratio * dip4;
        }
        return 0;
    }

    @Override public void setAlpha(int alpha) {
        iconPaint.setAlpha(alpha);
    }

    @Override public void setColorFilter(ColorFilter cf) {
        iconPaint.setColorFilter(cf);
    }

    @Override public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }

    /*
     * Accessor methods
     */

    public void setColor(int color) {
        iconPaint.setColor(color);
        circlePaint.setColor(color);
        invalidateSelf();
    }

    public void setTransformationDuration(int duration) {
        transformation.setDuration(duration);
    }

    public void setInterpolator(Interpolator interpolator) {
        transformation.setInterpolator(interpolator);
    }

    public void setAnimationListener(Animator.AnimatorListener listener) {
        if (animatorListener != null) {
            transformation.removeListener(animatorListener);
        }

        if (listener != null) {
            transformation.addListener(listener);
        }

        animatorListener = listener;
    }

    public void setIconState(IconState iconState) {
        synchronized (lock) {
            if (transformationRunning) {
                transformation.cancel();
                transformationRunning = false;
            }

            if (currentIconState == iconState) return;

            switch (iconState) {
                case BURGER:
                    animationState = AnimationState.BURGER_ARROW;
                    transformationValue = TRANSFORMATION_START;
                    break;
                case ARROW:
                    animationState = AnimationState.BURGER_ARROW;
                    transformationValue = TRANSFORMATION_MID;
                    break;
                case X:
                    animationState = AnimationState.BURGER_X;
                    transformationValue = TRANSFORMATION_MID;
                    break;
                case CHECK:
                    animationState = AnimationState.BURGER_CHECK;
                    transformationValue = TRANSFORMATION_MID;
            }
            currentIconState = iconState;
            invalidateSelf();
        }
    }

    public void animateIconState(IconState state) {
        synchronized (lock) {
            if (transformationRunning) {
                transformation.end();
            }
            animatingIconState = state;
            start();
        }
    }

    public IconState setTransformationOffset(AnimationState animationState, float offset) {
        if (offset < TRANSFORMATION_START || offset > TRANSFORMATION_END) {
            throw new IllegalArgumentException(
                    String.format("Value must be between %s and %s", TRANSFORMATION_START, TRANSFORMATION_END)
            );
        }

        this.animationState = animationState;

        final boolean isFirstIcon = offset < TRANSFORMATION_MID || offset == TRANSFORMATION_END;

        currentIconState = isFirstIcon ? animationState.getFirstState() : animationState.getSecondState();
        animatingIconState = isFirstIcon ? animationState.getSecondState() : animationState.getFirstState();

        setTransformationValue(offset);

        return currentIconState;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
        invalidateSelf();
    }

    public void setRTLEnabled(boolean rtlEnabled) {
        this.rtlEnabled = rtlEnabled;
        invalidateSelf();
    }

    public IconState getIconState() {
        return currentIconState;
    }

    public boolean isDrawableVisible(){
        return visible;
    }

    /*
     * Animations
     */
    private final Property<MaterialMenuDrawable, Float> transformationProperty
            = new Property<MaterialMenuDrawable, Float>(Float.class, "transformation") {
        @Override
        public Float get(MaterialMenuDrawable object) {
            return object.getTransformationValue();
        }

        @Override
        public void set(MaterialMenuDrawable object, Float value) {
            object.setTransformationValue(value);
        }
    };

    public Float getTransformationValue() {
        return transformationValue;
    }

    public void setTransformationValue(Float value) {
        this.transformationValue = value;
        invalidateSelf();
    }

    private void initAnimations(int transformDuration) {
        transformation = ObjectAnimator.ofFloat(this, transformationProperty, 0);
        transformation.setInterpolator(new DecelerateInterpolator(3));
        transformation.setDuration(transformDuration);
        transformation.addListener(new AnimatorListenerAdapter() {
            @Override public void onAnimationEnd(Animator animation) {
                transformationRunning = false;
                setIconState(animatingIconState);
            }
        });
    }

    private boolean resolveTransformation() {
        boolean isCurrentBurger = currentIconState == IconState.BURGER;
        boolean isCurrentArrow = currentIconState == IconState.ARROW;
        boolean isCurrentX = currentIconState == IconState.X;
        boolean isCurrentCheck = currentIconState == IconState.CHECK;
        boolean isAnimatingBurger = animatingIconState == IconState.BURGER;
        boolean isAnimatingArrow = animatingIconState == IconState.ARROW;
        boolean isAnimatingX = animatingIconState == IconState.X;
        boolean isAnimatingCheck = animatingIconState == IconState.CHECK;

        if ((isCurrentBurger && isAnimatingArrow) || (isCurrentArrow && isAnimatingBurger)) {
            animationState = AnimationState.BURGER_ARROW;
            return isCurrentBurger;
        }

        if ((isCurrentArrow && isAnimatingX) || (isCurrentX && isAnimatingArrow)) {
            animationState = AnimationState.ARROW_X;
            return isCurrentArrow;
        }

        if ((isCurrentBurger && isAnimatingX) || (isCurrentX && isAnimatingBurger)) {
            animationState = AnimationState.BURGER_X;
            return isCurrentBurger;
        }

        if ((isCurrentArrow && isAnimatingCheck) || (isCurrentCheck && isAnimatingArrow)) {
            animationState = AnimationState.ARROW_CHECK;
            return isCurrentArrow;
        }

        if ((isCurrentBurger && isAnimatingCheck) || (isCurrentCheck && isAnimatingBurger)) {
            animationState = AnimationState.BURGER_CHECK;
            return isCurrentBurger;
        }

        if ((isCurrentX && isAnimatingCheck) || (isCurrentCheck && isAnimatingX)) {
            animationState = AnimationState.X_CHECK;
            return isCurrentX;
        }

        throw new IllegalStateException(
                String.format("Animating from %s to %s is not supported", currentIconState, animatingIconState)
        );
    }

    @Override public void start() {
        if (transformationRunning) return;

        if (animatingIconState != null && animatingIconState != currentIconState) {
            transformationRunning = true;

            final boolean direction = resolveTransformation();
            transformation.setFloatValues(
                    direction ? TRANSFORMATION_START : TRANSFORMATION_MID,
                    direction ? TRANSFORMATION_MID : TRANSFORMATION_END
            );
            transformation.start();
        }

        invalidateSelf();
    }

    @Override public void stop() {
        if (isRunning() && transformation.isRunning()) {
            transformation.end();
        } else {
            transformationRunning = false;
            invalidateSelf();
        }
    }

    @Override public boolean isRunning() {
        return transformationRunning;
    }

    @Override
    public int getIntrinsicWidth() {
        return width;
    }

    @Override
    public int getIntrinsicHeight() {
        return height;
    }


    @Override
    public ConstantState getConstantState() {
        materialMenuState.changingConfigurations = getChangingConfigurations();
        return materialMenuState;
    }

    @Override
    public Drawable mutate() {
        materialMenuState = new MaterialMenuState();
        return this;
    }

    private final class MaterialMenuState extends ConstantState {
        private int changingConfigurations;

        private MaterialMenuState() {
        }

        @Override
        public Drawable newDrawable() {
            MaterialMenuDrawable drawable = new MaterialMenuDrawable(
                    circlePaint.getColor(), stroke, transformation.getDuration(),
                    width, height, iconWidth, circleRadius, strokeWidth, dip1
            );
            drawable.setIconState(animatingIconState != null ? animatingIconState : currentIconState);
            drawable.setVisible(visible);
            drawable.setRTLEnabled(rtlEnabled);
            return drawable;
        }

        @Override
        public int getChangingConfigurations() {
            return changingConfigurations;
        }
    }

    static float dpToPx(Resources resources, float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
    }
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/MathHelper.java
================================================
package no.agens.depth.lib;

import java.util.Random;

public class MathHelper {
    public static final Random rand = new Random();
    public static float randomRange(float min, float max) {


        return rand.nextInt(((int) max - (int) min) + 1) + (int) min;
    }
}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/RectEvaluator.java
================================================
package no.agens.depth.lib;

import android.animation.TypeEvaluator;
import android.graphics.Rect;

public class RectEvaluator implements TypeEvaluator<Rect> {

    @Override
    public Rect evaluate(float fraction, Rect startValue, Rect endValue) {

        return new Rect(startValue.left + (int) ((endValue.left - startValue.left) * fraction),
                startValue.top + (int) ((endValue.top - startValue.top) * fraction),
                startValue.right + (int) ((endValue.right - startValue.right) * fraction),
                startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction));
    }

}


================================================
FILE: lib/src/main/java/no/agens/depth/lib/RectFEvaluator.java
================================================
package no.agens.depth.lib;

import android.animation.TypeEvaluator;
import android.graphics.RectF;

public class RectFEvaluator implements TypeEvaluator<RectF> {

    @Override
    public RectF evaluate(float fraction, RectF startValue, RectF endValue) {

        return new RectF(startValue.left + (int) ((endValue.left - startValue.left) * fraction),
                startValue.top + (int) ((endValue.top - startValue.top) * fraction),
                startValue.right + (int) ((endValue.right - startValue.right) * fraction),
                startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction));
    }

}


================================================
FILE: lib/src/main/
Download .txt
gitextract_4xerzip3/

├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── no/
│       │           └── agens/
│       │               └── depth/
│       │                   └── ApplicationTest.java
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── no/
│           │       └── agens/
│           │           └── depth/
│           │               ├── BearSceneView.java
│           │               ├── Foam.java
│           │               ├── MenuAnimation.java
│           │               ├── PlayGroundActivity.java
│           │               ├── RenderableBear.java
│           │               ├── RenderableTree.java
│           │               ├── RootActivity.java
│           │               ├── SeekBarProgressChangeListener.java
│           │               ├── Smoke.java
│           │               ├── TransitionHelper.java
│           │               ├── Water.java
│           │               ├── WaterFragment.java
│           │               ├── WaterSceneView.java
│           │               └── WindFragment.java
│           └── res/
│               ├── drawable/
│               │   ├── bear_bg_gradient.xml
│               │   ├── circle.xml
│               │   ├── fab_bg.xml
│               │   ├── menu_btn.xml
│               │   ├── menu_btn2.xml
│               │   ├── menu_btn3.xml
│               │   └── menu_btn4.xml
│               ├── layout/
│               │   ├── activity_root.xml
│               │   ├── fragment_playground.xml
│               │   ├── fragment_water.xml
│               │   ├── fragment_wind.xml
│               │   └── menu_item.xml
│               ├── menu/
│               │   └── menu_root.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-w820dp/
│                   └── dimens.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── lib/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── no/
│       │           └── agens/
│       │               └── depth/
│       │                   └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── no/
│       │   │       └── agens/
│       │   │           └── depth/
│       │   │               └── lib/
│       │   │                   ├── CircularSplashView.java
│       │   │                   ├── ColorAnimator.java
│       │   │                   ├── CustomShadow.java
│       │   │                   ├── DepthLayout.java
│       │   │                   ├── DepthRendrer.java
│       │   │                   ├── MaterialMenuDrawable.java
│       │   │                   ├── MathHelper.java
│       │   │                   ├── RectEvaluator.java
│       │   │                   ├── RectFEvaluator.java
│       │   │                   ├── RippleHelper.java
│       │   │                   ├── headers/
│       │   │                   │   ├── AuraDrawable.java
│       │   │                   │   ├── NoiseEffect.java
│       │   │                   │   ├── Particle.java
│       │   │                   │   ├── ParticleSystem.java
│       │   │                   │   ├── PathBitmapMesh.java
│       │   │                   │   └── Renderable.java
│       │   │                   └── tween/
│       │   │                       ├── FrameRateCounter.java
│       │   │                       ├── TRectFEvaluator.java
│       │   │                       └── interpolators/
│       │   │                           ├── BackIn.java
│       │   │                           ├── BackInOut.java
│       │   │                           ├── BackOut.java
│       │   │                           ├── CircIn.java
│       │   │                           ├── CircInOut.java
│       │   │                           ├── CircOut.java
│       │   │                           ├── ElasticIn.java
│       │   │                           ├── ElasticInOut.java
│       │   │                           ├── ElasticOut.java
│       │   │                           ├── ExpoIn.java
│       │   │                           ├── ExpoInOut.java
│       │   │                           ├── ExpoOut.java
│       │   │                           ├── QuadIn.java
│       │   │                           ├── QuadInOut.java
│       │   │                           ├── QuadOut.java
│       │   │                           ├── QuartIn.java
│       │   │                           ├── QuartInOut.java
│       │   │                           ├── QuartOut.java
│       │   │                           ├── QuintIn.java
│       │   │                           ├── QuintInOut.java
│       │   │                           ├── QuintOut.java
│       │   │                           ├── SineIn.java
│       │   │                           ├── SineInOut.java
│       │   │                           └── SineOut.java
│       │   └── res/
│       │       └── values/
│       │           ├── dept_view.xml
│       │           └── values.xml
│       └── test/
│           └── java/
│               └── no/
│                   └── agens/
│                       └── depth/
│                           └── ExampleUnitTest.java
└── settings.gradle
Download .txt
SYMBOL INDEX (452 symbols across 59 files)

FILE: app/src/androidTest/java/no/agens/depth/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: app/src/main/java/no/agens/depth/BearSceneView.java
  class BearSceneView (line 21) | public class BearSceneView extends View {
    method BearSceneView (line 27) | public BearSceneView(Context context) {
    method BearSceneView (line 40) | public BearSceneView(Context context, AttributeSet attrs) {
    method BearSceneView (line 44) | public BearSceneView(Context context, AttributeSet attrs, int defStyle...
    method onLayout (line 49) | @Override
    method init (line 57) | private void init() {
    method addGrunge (line 82) | private void addGrunge(Bitmap grunge) {
    method addFire (line 89) | private void addFire(Bitmap smoke, Bitmap stones, float x, float y) {
    method addWhiteBear (line 125) | private void addWhiteBear(float v, float v1, Bitmap bear3) {
    method addBear (line 130) | private void addBear(float v, float v1, Bitmap bear1, Bitmap bear2) {
    method addTree (line 137) | void addTree(Bitmap bitmap, float x, float y, float scale, float alpha) {
    method onDetachedFromWindow (line 143) | @Override
    method destroyResources (line 149) | private void destroyResources() {
    method onAttachedToWindow (line 155) | @Override
    method onDraw (line 162) | @Override
    method setPause (line 183) | public void setPause(boolean pause) {
    method setWind (line 201) | public void setWind(int wind) {
    method setFlamesHeight (line 209) | public void setFlamesHeight(int progress) {
    method getYCoordByPercent (line 217) | private float getYCoordByPercent(float percent) {

FILE: app/src/main/java/no/agens/depth/Foam.java
  class Foam (line 10) | public class Foam extends PathBitmapMesh {
    method update (line 13) | void update(float deltaTime) {
    method Foam (line 24) | public Foam(int horizontalSlices, int verticalSlices, Bitmap bitmap, f...
    method setupFoam (line 33) | private void setupFoam(int verts) {
    method calcWave (line 42) | void calcWave() {
    method matchVertsToPath (line 50) | public void matchVertsToPath(Path path, float extraOffset) {
    method setVerticalOffset (line 77) | public void setVerticalOffset(float verticalOffset) {

FILE: app/src/main/java/no/agens/depth/MenuAnimation.java
  type MenuAnimation (line 3) | public interface MenuAnimation {
    method animateTOMenu (line 4) | void animateTOMenu();
    method revertFromMenu (line 5) | void revertFromMenu();
    method exitFromMenu (line 6) | void exitFromMenu();

FILE: app/src/main/java/no/agens/depth/PlayGroundActivity.java
  class PlayGroundActivity (line 13) | public class PlayGroundActivity extends Activity {
    method onCreate (line 25) | @Override
    method setupMenuButton (line 36) | private void setupMenuButton() {
    method setupSeekBars (line 48) | private void setupSeekBars() {
    method makeAppFullscreen (line 57) | private void makeAppFullscreen() {
    method setupDepthSeekbar (line 64) | private void setupDepthSeekbar() {
    method setupRotationXSeekbar (line 76) | private SeekBar setupRotationXSeekbar() {
    method setupRotationYSeekbar (line 90) | private void setupRotationYSeekbar() {
    method setupRotationZSeekbar (line 102) | private void setupRotationZSeekbar() {
    method setupElevationSeekbar (line 115) | private void setupElevationSeekbar() {

FILE: app/src/main/java/no/agens/depth/RenderableBear.java
  class RenderableBear (line 8) | public class RenderableBear extends Renderable {
    method RenderableBear (line 15) | public RenderableBear(Bitmap[] bitmaps, float x, float y) {
    method draw (line 21) | @Override
    method update (line 29) | @Override
    method destroy (line 40) | public void destroy() {

FILE: app/src/main/java/no/agens/depth/RenderableTree.java
  class RenderableTree (line 15) | public class RenderableTree extends Renderable {
    method RenderableTree (line 29) | public RenderableTree(Bitmap bitmap, float x, float y, float alpha) {
    method setScale (line 38) | public void setScale(float scaleX, float scaleY) {
    method createVerts (line 43) | private void createVerts() {
    method setXY (line 61) | public void setXY(float[] array, int index, float x, float y) {
    method setXA (line 66) | public void setXA(float[] array, int index, float x) {
    method setYA (line 70) | public void setYA(float[] array, int index, float y) {
    method draw (line 74) | @Override
    method createPath (line 88) | private void createPath() {
    method matchVertsToPath (line 98) | private void matchVertsToPath() {
    method setOffsetPercent (line 119) | public void setOffsetPercent(float offset) {
    method isBounceAnimatin (line 125) | public boolean isBounceAnimatin() {
    method cancelBounce (line 129) | public void cancelBounce() {
    method update (line 133) | @Override

FILE: app/src/main/java/no/agens/depth/RootActivity.java
  class RootActivity (line 22) | public class RootActivity extends Activity {
    method onCreate (line 31) | @Override
    method setCurrentMenuIndex (line 44) | public void setCurrentMenuIndex(int currentMenuIndex) {
    method makeAppFullscreen (line 50) | private void makeAppFullscreen() {
    method onBackPressed (line 60) | @Override
    method showMenu (line 70) | public void showMenu() {
    method hideMenu (line 81) | public void hideMenu() {
    method setupMenu (line 90) | private void setupMenu() {
    method addMenuItem (line 102) | private void addMenuItem(ViewGroup menu, String text, int drawableReso...
    method getMenuItemCLick (line 123) | private View.OnClickListener getMenuItemCLick(final int menuIndex, fin...
    method showWindFragment (line 141) | private void showWindFragment(int menuIndex, int color) {
    method showWaterFragment (line 150) | private void showWaterFragment(int menuIndex, int color) {
    method selectMenuItem (line 159) | private void selectMenuItem(int menuIndex, int color) {
    method unSelect (line 170) | private void unSelect(View menuItem) {
    method fadeColorTo (line 181) | private void fadeColorTo(int newColor, TextView view) {
    method select (line 187) | private void select(View menuItem, int color) {
    method goToFragment (line 196) | public void goToFragment(final Fragment newFragment) {

FILE: app/src/main/java/no/agens/depth/SeekBarProgressChangeListener.java
  class SeekBarProgressChangeListener (line 5) | public abstract class SeekBarProgressChangeListener implements SeekBar.O...
    method onStartTrackingTouch (line 6) | @Override
    method onStopTrackingTouch (line 10) | @Override

FILE: app/src/main/java/no/agens/depth/Smoke.java
  class Smoke (line 14) | public class Smoke extends Renderable {
    method createVerts (line 26) | private void createVerts() {
    method setXY (line 44) | public void setXY(float[] array, int index, float x, float y) {
    method Smoke (line 49) | public Smoke(Bitmap bitmap, float x, float y, float height, float widt...
    method destroy (line 76) | public void destroy() {
    method pause (line 81) | @Override
    method resume (line 87) | @Override
    method draw (line 97) | @Override
    method setY (line 105) | public void setY(float y) {
    method update (line 110) | @Override
    method createPath (line 115) | private void createPath() {
    method matchVertsToPath (line 135) | private void matchVertsToPath(float wind) {

FILE: app/src/main/java/no/agens/depth/TransitionHelper.java
  class TransitionHelper (line 19) | public class TransitionHelper {
    method startIntroAnim (line 30) | public static void startIntroAnim(View root, AnimatorListenerAdapter i...
    method introAnimate (line 38) | static ObjectAnimator introAnimate(final DepthLayout target, final flo...
    method startExitAnim (line 96) | public static void startExitAnim(View root) {
    method hideStatusBar (line 105) | private static void hideStatusBar(View root) {
    method exitAnimate (line 112) | static ValueAnimator exitAnimate(final DepthLayout target, final float...
    method continueOutToRight (line 153) | private static void continueOutToRight(DepthLayout target, float moveY...
    method getDistanceToCenter (line 166) | public static float getDistanceToCenter(View target) {
    method getDistanceToCenterX (line 172) | public static float getDistanceToCenterX(View target) {
    method animateToMenuState (line 178) | public static void animateToMenuState(View root, AnimatorListenerAdapt...
    method makeAppFullscreen (line 191) | private static void makeAppFullscreen(View target) {
    method animateMenuOut (line 198) | public static void animateMenuOut(View root) {
    method startRevertFromMenu (line 206) | public static void startRevertFromMenu(View root, AnimatorListenerAdap...
    method revertFromMenu (line 219) | static ObjectAnimator revertFromMenu(final DepthLayout target, final f...
    method getShowStatusBarListener (line 264) | @NonNull

FILE: app/src/main/java/no/agens/depth/Water.java
  class Water (line 12) | public class Water extends Renderable {
    method Water (line 22) | public Water(Bitmap bitmap, Bitmap foam, float y, float height, float ...
    method pause (line 43) | @Override
    method resume (line 51) | @Override
    method destroy (line 59) | @Override
    method draw (line 68) | @Override
    method update (line 77) | @Override
    method createPath (line 98) | private void createPath() {
    method setWaveHeight (line 120) | public void setWaveHeight(float waveHeight) {

FILE: app/src/main/java/no/agens/depth/WaterFragment.java
  class WaterFragment (line 18) | public class WaterFragment extends Fragment implements MenuAnimation {
    method WaterFragment (line 23) | public WaterFragment() {
    method setIntroAnimate (line 26) | public void setIntroAnimate(boolean introAnimate) {
    method onCreateView (line 34) | @Override
    method setupSeekbars (line 48) | private void setupSeekbars() {
    method setupMenuButton (line 72) | private void setupMenuButton() {
    method introAnimate (line 87) | private void introAnimate() {
    method setupFab (line 105) | private void setupFab() {
    method onAnimationEnd (line 128) | @Override
    method hideShadow (line 136) | private void hideShadow() {
    method showShadow (line 141) | private void showShadow() {
    method animateTOMenu (line 147) | @Override
    method revertFromMenu (line 161) | @Override
    method exitFromMenu (line 168) | @Override

FILE: app/src/main/java/no/agens/depth/WaterSceneView.java
  class WaterSceneView (line 17) | public class WaterSceneView extends View {
    method WaterSceneView (line 25) | public WaterSceneView(Context context) {
    method WaterSceneView (line 30) | public WaterSceneView(Context context, AttributeSet attrs) {
    method WaterSceneView (line 34) | public WaterSceneView(Context context, AttributeSet attrs, int defStyl...
    method onLayout (line 39) | @Override
    method init (line 47) | private void init() {
    method onDetachedFromWindow (line 68) | @Override
    method destroyResources (line 74) | private void destroyResources() {
    method onAttachedToWindow (line 79) | @Override
    method onDraw (line 86) | @Override
    method setPause (line 99) | public void setPause(boolean pause) {
    method getYCoordByPercent (line 114) | private float getYCoordByPercent(float percent) {
    method getXCoordByPercent (line 118) | private float getXCoordByPercent(float percent) {
    method setWaveHeight (line 122) | public void setWaveHeight(float height) {
    method setNoiseIntensity (line 126) | public void setNoiseIntensity(float noiseAmount) {

FILE: app/src/main/java/no/agens/depth/WindFragment.java
  class WindFragment (line 23) | public class WindFragment extends Fragment implements MenuAnimation {
    method WindFragment (line 29) | public WindFragment() {
    method onCreateView (line 36) | @Override
    method setupSliders (line 50) | private void setupSliders() {
    method doIntroAnimation (line 79) | private void doIntroAnimation() {
    method setupFabButton (line 97) | private void setupFabButton() {
    method setupMenuButton (line 119) | private void setupMenuButton() {
    method setProgressBarColor (line 134) | public static void setProgressBarColor(SeekBar progressBar, int newCol...
    method setIntroAnimate (line 150) | public void setIntroAnimate(boolean introAnimate) {
    method animateTOMenu (line 154) | @Override
    method hideShadow (line 168) | private void hideShadow() {
    method revertFromMenu (line 173) | @Override
    method onAnimationEnd (line 181) | @Override
    method showShadow (line 189) | private void showShadow() {
    method exitFromMenu (line 195) | @Override

FILE: lib/src/androidTest/java/no/agens/depth/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: lib/src/main/java/no/agens/depth/lib/CircularSplashView.java
  class CircularSplashView (line 24) | public class CircularSplashView extends View {
    method CircularSplashView (line 28) | public CircularSplashView(Context context) {
    method CircularSplashView (line 32) | public CircularSplashView(Context context, AttributeSet attrs) {
    method CircularSplashView (line 36) | public CircularSplashView(Context context, AttributeSet attrs, int def...
    method setSplash (line 40) | public void setSplash(Bitmap splash) {
    method setSplashColor (line 44) | public void setSplashColor(int splashColor) {
    method onLayout (line 51) | @Override
    method introAnimate (line 59) | public void introAnimate() {
    method onDraw (line 71) | @Override
    type CircledDrawable (line 78) | interface CircledDrawable {
      method startAnim (line 79) | void startAnim();
      method draw (line 81) | void draw(Canvas canvas);
    class CircleBitmapExpand (line 84) | public class CircleBitmapExpand implements CircledDrawable {
      method CircleBitmapExpand (line 91) | public CircleBitmapExpand(Rect targetSize, long startDelay, long ani...
      method GetBitmapClippedCircle (line 99) | public Bitmap GetBitmapClippedCircle(Bitmap bitmap) {
      method startAnim (line 119) | public void startAnim() {
      method draw (line 136) | public void draw(Canvas canvas) {
    class CircleColorExpand (line 142) | public class CircleColorExpand implements CircledDrawable {
      method CircleColorExpand (line 149) | public CircleColorExpand(RectF targetSize, long startDelay, long ani...
      method startAnim (line 158) | public void startAnim() {
      method draw (line 174) | public void draw(Canvas canvas) {

FILE: lib/src/main/java/no/agens/depth/lib/ColorAnimator.java
  class ColorAnimator (line 10) | public class ColorAnimator {
    method ofColor (line 12) | public static ObjectAnimator ofColor(Object target, String propertyNam...
    method ofColor (line 16) | public static ObjectAnimator ofColor(Object target, String propertyNam...
    method ofBackgroundColor (line 20) | public static ObjectAnimator ofBackgroundColor(View target, int from, ...
    method ofBackgroundColor (line 24) | public static ObjectAnimator ofBackgroundColor(View target, int to) {
    class ColorEvaluator (line 28) | private static class ColorEvaluator implements TypeEvaluator<Integer> {
      method evaluate (line 30) | @Override
    class ViewBackgroundWrapper (line 44) | public static class ViewBackgroundWrapper {
      method ViewBackgroundWrapper (line 48) | public ViewBackgroundWrapper(View v) {
      method getBackgroundColor (line 52) | public int getBackgroundColor() {
      method setBackgroundColor (line 63) | public void setBackgroundColor(int color) {

FILE: lib/src/main/java/no/agens/depth/lib/CustomShadow.java
  class CustomShadow (line 19) | public class CustomShadow extends Drawable {
    method CustomShadow (line 71) | public CustomShadow(
    method toEven (line 100) | private int toEven(float value) {
    method setAddPaddingForCorners (line 108) | public void setAddPaddingForCorners(boolean addPaddingForCorners) {
    method setAlpha (line 113) | @Override
    method onBoundsChange (line 120) | @Override
    method setShadowSize (line 126) | void setShadowSize(float shadowSize, float maxShadowSize) {
    method getPadding (line 149) | @Override
    method calculateVerticalPadding (line 160) | static float calculateVerticalPadding(float maxShadowSize, float corne...
    method calculateHorizontalPadding (line 169) | static float calculateHorizontalPadding(float maxShadowSize, float cor...
    method setColorFilter (line 178) | @Override
    method getOpacity (line 185) | @Override
    method setCornerRadius (line 190) | void setCornerRadius(float radius) {
    method draw (line 200) | @Override
    method drawShadow (line 212) | private void drawShadow(Canvas canvas) {
    method buildShadowCorners (line 231) | private void buildShadowCorners() {
    method buildComponents (line 265) | private void buildComponents(Rect bounds) {
    method getCornerRadius (line 275) | float getCornerRadius() {
    method getMaxShadowAndCornerPadding (line 279) | void getMaxShadowAndCornerPadding(Rect into) {
    method setShadowSize (line 283) | void setShadowSize(float size) {
    method setMaxShadowSize (line 287) | void setMaxShadowSize(float size) {
    method getShadowSize (line 291) | float getShadowSize() {
    method getMaxShadowSize (line 295) | float getMaxShadowSize() {
    method getMinWidth (line 299) | float getMinWidth() {
    method getMinHeight (line 305) | float getMinHeight() {
    method setColor (line 311) | public void setColor(int color) {
    type RoundRectHelper (line 316) | interface RoundRectHelper {
      method drawRoundRect (line 317) | void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, ...

FILE: lib/src/main/java/no/agens/depth/lib/DepthLayout.java
  class DepthLayout (line 17) | public class DepthLayout extends RelativeLayout {
    method DepthLayout (line 24) | public DepthLayout(Context context) {
    method hasOverlappingRendering (line 30) | @Override
    method getEdgePaint (line 35) | public Paint getEdgePaint() {
    method setEdgePaint (line 40) | public void setEdgePaint(Paint edgePaint) {
    method initView (line 44) | private void initView(AttributeSet attrs) {
    method DepthLayout (line 72) | public DepthLayout(Context context, AttributeSet attrs) {
    method DepthLayout (line 78) | public DepthLayout(Context context, AttributeSet attrs, int defStyleAt...
    method getDepth (line 87) | public float getDepth() {
    method setDepth (line 91) | public void setDepth(float depth) {
    method isCircle (line 96) | public boolean isCircle() {
    method setIsCircle (line 100) | public void setIsCircle(boolean isCircle) {
    method calculateBounds (line 108) | public boolean calculateBounds() {
    method hasMatrixChanged (line 149) | boolean hasMatrixChanged(float[] newSrc) {
    method getTopLeft (line 157) | public PointF getTopLeft() {
    method getTopRight (line 161) | public PointF getTopRight() {
    method getBottomLeft (line 165) | public PointF getBottomLeft() {
    method getBottomRight (line 169) | public PointF getBottomRight() {
    method getTopLeftBack (line 173) | public PointF getTopLeftBack() {
    method getTopRightBack (line 177) | public PointF getTopRightBack() {
    method getBottomLeftBack (line 181) | public PointF getBottomLeftBack() {
    method getBottomRightBack (line 185) | public PointF getBottomRightBack() {
    method getCustomShadow (line 203) | public CustomShadow getCustomShadow() {
    method setCustomShadowElevation (line 207) | public void setCustomShadowElevation(float customShadowElevation) {
    method getCustomShadowElevation (line 212) | public float getCustomShadowElevation() {
    class CustomShadow (line 218) | class CustomShadow {
      method calculateBounds (line 227) | public void calculateBounds(DepthLayout target) {
      method drawShadow (line 252) | public void drawShadow(Canvas canvas, DepthLayout dl, Drawable shado...

FILE: lib/src/main/java/no/agens/depth/lib/DepthRendrer.java
  class DepthRendrer (line 17) | public class DepthRendrer extends RelativeLayout {
    method DepthRendrer (line 25) | public DepthRendrer(Context context) {
    method DepthRendrer (line 31) | public DepthRendrer(Context context, AttributeSet attrs) {
    method DepthRendrer (line 36) | public DepthRendrer(Context context, AttributeSet attrs, int defStyleA...
    method DepthRendrer (line 41) | public DepthRendrer(Context context, AttributeSet attrs, int defStyleA...
    method getTopEdgeLength (line 46) | public float getTopEdgeLength(DepthLayout dl) {
    method getDistance (line 50) | float getDistance(PointF p1, PointF p2) {
    method getShadowAlpha (line 54) | public float getShadowAlpha() {
    method setShadowAlpha (line 58) | public void setShadowAlpha(float shadowAlpha) {
    method setup (line 64) | void setup() {
    method drawChild (line 86) | @Override
    method drawCornerBaseShape (line 110) | private void drawCornerBaseShape(DepthLayout dl, Canvas canvas, float[...
    method drawHorizontalFist (line 126) | private void drawHorizontalFist(DepthLayout dl, Canvas canvas, float[]...
    method drawVerticalFirst (line 143) | private void drawVerticalFirst(DepthLayout dl, Canvas canvas, float[] ...
    method getLongestHorizontalEdge (line 163) | float getLongestHorizontalEdge(DepthLayout dl) {
    method getLongestVerticalEdge (line 173) | float getLongestVerticalEdge(DepthLayout dl) {
    method getRightEdgeLength (line 183) | private float getRightEdgeLength(DepthLayout dl) {
    method getLeftEdgeLength (line 187) | private float getLeftEdgeLength(DepthLayout dl) {
    method getBottomEdgeLength (line 192) | private float getBottomEdgeLength(DepthLayout dl) {
    method drawShadow (line 197) | void drawShadow(PointF point1, PointF point2, float correctionValue, C...
    method drawRectancle (line 206) | private void drawRectancle(DepthLayout dl, Canvas canvas) {
    method getAngle (line 210) | public float getAngle(PointF point1, PointF point2) {
    method drawLeftEdge (line 215) | private void drawLeftEdge(DepthLayout dl, Canvas canvas, float[] src) {
    method drawRightEdge (line 227) | private void drawRightEdge(DepthLayout dl, Canvas canvas, float[] src) {
    method drawTopEdge (line 239) | private void drawTopEdge(DepthLayout dl, Canvas canvas, float[] src) {
    method drawBottomEdge (line 250) | private void drawBottomEdge(DepthLayout dl, Canvas canvas, float[] src) {

FILE: lib/src/main/java/no/agens/depth/lib/MaterialMenuDrawable.java
  class MaterialMenuDrawable (line 21) | public class MaterialMenuDrawable extends Drawable implements Animatable {
    type IconState (line 23) | public enum IconState {
    type AnimationState (line 27) | public enum AnimationState {
      method getFirstState (line 30) | public IconState getFirstState() {
      method getSecondState (line 49) | public IconState getSecondState() {
    type Stroke (line 69) | public enum Stroke {
      method Stroke (line 85) | Stroke(int strokeWidth) {
      method valueOf (line 89) | protected static Stroke valueOf(int strokeWidth) {
    method MaterialMenuDrawable (line 165) | public MaterialMenuDrawable(Context context, int color, Stroke stroke) {
    method MaterialMenuDrawable (line 169) | public MaterialMenuDrawable(Context context, int color, Stroke stroke,...
    method MaterialMenuDrawable (line 173) | public MaterialMenuDrawable(Context context, int color, Stroke stroke,...
    method MaterialMenuDrawable (line 200) | private MaterialMenuDrawable(int color, Stroke stroke, long transformD...
    method initPaint (line 224) | private void initPaint(int color) {
    method draw (line 242) | @Override public void draw(Canvas canvas) {
    method drawMiddleLine (line 262) | private void drawMiddleLine(Canvas canvas, float ratio) {
    method drawTopLine (line 334) | private void drawTopLine(Canvas canvas, float ratio) {
    method drawBottomLine (line 429) | private void drawBottomLine(Canvas canvas, float ratio) {
    method isMorphingForward (line 536) | private boolean isMorphingForward() {
    method resolveStrokeModifier (line 540) | private float resolveStrokeModifier(float ratio) {
    method setAlpha (line 561) | @Override public void setAlpha(int alpha) {
    method setColorFilter (line 565) | @Override public void setColorFilter(ColorFilter cf) {
    method getOpacity (line 569) | @Override public int getOpacity() {
    method setColor (line 577) | public void setColor(int color) {
    method setTransformationDuration (line 583) | public void setTransformationDuration(int duration) {
    method setInterpolator (line 587) | public void setInterpolator(Interpolator interpolator) {
    method setAnimationListener (line 591) | public void setAnimationListener(Animator.AnimatorListener listener) {
    method setIconState (line 603) | public void setIconState(IconState iconState) {
    method animateIconState (line 634) | public void animateIconState(IconState state) {
    method setTransformationOffset (line 644) | public IconState setTransformationOffset(AnimationState animationState...
    method setVisible (line 663) | public void setVisible(boolean visible) {
    method setRTLEnabled (line 668) | public void setRTLEnabled(boolean rtlEnabled) {
    method getIconState (line 673) | public IconState getIconState() {
    method isDrawableVisible (line 677) | public boolean isDrawableVisible(){
    method get (line 686) | @Override
    method set (line 691) | @Override
    method getTransformationValue (line 697) | public Float getTransformationValue() {
    method setTransformationValue (line 701) | public void setTransformationValue(Float value) {
    method initAnimations (line 706) | private void initAnimations(int transformDuration) {
    method resolveTransformation (line 718) | private boolean resolveTransformation() {
    method start (line 763) | @Override public void start() {
    method stop (line 780) | @Override public void stop() {
    method isRunning (line 789) | @Override public boolean isRunning() {
    method getIntrinsicWidth (line 793) | @Override
    method getIntrinsicHeight (line 798) | @Override
    method getConstantState (line 804) | @Override
    method mutate (line 810) | @Override
    class MaterialMenuState (line 816) | private final class MaterialMenuState extends ConstantState {
      method MaterialMenuState (line 819) | private MaterialMenuState() {
      method newDrawable (line 822) | @Override
      method getChangingConfigurations (line 834) | @Override
    method dpToPx (line 840) | static float dpToPx(Resources resources, float dp) {

FILE: lib/src/main/java/no/agens/depth/lib/MathHelper.java
  class MathHelper (line 5) | public class MathHelper {
    method randomRange (line 7) | public static float randomRange(float min, float max) {

FILE: lib/src/main/java/no/agens/depth/lib/RectEvaluator.java
  class RectEvaluator (line 6) | public class RectEvaluator implements TypeEvaluator<Rect> {
    method evaluate (line 8) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/RectFEvaluator.java
  class RectFEvaluator (line 6) | public class RectFEvaluator implements TypeEvaluator<RectF> {
    method evaluate (line 8) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/RippleHelper.java
  class RippleHelper (line 7) | public class RippleHelper {
    method getPressedColorRippleDrawable (line 8) | public static RippleDrawable getPressedColorRippleDrawable(int normalC...
    method getPressedColorSelector (line 13) | public static ColorStateList getPressedColorSelector(int normalColor, ...
    method getColorDrawableFromColor (line 33) | public static ColorDrawable getColorDrawableFromColor(int color)

FILE: lib/src/main/java/no/agens/depth/lib/headers/AuraDrawable.java
  class AuraDrawable (line 9) | public class AuraDrawable extends Renderable {
    method AuraDrawable (line 13) | public AuraDrawable(Drawable drawable, Rect position) {
    method draw (line 20) | @Override
    method update (line 25) | public void update(float deltaTime, float wind) {

FILE: lib/src/main/java/no/agens/depth/lib/headers/NoiseEffect.java
  class NoiseEffect (line 14) | public class NoiseEffect extends Renderable {
    method NoiseEffect (line 21) | public NoiseEffect(Bitmap bitmap, int grainFPS, float scale) {
    method draw (line 35) | @Override
    method update (line 44) | @Override
    method setNoiseIntensity (line 75) | public void setNoiseIntensity(float noiseIntensity) {

FILE: lib/src/main/java/no/agens/depth/lib/headers/Particle.java
  class Particle (line 3) | public class Particle extends Renderable {
    method Particle (line 7) | public Particle(float x, float y,float randomSpeedX, float randomSpeed...
    method setRandomSpeed (line 15) | public void setRandomSpeed( float randomSpeedX, float randomSpeedY){

FILE: lib/src/main/java/no/agens/depth/lib/headers/ParticleSystem.java
  class ParticleSystem (line 14) | public class ParticleSystem extends Renderable {
    method setParticleSize (line 27) | public void setParticleSize(int particleSize) {
    method setRandomMovementX (line 33) | public void setRandomMovementX(float randomMovement) {
    method ParticleSystem (line 39) | public ParticleSystem(float x, float y, int emitInterWall, float gravi...
    method setColors (line 48) | public void setColors(int startColor, int endColor) {
    method draw (line 56) | @Override
    method update (line 66) | @Override
    method addParticle (line 90) | private void addParticle() {
    method setMinYCoord (line 97) | public void setMinYCoord(float minYCoord) {
    method setRandomMovementY (line 101) | public void setRandomMovementY(float randomMovementY) {
    method setParticlePaintColor (line 107) | public void setParticlePaintColor(Particle particle) {
    method setRandomMovementChangeInterval (line 115) | public void setRandomMovementChangeInterval(int randomMovementChangeIn...

FILE: lib/src/main/java/no/agens/depth/lib/headers/PathBitmapMesh.java
  class PathBitmapMesh (line 11) | public class PathBitmapMesh {
    method PathBitmapMesh (line 19) | public PathBitmapMesh(int horizontalSlices, int verticalSlices, Bitmap...
    method startWaveAnim (line 30) | private void startWaveAnim(Bitmap bitmap, float waves, int animDuratio...
    method destroy (line 47) | public void destroy() {
    method setAlpha (line 55) | public void setAlpha(int alpha) {
    method createVerts (line 59) | private void createVerts() {
    method setXY (line 80) | public void setXY(float[] array, int index, float x, float y) {
    method matchVertsToPath (line 85) | public void matchVertsToPath(Path path, float bottomCoord, float extra...
    method getBitmap (line 109) | public Bitmap getBitmap() {
    method draw (line 118) | public void draw(Canvas canvas) {
    method pause (line 122) | public void pause() {
    method resume (line 126) | public void resume() {

FILE: lib/src/main/java/no/agens/depth/lib/headers/Renderable.java
  class Renderable (line 10) | public class Renderable {
    method setY (line 13) | public void setY(float y) {
    method Renderable (line 26) | public Renderable(Bitmap bitmap, float x, float y) {
    method draw (line 32) | public void draw(Canvas canvas) {
    method drawStretched (line 38) | public void drawStretched(Canvas canvas, float parentWidth) {
    method setTranslationY (line 44) | public void setTranslationY(Float translationY) {
    method getTranslationY (line 48) | public float getTranslationY() {
    method setTranslationY (line 52) | public void setTranslationY(float translationY) {
    method getTranslationX (line 56) | public float getTranslationX() {
    method setTranslationX (line 60) | public void setTranslationX(float translationX) {
    method setScale (line 64) | public void setScale(float scale, float scale1) {
    method update (line 68) | public void update(float deltaTime, float wind) {
    method destroy (line 72) | public void destroy() {
    method pause (line 79) | public void pause() {
    method resume (line 83) | public void resume() {

FILE: lib/src/main/java/no/agens/depth/lib/tween/FrameRateCounter.java
  class FrameRateCounter (line 9) | public class FrameRateCounter {
    method timeStep (line 12) | public static float timeStep() {

FILE: lib/src/main/java/no/agens/depth/lib/tween/TRectFEvaluator.java
  class TRectFEvaluator (line 9) | public class TRectFEvaluator implements TypeEvaluator<RectF> {
    method evaluate (line 24) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackIn.java
  class BackIn (line 8) | public class BackIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override
    method amount (line 16) | public BackIn amount(float s) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackInOut.java
  class BackInOut (line 8) | public class BackInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override
    method amount (line 17) | public BackInOut amount(float s) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackOut.java
  class BackOut (line 8) | public class BackOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override
    method amount (line 16) | public BackOut amount(float s) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircIn.java
  class CircIn (line 8) | class CircIn implements TimeInterpolator {
    method getInterpolation (line 10) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircInOut.java
  class CircInOut (line 8) | public class CircInOut implements TimeInterpolator {
    method getInterpolation (line 10) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircOut.java
  class CircOut (line 8) | class CircOut implements TimeInterpolator {
    method getInterpolation (line 10) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticIn.java
  class ElasticIn (line 8) | public class ElasticIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override
    method a (line 24) | public ElasticIn a(float a) {
    method p (line 30) | public ElasticIn p(float p) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticInOut.java
  class ElasticInOut (line 8) | public class ElasticInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override
    method a (line 25) | public ElasticInOut a(float a) {
    method p (line 31) | public ElasticInOut p(float p) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticOut.java
  class ElasticOut (line 8) | public class ElasticOut implements TimeInterpolator {
    method getInterpolation (line 16) | @Override
    method a (line 27) | public ElasticOut a(float a) {
    method p (line 33) | public ElasticOut p(float p) {

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoIn.java
  class ExpoIn (line 8) | public class ExpoIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoInOut.java
  class ExpoInOut (line 8) | public class ExpoInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoOut.java
  class ExpoOut (line 8) | public class ExpoOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadIn.java
  class QuadIn (line 8) | public class QuadIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadInOut.java
  class QuadInOut (line 8) | public class QuadInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadOut.java
  class QuadOut (line 8) | public class QuadOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartIn.java
  class QuartIn (line 8) | public class QuartIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartInOut.java
  class QuartInOut (line 8) | public class QuartInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartOut.java
  class QuartOut (line 8) | public class QuartOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintIn.java
  class QuintIn (line 8) | public class QuintIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintInOut.java
  class QuintInOut (line 8) | public class QuintInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintOut.java
  class QuintOut (line 8) | public class QuintOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineIn.java
  class SineIn (line 8) | public class SineIn implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineInOut.java
  class SineInOut (line 8) | public class SineInOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineOut.java
  class SineOut (line 8) | public class SineOut implements TimeInterpolator {
    method getInterpolation (line 9) | @Override

FILE: lib/src/test/java/no/agens/depth/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test
Condensed preview — 98 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (235K chars).
[
  {
    "path": ".gitignore",
    "chars": 65,
    "preview": ".gradle\n/local.properties\n.DS_Store\n/build\n/captures\n.idea\n*.iml\n"
  },
  {
    "path": ".travis.yml",
    "chars": 459,
    "preview": "language: android\n\njdk:\n    - oraclejdk7\n\nandroid:\n  components:\n    - platform-tools\n    - tools\n    - build-tools-23.0"
  },
  {
    "path": "LICENSE",
    "chars": 1135,
    "preview": "Authors:\nDaniel Zeller <daniel@agens.no>\n\nThe MIT License (MIT)\nCopyright (c) 2016 Agens AS (http://agens.no/)\n\nPermissi"
  },
  {
    "path": "README.md",
    "chars": 1545,
    "preview": "# Depth-LIB-Android\n\nThis library adds depth/thickness to views. \n\n[<img src=\"https://cdn.dribbble.com/users/655449/scre"
  },
  {
    "path": "app/.gitignore",
    "chars": 14,
    "preview": "/build\napp.iml"
  },
  {
    "path": "app/build.gradle",
    "chars": 702,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        applicationId \"n"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 654,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/androidTest/java/no/agens/depth/ApplicationTest.java",
    "chars": 345,
    "preview": "package no.agens.depth;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http:"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 1054,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/no/agens/depth/BearSceneView.java",
    "chars": 8492,
    "preview": "package no.agens.depth;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapF"
  },
  {
    "path": "app/src/main/java/no/agens/depth/Foam.java",
    "chars": 2541,
    "preview": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Path;\nimport android.graphics.PathMeasu"
  },
  {
    "path": "app/src/main/java/no/agens/depth/MenuAnimation.java",
    "chars": 144,
    "preview": "package no.agens.depth;\n\npublic interface MenuAnimation {\n      void animateTOMenu();\n      void revertFromMenu();\n     "
  },
  {
    "path": "app/src/main/java/no/agens/depth/PlayGroundActivity.java",
    "chars": 5314,
    "preview": "package no.agens.depth;\n\nimport android.app.Activity;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport an"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RenderableBear.java",
    "chars": 1256,
    "preview": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\n\nimport no.agens.depth.lib.head"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RenderableTree.java",
    "chars": 4773,
    "preview": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RootActivity.java",
    "chars": 8742,
    "preview": "package no.agens.depth;\n\nimport android.animation.ArgbEvaluator;\nimport android.animation.ObjectAnimator;\nimport android"
  },
  {
    "path": "app/src/main/java/no/agens/depth/SeekBarProgressChangeListener.java",
    "chars": 307,
    "preview": "package no.agens.depth;\n\nimport android.widget.SeekBar;\n\npublic abstract class SeekBarProgressChangeListener implements "
  },
  {
    "path": "app/src/main/java/no/agens/depth/Smoke.java",
    "chars": 5747,
    "preview": "package no.agens.depth;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Bitmap;\nimport android.graphics"
  },
  {
    "path": "app/src/main/java/no/agens/depth/TransitionHelper.java",
    "chars": 14500,
    "preview": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport and"
  },
  {
    "path": "app/src/main/java/no/agens/depth/Water.java",
    "chars": 3458,
    "preview": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WaterFragment.java",
    "chars": 6400,
    "preview": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport and"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WaterSceneView.java",
    "chars": 3910,
    "preview": "package no.agens.depth;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapF"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WindFragment.java",
    "chars": 7651,
    "preview": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport and"
  },
  {
    "path": "app/src/main/res/drawable/bear_bg_gradient.xml",
    "chars": 268,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n"
  },
  {
    "path": "app/src/main/res/drawable/circle.xml",
    "chars": 279,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\" android:color="
  },
  {
    "path": "app/src/main/res/drawable/fab_bg.xml",
    "chars": 352,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:co"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn.xml",
    "chars": 207,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn2.xml",
    "chars": 207,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn3.xml",
    "chars": 207,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn4.xml",
    "chars": 207,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "app/src/main/res/layout/activity_root.xml",
    "chars": 713,
    "preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                android:layout_width=\"match_p"
  },
  {
    "path": "app/src/main/res/layout/fragment_playground.xml",
    "chars": 8963,
    "preview": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                            "
  },
  {
    "path": "app/src/main/res/layout/fragment_water.xml",
    "chars": 7600,
    "preview": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                            "
  },
  {
    "path": "app/src/main/res/layout/fragment_wind.xml",
    "chars": 7543,
    "preview": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                            "
  },
  {
    "path": "app/src/main/res/layout/menu_item.xml",
    "chars": 899,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "app/src/main/res/menu/menu_root.xml",
    "chars": 399,
    "preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-aut"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 891,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"light_grey\">#8C9CA4</color>\n    <color name=\"white\">"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "chars": 611,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 234,
    "preview": "<resources>\n    <string name=\"app_name\">Depth</string>\n\n    <string name=\"hello_world\">Hello world!</string>\n    <string"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 350,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "chars": 358,
    "preview": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as s"
  },
  {
    "path": "build.gradle",
    "chars": 618,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Tue Oct 16 12:59:36 CEST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER"
  },
  {
    "path": "gradle.properties",
    "chars": 855,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 5080,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "lib/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "lib/build.gradle",
    "chars": 3184,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'"
  },
  {
    "path": "lib/proguard-rules.pro",
    "chars": 664,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:"
  },
  {
    "path": "lib/src/androidTest/java/no/agens/depth/ApplicationTest.java",
    "chars": 345,
    "preview": "package no.agens.depth;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http:"
  },
  {
    "path": "lib/src/main/AndroidManifest.xml",
    "chars": 143,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"no.agens.depth.lib\">\n\n    <appli"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/CircularSplashView.java",
    "chars": 6043,
    "preview": "package no.agens.depth.lib;\n\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.grap"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/ColorAnimator.java",
    "chars": 2484,
    "preview": "\npackage no.agens.depth.lib;\n\nimport android.animation.ObjectAnimator;\nimport android.animation.TypeEvaluator;\nimport an"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/CustomShadow.java",
    "chars": 11081,
    "preview": "package no.agens.depth.lib;\n\nimport android.content.res.Resources;\nimport android.graphics.Canvas;\nimport android.graphi"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/DepthLayout.java",
    "chars": 8120,
    "preview": "package no.agens.depth.lib;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graph"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/DepthRendrer.java",
    "chars": 9693,
    "preview": "package no.agens.depth.lib;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Col"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/MaterialMenuDrawable.java",
    "chars": 29209,
    "preview": "package no.agens.depth.lib;\n        import android.animation.Animator;\n        import android.animation.AnimatorListener"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/MathHelper.java",
    "chars": 273,
    "preview": "package no.agens.depth.lib;\n\nimport java.util.Random;\n\npublic class MathHelper {\n    public static final Random rand = n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RectEvaluator.java",
    "chars": 627,
    "preview": "package no.agens.depth.lib;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.Rect;\n\npublic class RectEva"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RectFEvaluator.java",
    "chars": 634,
    "preview": "package no.agens.depth.lib;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.RectF;\n\npublic class RectFE"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RippleHelper.java",
    "chars": 1323,
    "preview": "package no.agens.depth.lib;\n\nimport android.content.res.ColorStateList;\nimport android.graphics.drawable.ColorDrawable;\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/AuraDrawable.java",
    "chars": 888,
    "preview": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\nimport android.graphi"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/NoiseEffect.java",
    "chars": 2856,
    "preview": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapShader;\nimport androi"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/Particle.java",
    "chars": 581,
    "preview": "package no.agens.depth.lib.headers;\n\npublic class Particle extends Renderable {\n\n    float randomSpeedX;\n    float rando"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/ParticleSystem.java",
    "chars": 4060,
    "preview": "package no.agens.depth.lib.headers;\n\nimport android.animation.ArgbEvaluator;\nimport android.animation.ValueAnimator;\nimp"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/PathBitmapMesh.java",
    "chars": 4200,
    "preview": "package no.agens.depth.lib.headers;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Bitmap;\nimport andr"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/Renderable.java",
    "chars": 1868,
    "preview": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.grap"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/FrameRateCounter.java",
    "chars": 488,
    "preview": "package no.agens.depth.lib.tween;\n\nimport android.os.SystemClock;\n\n/**\n * Created by danielzeller on 26.03.14.\n*/\n\npubli"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/TRectFEvaluator.java",
    "chars": 1341,
    "preview": "package no.agens.depth.lib.tween;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.RectF;\n\n/**\n * Create"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackIn.java",
    "chars": 441,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackInOut.java",
    "chars": 544,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackOut.java",
    "chars": 452,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircIn.java",
    "chars": 296,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircInOut.java",
    "chars": 393,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircOut.java",
    "chars": 311,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticIn.java",
    "chars": 946,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticInOut.java",
    "chars": 1089,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticOut.java",
    "chars": 947,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoIn.java",
    "chars": 320,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoInOut.java",
    "chars": 449,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoOut.java",
    "chars": 321,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadIn.java",
    "chars": 277,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadInOut.java",
    "chars": 343,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadOut.java",
    "chars": 283,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartIn.java",
    "chars": 282,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartInOut.java",
    "chars": 349,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartOut.java",
    "chars": 295,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintIn.java",
    "chars": 284,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintInOut.java",
    "chars": 351,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintOut.java",
    "chars": 294,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineIn.java",
    "chars": 312,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineInOut.java",
    "chars": 318,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineOut.java",
    "chars": 308,
    "preview": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzel"
  },
  {
    "path": "lib/src/main/res/values/dept_view.xml",
    "chars": 340,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <declare-styleable name=\"DepthView\">\n\n        <attr name=\"is_cir"
  },
  {
    "path": "lib/src/main/res/values/values.xml",
    "chars": 248,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"cardview_shadow_end_color\">#03000000</color>\n    <co"
  },
  {
    "path": "lib/src/test/java/no/agens/depth/ExampleUnitTest.java",
    "chars": 307,
    "preview": "package no.agens.depth;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch"
  },
  {
    "path": "settings.gradle",
    "chars": 23,
    "preview": "include ':app', ':lib'\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the danielzeller/Depth-LIB-Android- GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 98 files (214.8 KB), approximately 53.9k tokens, and a symbol index with 452 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!