diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5edb4ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*.iml +.gradle +/local.properties +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..206b933 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..99202cc --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..99f7877 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 27 + defaultConfig { + applicationId "bg.devlabs.twinklelibrary" + minSdkVersion 19 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.2' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation project(path: ':twinkle') +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f260dfa --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/bg/devlabs/twinklelibrary/TwinkleActivity.kt b/app/src/main/java/bg/devlabs/twinklelibrary/TwinkleActivity.kt new file mode 100644 index 0000000..de150d8 --- /dev/null +++ b/app/src/main/java/bg/devlabs/twinklelibrary/TwinkleActivity.kt @@ -0,0 +1,35 @@ +package bg.devlabs.twinklelibrary + +import android.support.v7.app.AppCompatActivity +import android.os.Bundle +import android.os.Handler +import android.util.Log +import bg.devlabs.twinkle.Twinkle +import bg.devlabs.twinkle.twinkle +import kotlinx.android.synthetic.main.activity_twinkle.* + +class TwinkleActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_twinkle) + + val t: Twinkle = twinkle_text.twinkle() + delay(1000) { + t.stop() + } + } + + + + private fun delay(delay: Long, func: () -> Unit) { + val handler = Handler() + handler.postDelayed({ + try { + func() + } catch (e: Exception) { + Log.d("Twinkle error", e.localizedMessage) + } + }, delay) + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c3903ed --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..5713f34 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_twinkle.xml b/app/src/main/res/layout/activity_twinkle.xml new file mode 100644 index 0000000..93ffa84 --- /dev/null +++ b/app/src/main/res/layout/activity_twinkle.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..bbd3e02 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..bbd3e02 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..a2f5908 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..1b52399 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..ff10afd Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..115a4c7 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..dcd3cd8 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..459ca60 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..8ca12fe Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..8e19b41 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..b824ebd Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..4c19a13 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..61cc9a4 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + twinklelibrary + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..6b25030 --- /dev/null +++ b/build.gradle @@ -0,0 +1,32 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + ext.kotlin_version = '1.2.51' + ext.dokka_version = '0.9.15' + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' + classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..743d692 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,13 @@ +# 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. +org.gradle.jvmargs=-Xmx1536m +# 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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7a3265e Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..428eeeb --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jul 20 14:54:08 EEST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..47e590f --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app', ':twinkle' diff --git a/twinkle/.gitignore b/twinkle/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/twinkle/.gitignore @@ -0,0 +1 @@ +/build diff --git a/twinkle/build.gradle b/twinkle/build.gradle new file mode 100644 index 0000000..8d54c7b --- /dev/null +++ b/twinkle/build.gradle @@ -0,0 +1,48 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'com.jfrog.bintray' +apply plugin: 'org.jetbrains.dokka-android' +apply plugin: 'maven-publish' + +android { + compileSdkVersion 27 + + + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + +} + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'com.android.support:appcompat-v7:27.1.1' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() +} +apply from: 'deploy.gradle' \ No newline at end of file diff --git a/twinkle/deploy.gradle b/twinkle/deploy.gradle new file mode 100644 index 0000000..07874df --- /dev/null +++ b/twinkle/deploy.gradle @@ -0,0 +1,79 @@ +apply plugin: 'com.github.dcendents.android-maven' +apply plugin: 'com.jfrog.bintray' +apply from: 'keystore.gradle'//the file, containing the bintray API key +ext { + // This configuration will result in: + // compile '::' + groupId = 'bg.devlabs.twinkle' // package name of the project + artifactId = "twinkle" // module name of the library + libVersion = "1.0" +} +version = libVersion +group = groupId +//take a look at https://github.com/bintray/gradle-bintray-plugin#buildgradle +bintray { + user = 'radoslav' // Your bintray User + key = bintray_key // Defined in keystore.gradle file + configurations = ['archives'] + publish = true //[Default: false] Whether version should be auto published after an upload + override = false //[Default: false] Whether to override version artifacts already published + // Package configuration. The plugin will use the repo and name properties to check if the + // package already exists. In that case, there's no need to configure the other package + // properties (like userOrg, desc, etc). + pkg { + repo = "maven" //bintray repo + name = "twinkle" //bintray package + version { + name = libVersion + } + } +} +install { + repositories.mavenInstaller { + pom.project { + packaging 'aar' + groupId groupId + artifactId artifactId + version libVersion + name artifactId // pom.project.name must be same as bintray.pkg.name + } + } +} + +//just copy paste the lines below +if (project.hasProperty("kotlin")) { //Kotlin libraries + task sourcesJar(type: Jar) { + classifier = 'sources' + from android.sourceSets.main.java.srcDirs + } + + task javadoc(type: Javadoc, dependsOn: dokka) { + + } +} else if (project.hasProperty("android")) { + 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)) + } +} else { // Java libraries + task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource + } +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir + // options.encoding = 'UTF-8' +} + +artifacts { + archives javadocJar + archives sourcesJar +} \ No newline at end of file diff --git a/twinkle/keystore.gradle b/twinkle/keystore.gradle new file mode 100644 index 0000000..dab7831 --- /dev/null +++ b/twinkle/keystore.gradle @@ -0,0 +1,3 @@ +ext{ + bintray_key = '-' +} \ No newline at end of file diff --git a/twinkle/proguard-rules.pro b/twinkle/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/twinkle/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/twinkle/src/main/AndroidManifest.xml b/twinkle/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b692265 --- /dev/null +++ b/twinkle/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/twinkle/src/main/java/bg/devlabs/twinkle/Twinkle.kt b/twinkle/src/main/java/bg/devlabs/twinkle/Twinkle.kt new file mode 100644 index 0000000..be13f87 --- /dev/null +++ b/twinkle/src/main/java/bg/devlabs/twinkle/Twinkle.kt @@ -0,0 +1,124 @@ +package bg.devlabs.twinkle + +import android.app.Activity +import android.os.Handler +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import java.util.* + +/** + * Created by Radoslav Yankov on 20.07.2018 + * Dev Labs + * radoslavyankov@gmail.com + */ + +/** + * @param drawableRes The drawable resource for the twinkle effect. Star by default + * @param duration The duration of each particle animation. 600ms by default + * @param sparsity The period between particle generation. Larger number -> less particles. + * @param size The size of each particle in pixels. 80 pixels by default + */ +fun View.twinkle(drawableRes: Int = R.drawable.twinkle, duration: Int = 600, sparsity: Int = 120, size: Int = 80): Twinkle { + return Twinkle(this, drawableRes, duration, sparsity, size) +} + +/** + * Main Twinkle class + */ +class Twinkle(var view: View, var drawableRes: Int, var duration: Int, private var sparsity: Int, var size: Int) { + private var isRunning = true + + init { + start() + } + + fun start() { + isRunning = true + val rInt = Random() + loop(rInt.nextInt(sparsity * 2) + (sparsity / 2L)) { + //creating the ImageView. Not the most optimal way of showing graphics, but it's easy + var image: ImageView? = ImageView(view.context) + image?.apply { + layoutParams = ViewGroup.LayoutParams(size, size) + setBackgroundResource(drawableRes) + try { + x = (rInt.nextInt((view.width / 1.1).toInt()) + view.x + view.width * 0.1f) - (layoutParams.width / 2) + y = (rInt.nextInt((view.height / 1.1).toInt()) + view.y + view.height * 0.1f) - (layoutParams.height / 2) + } catch (e: Exception) { + return@apply + } + (view.context as? Activity)?.window?.decorView?.findViewById(android.R.id.content)?.addView(this) + alpha = 0f + scaleX = 0.7f + scaleY = 0.7f + animate().alpha(0.5f).duration = duration / 3L + animate().scaleX(1f).duration = duration / 3L + animate().scaleY(1f).duration = duration / 3L + loop(150) { + // alpha = 0.5f + animate().alpha(0.5f).duration = 70 + delay(80) { + animate().alpha(0.4f).duration = 30 +// alpha = 0.4f + } + } + //animation + delay(duration / 3L) { + animate().rotation(-10f).duration = duration / 6L + delay(duration / 6L) { + animate().rotation(10f).duration = duration / 6L * 2 + delay(duration / 6L * 2) { + animate().rotation(0f).duration = duration / 6L + } + } + delay(duration / 3L) { + animate().alpha(0f).duration = duration / 3L + animate().scaleX(0.7f).duration = duration / 3L + animate().scaleY(0.7f).duration = duration / 3L + } + } + } + delay(duration.toLong()) { + (view.context as? Activity)?.window?.decorView?.findViewById(android.R.id.content)?.removeView(image) + image = null + } + } + } + + + fun stop(){ + isRunning = false + } + + private fun loop(delay: Long, f: () -> Unit) { + f() + var handler: Handler? = Handler() + val runnable = object : Runnable { + override fun run() { + if (!isRunning){ + handler = null + return + } + try { + f() + } catch (e: Exception) { + Log.d("Twinkle error", e.localizedMessage) + }; handler?.postDelayed(this, delay) + } + }; handler?.postDelayed(runnable, delay) + } + + private fun delay(delay: Long, func: () -> Unit) { + val handler = Handler() + handler.postDelayed({ + try { + func() + } catch (e: Exception) { + Log.d("Twinkle error", e.localizedMessage) + } + }, delay) + } + +} \ No newline at end of file diff --git a/twinkle/src/main/res/drawable/twinkle.png b/twinkle/src/main/res/drawable/twinkle.png new file mode 100644 index 0000000..883157c Binary files /dev/null and b/twinkle/src/main/res/drawable/twinkle.png differ diff --git a/twinkle/src/main/res/values/strings.xml b/twinkle/src/main/res/values/strings.xml new file mode 100644 index 0000000..d1d4c5d --- /dev/null +++ b/twinkle/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + twinkle +