jinatonic / confetti Goto Github PK
View Code? Open in Web Editor NEWAn Android particle system library for displaying confetti!
Home Page: https://medium.com/@jinatonic/its-parfetti-time-f40634472608
License: Apache License 2.0
An Android particle system library for displaying confetti!
Home Page: https://medium.com/@jinatonic/its-parfetti-time-f40634472608
License: Apache License 2.0
Hi there,
I read the source code and found that confettiView would be invalidated every millisecond in ValueAnimator.AnimatorUpdateListener。I used AndroidStudioProfileTool to check the cpu usage, about 6-7%。Then I changed frequency, redrawing view in every 30ms, then cpu usage would be 3-4%。And according to the Internet, Our eyes can accept this fraquence,no stumbling feeling.
Do you think it is a good idea? Looking forward to your reply @jinatonic
// ----------------------------
My change is:
// ConfettiManager.java
private void startNewAnimation() {
……
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
private long lastUpdateTime = -1;
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
final long elapsedTime = valueAnimator.getCurrentPlayTime();
if(lastUpdateTime < 0) {
lastUpdateTime = elapsedTime;
} else if(lastUpdateTime + 30 > elapsedTime) {
return;
}
lastUpdateTime = elapsedTime;
……
}
});
animator.start();
}
The class ConfettiManager.ConfettiAnimationListenerAdapter should be declared static so it can be created for ConfettiManager.setConfettiAnimationListener() API that only override cared callback.
Can we add multiple bitmap in BitmapConfetto .Basically i want to add mutiple image in ShimmeringActivity without changing color
@Override public Confetto generateConfetto(Random random) { return new BitmapConfetto(confettoBitmaps); }
Hey,
First, thanks for the library. I recently had to do a lot of particle systems on Android and found very little options out there and yours is one of the most flexible ones I found.
I'm trying to create a bunch of simple customizations for an app I'm working on and I'm noticing that it is a bit limited to customize things without having to write my one ConfettiManager. Maybe I'm just missing something so let me know if I am.
For example, I want to be able to customize the initial position and direction of each confetto.
While technically I can do that in the listener, I want to still follow the rules set in the ConfettiManager
about velocity for example. There are no getters for these though. Not in ConfettiManager
or in Confetto
as they are private
. Why not have getters for these values on the Confetto
?
Edit: I just realized you already did this one in your current last commit on master but it is just not in the latest tagged version I added via Gradle.
Another option was to subclass ConfettiManager
and override configureConfetto
but unfortunately it is also set to private
and not protected
so I would have to override a whole lot of functions and variables that I don't really need. Is there a specific reason that function was not set to be overridable? If not, can you please set it to protected
.
How to remove a Confetto after touch on it?
Hi,
How can I achieve to show confetti for 5 seconds and It should reach till the end of the screen within 5 sec timeframe.
I am using below code but this shows confetti on screen for 13 seconds (It takes 13 seconds to clear confetti screens from the screen)
getConfettiManager(context, container).setNumInitialCount(0)
.setEmissionDuration(4000)
.setEmissionRate(15)
.animate();
Am I doing anything wrong?
I appreciate your help.
As we know, the confetti direction is from middle to the edge of the container. Is there any function make it reversed, from edge of container to center of container?
As if you've bought something...
Maybe colors like on this:
https://cdn-images-1.medium.com/max/800/1*cipIsoMzYhdxGU_p8CdRzA.png
I am trying to have confetti on the top of an alert dialog.
What should be the container for that context?
The confetti does not show up if i have a alert dialog.
Hello, now I have a question, if I do a single picture click or single snowflake click event in the demo. You can't make the next step of operation such as animation
The raining confetti does exactly what I need except the individual squares are too small. I'm not seeing an option to set their scale (or a random scale ideally). Thanks for the cool lib!
Hello, Thank you for this wonderful library.
I'm having a little trouble understanding if I'm doing things the right way. I created my own custom confetto using ConfettoGenerator
and then initialized my ConfettiManager
like this:
confettoGenerator = new ConfettoGenerator() {
@Override
public Confetto generateConfetto(Random random) {
return new Particles(Assets.particle_blue);
}
};
confettiSource = new ConfettiSource(sW,sH/2);
mConfetti = new ConfettiManager(getContext(), confettoGenerator, confettiSource, (ViewGroup) this.getParent().getParent())
.setEmissionDuration(700)
.setVelocityX(-100)
.setTTL(700);
Now I'm able to draw my animation in my onDraw()
method by simply doing confettiManager.animate()
but what if I want to change the X and Y values during animation. For example, moving the animation as the user moves their finger on screen? Am I missing something since clearly I should not have to create a new confettiManager
each time I wanna move the same animation and I must avoid object allocation at all costs in my onDraw()
method.
Looking forward to your reply, thanks once again.
After falling to down my confetti returns to the top, because speed becomes negative
int height = container.getHeight();
int speed = height/4;
int acceleration = -(height/4)/8;
final ConfettiSource confettiSource = new ConfettiSource(-container.getWidth()/4, 0,container.getWidth()/2, 0);
confettiManager = new ConfettiManager(this, myConfettoGenerator, confettiSource, container)
.setNumInitialCount(2)
.setEmissionDuration(ConfettiManager.INFINITE_DURATION)
.setInitialRotation(180, 180)
.setEmissionRate(4f)
.setVelocityY(speed)
.setAccelerationY(acceleration)
.setRotationalVelocity(30, 60)
.animate();
I'm trying to use the common confetti inside an onAnimationEnd function. It doesn't work and the app gets frezzed.
how to stop the one shot rain, I can't call start activity when it is animating.
Hi, i am using the library to display some confetti like this:
CommonConfetti.explosion(container, centerX, centerY, getConfettiColor(context, score))
.stream(1000)
.setBound(new Rect(0, 0, container.getWidth(), container.getHeight()))
.setNumInitialCount(1)
.setEmissionRate(1)
.setEmissionDuration(1000)
.animate();
And i had some crashes after about a minute because of memory overflow. So i checked the Android Studio monitors and the memory was constantly raising and raising until it crashes.
Is there any tip or API to release memory that i have not seen in the wiki??
Thanks
Add a listener when confetti attached to view and is displayed. Also add a listener for case when confetti FadeOut from screen.
Can I use confetti to appear from the bottom and fly to the top? If this possible, how to configure it? do you have any sample how to do it with conffeti? Thank you :)
This library works great and I want to include it in an app for the play store.
I would like to give you credit for the library.
Could you update the project with a license?
I wonder if it is possible to display Confetti on the background, i.e. behind any Buttons or TextViews.
I've already tried to set the elevation for the other layout components as 3dp, but the confettos are still being displayed in front of Buttons and TextViews.
I think it would be great to have an option to set confetti elevation or something like that.
Oh, and thanks for the great lib!
Hi @jinatonic
I have used the rootview for setting the container for confetti as shown :
CommonConfetti.rainingConfetti(
(ViewGroup) dialog.getWindow().getDecorView().getRootView(),new int[]{
Color.WHITE,
ContextCompat.getColor(context, R.color.sky_blue),
Color.YELLOW,
Color.GREEN,
ContextCompat.getColor(context, R.color.red_pink),
ContextCompat.getColor(context, R.color.teal),
ContextCompat.getColor(context, R.color.teal_dark),
ContextCompat.getColor(context, R.color.dark_orange)})
.infinite();
)
I don't see confetti, nor i see an exception.
config:
new ConfettiManager(this, this, source, container) .setEmissionDuration(ConfettiManager.INFINITE_DURATION) .setTTL(CONFETTI_LIFE_DURATION_MS) .setVelocityX(0, velocitySlow) .setVelocityY(velocityNormal, velocitySlow) .setRotationalVelocity(ROTATIONAL_VELOCITY, ROTATIONAL_DEVIATION) .setEmissionRate(CONFETTI_PER_SECOND);
works on samsung/asus/etc. but shows nothing on honor 8x (android 9, JSN-L22) and huawei p20 pro (android 9, CLT-L29).
I've got similar issue with Huawei devices - there is not working rotation animation.
For this case I have to use such workaround:
DeviceHelper.isHuawei() ? ObjectAnimator.ofFloat(guestAvatarImage, View.ALPHA, 1, 0) : ObjectAnimator.ofFloat(guestAvatarImage, View.ROTATION_Y, 0, 90);
public static boolean isHuawei() { return "HUAWEI".equals(Build.MANUFACTURER.toUpperCase()); }
snippet:
( if (targetTime == null || targetTime < 0) {
// https://www.wolframalpha.com/input/
// ?i=solve+for+t+in+(d+%3D+x+%2B+v+*+t+%2B+0.5+*+a+*+t+*+t)
final double tmp = Math.sqrt(
2 * acceleration * bound - 2 * acceleration * initialPos
+ velocity * velocity);
final double firstTime = (-tmp - velocity) / acceleration;
if (firstTime > 0) {
return (long) firstTime;
}
final double secondTime = (tmp - velocity) / acceleration;
if (secondTime > 0) {
return (long) secondTime;
}
return Long.MAX_VALUE;
})
Hi,Confetti will Accelerate until reaching bound because it doest have targetTime.So tmp is the time of the reaching Bound.Why you have to calculate firstTime and secondTime to determine the reaching bound time?
In AbstractActivity the has used to terminate the ConfettiManager collection is throwing ConcurrentModificationException .
Bug Code:
for (ConfettiManager confettiManager : activeConfettiManagers) {
confettiManager.terminate();
}
I tried to change the way for terminating the collection in below code, but still its throwing the same exception.
Iterator<ConfettiManager> iter = allConfettiManagers.iterator();
while(iter.hasNext()) {
ConfettiManager blah = iter.next();
if(blah != null) {
blah.terminate(); // Removes the 'current' item
}
}
Full Stack Trace:
STACK_TRACE=java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
at com.openskylabs.skymo.uiscreens.ScrollerActivity.endConfitti(ScrollerActivity.java:689)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen.handleCardsonSwipe(OSLCardHomeScreen.java:860)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen.access$11(OSLCardHomeScreen.java:824)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen$8.onDislike(OSLCardHomeScreen.java:774)
at com.openskylabs.skymo.cardswipe.animation.CardContainer$GestureListener.onFling(CardContainer.java:472)
at android.view.GestureDetector.onTouchEvent(GestureDetector.java:600)
at com.openskylabs.skymo.cardswipe.animation.CardContainer.onTouchEvent(CardContainer.java:255)
at android.view.View.dispatchTouchEvent(View.java:7337)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2257)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1979)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1429)
at android.app.Activity.dispatchTouchEvent(Activity.java:2436)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1927)
at android.view.View.dispatchPointerEvent(View.java:7528)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3655)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3580)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4850)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4810)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4966)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:134)
at android.os.Looper.loop(Looper.java:151)
at android.app.ActivityThread.main(ActivityThread.java:5400)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
Not sure if it is an issue, but it looks like the copyright of this library is attributed to Robinhood. Maybe this was a copy paste sort of error? 😛
`int[] confettiColors = new int[]{R.color.red, R.color.blue, R.color.green, R.color.black, R.color.orange, R.color.darkergray};
ConfettiSource confettiSource = new ConfettiSource(linearLayout.getWidth(),
linearLayout.getHeight());
CommonConfetti.rainingConfetti(linearLayout, confettiSource, confettiColors ).infinite();`
i have done this code ....is that sufficient for showing confetti?
Hey
I am trying to use the library and have called the explosion() -
CommonConfetti.explosion(container, centerX, centerY, new int[] {Color.RED}).oneShot();
its not showing whereas the raining-effects are working fine. Could you please have a look at the issue or anything i am missing in the explosion()
Hi,
maybe you could implement setScaleX(int from, int to), setScaleY(int from, int to) in ConfettiManager? So for example, the bitmap would scale by the time elapsed.
At the moment I'm overriding Confetti class, accessing private "millisToReachBound" field with reflection and then preScaling matrix by calculating how much time have elapsed.
I was not able to integrate a confetti generatot with custom bitmap for Explosion Effect ?
Is there any specific method i should use for Explosion type to change the Confetti drawable ?
I created list of BitmapConfetto with 200 different , not the same images. And I need to fall all of the to bottom from the top. But when first confetti FadeOut at the bottom, then it recreates on the top again.
int height = container.getHeight();
int speed = height/4;
int acceleration = -(height/4)/8;
final ConfettiSource confettiSource = new ConfettiSource(-container.getWidth()/4, 0,container.getWidth()/2, 0);
confettiManager = new ConfettiManager(this, myConfettoGenerator, confettiSource, container)
.setNumInitialCount(2)
.setTTL(6000)
.enableFadeOut(Utils.getDefaultAlphaInterpolator())
.setEmissionDuration(ConfettiManager.INFINITE_DURATION)
.setInitialRotation(180, 180)
.setEmissionRate(4f)
.setVelocityY(speed)
.setAccelerationY(acceleration)
.setRotationalVelocity(30, 60)
.animate();
Hi there,
It would be extremely helpful if you could the the appropriate library proguard rules.
Title says it all, forcing me to use Studio 3.0
Had to look back in the commits and roll back to Gradle Build 2.3.3 to get it to work
'void android.view.ViewParent.requestLayout()' on a null object reference
In your sample app ShimmeringActivity added on more button stop and on click listener
getConfettiManager.terminate() crashing.
My use case will be I have to show infinite shower animation but on click on something dismiss the animation. Using terminate leads to crash copy pasting error log
java.lang.NullPointerException: Attempt to invoke interface method 'void android.view.ViewParent.requestLayout()' on a null object reference at com.github.jinatonic.confetti.ConfettiView.terminate(ConfettiView.java:86) at com.github.jinatonic.confetti.ConfettiManager.terminate(ConfettiManager.java:481) at com.github.jinatonic.confetti.ConfettiManager$2.onAnimationUpdate(ConfettiManager.java:534) at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1463) at android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1384) at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1427) at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:759) at android.animation.ValueAnimator$AnimationHandler$1.run(ValueAnimator.java:801) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:603) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:5497) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
You can use some of the Guava caches here to optimize your confetto recycling and limit the number of active confetti on-screen.
This should be completely configurable, since some devices are more powerful than others. The animator could keep track of the last frame-time and also dynamically adjust the value.
Hey! I am using a custom drawable, 2 different drawables in this case.
One that works is 128x128 which shows up just fine.
The other one being 10x120 which doesnt show, instead it picks one drawable from the library, that looks like a rounded square.
Any clue why I am seeing this?
Anyway to add Flip rotation animation instead of Clockwise or Counter Clockwise rotation animation while the confetti is falling down?
Any feedback on this feature would be greatly appreciated.
Hei guys, can you explain me if I could use it with a DialogFragment.
I have tried but I am unable to display the confettis. I think it is because of the container I have to pass to the ConfetiiManager, because the widht/height I receive from it is 0.
Thank you!
Hi,
I really like this library and was wondering if the 1.1.1 release was going to happen soon as I could really do with the animation listener.
Thanks
Hey,
I fixed the crash on the terminate method:
/**
* Terminate the currently running animation if there is any.
*/
public void terminate() {
if (animator != null) {
animator.cancel();
}
if (confettiView != null && confettiView.getParent() != null)
confettiView.terminate();
if (animationListener != null) {
animationListener.onAnimationEnd(this);
}
}
The problem is when you initialize an ConfettiManager with confettiView null the terminate method will crash. This is easily avoidable by adding this extra check. I've tried making an PR for it but i can't seem to push on a separate branch getting error 403.
Btw this crash happens in Kotlin because you van initialize the ConfettiManager as Confettimanager(ConfettoGenerator,ConfettiSource,null,null) if you want.
Can i somehow collect all dropped images at the bottom of the screen, something like tetris?
These are not calculated because you already use twice-integrated equations of motion based on the current time, acceleration, and initial conditions, but they could be similar fields to currentX
and currentY
. I'd be happy to submit a PR implementing the feature!
As a side note, the comments in the computeDistance
function talk about linear acceleration, when you are clearly dealing with constant acceleration. It would be possible to implement linear acceleration, but I don't see any use cases for it.
As a side note to the side note, If you were to go down that path, you could use generalized mathematical functions from Apache Math to take derivatives, etc.
Hello,
I am trying to stop the confetti on a button click. Which method do i use for that?
I am using it by trying the following code:
private CommonConfetti getCommonConfetti() {
final int size = getResources().getDimensionPixelSize(R.dimen.default_confetti_size);
final ConfettiSource confettiSource = new ConfettiSource(-size, -size);
final Resources res = getResources();
int goldDark = res.getColor(R.color.zotocolor);
int goldMed = res.getColor(R.color.zotocolortrans);
int gold = res.getColor(R.color.offer_blue);
int goldLight = res.getColor(R.color.offer_validated_green);
int[] colors = new int[]{goldDark, goldMed, gold, goldLight};
final CommonConfetti commonConfetti =
CommonConfetti.rainingConfetti(parentContainer, confettiSource, colors);
final int velocitySlow = res.getDimensionPixelOffset(R.dimen.default_velocity_slow);
final int velocityNormal = res.getDimensionPixelOffset(R.dimen.default_velocity_normal);
final int velocityFast = res.getDimensionPixelOffset(R.dimen.default_velocity_fast);
// Further configure it
commonConfetti.getConfettiManager()
.setVelocityX(velocityFast, velocityNormal)
.setAccelerationX(-velocityNormal, velocitySlow)
.setTargetVelocityX(0, velocitySlow / 2)
.setVelocityY(velocityNormal, velocitySlow);
return commonConfetti;
}
And calling the confetti like this:
getCommonConfetti().infinite().animate();
And parentContainer is a FrameLayout(parent) in my xml.
But code executes without any confetti on my screen. Why so ? Am I doing something wrong ?
Steps:
Actual:
Confetti displayed below dialog since it's attached to decor view
Expected:
It should be customisable if effect should be above or below dialog
Hi,
I'm extending Confetto class to make my custom animation. This is all what I have:
@Override
protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y,
float rotation, float percentAnimated) {
float scaleX = ((rotation % 720) - 180) / 180.0f;
if (scaleX > 1f) {
scaleX = 1f - (scaleX - 1f);
}
float centerXDiff = (getWidth() * scaleX) / 2;
if (scaleX < 0f) {
matrix.preTranslate(x + Math.abs(centerXDiff), y);
} else {
matrix.preTranslate(x - Math.abs(centerXDiff), y);
}
matrix.preRotate(rotation, 0, bitmapCenterY);
matrix.preScale(scaleX, 1f);
canvas.drawBitmap(bitmap, matrix, paint);
}
I cannot reproduce by myself, but I have a bunch of users having a fatal exception when last line "canvas.drawBitmap" gets called. What could be the problem? I checked your source code and couldn't find a place where you call bitmap.recycle().
This is the stacktrace:
Fatal Exception: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1bafec58
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1225)
at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:589)
at MyCustomConfetto.drawInternal(MyCustomConfetto.java:57)
at com.github.jinatonic.confetti.confetto.Confetto.getWidth(Confetto.java:342)
at com.github.jinatonic.confetti.confetto.Confetto.getWidth(Confetto.java:332)
at com.github.jinatonic.confetti.ConfettiView.onDraw(ConfettiView.java:132)
A .shape(intArrayOf())
should be added in CommonConfetti
so it is easier to add shapes in one single line.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.