crashinvaders / gdx-vfx Goto Github PK
View Code? Open in Web Editor NEWlibGDX post-processing visual effects
Home Page: https://crashinvaders.github.io/gdx-vfx
License: Apache License 2.0
libGDX post-processing visual effects
Home Page: https://crashinvaders.github.io/gdx-vfx
License: Apache License 2.0
I successfully got the basic ShapeRenderer example to work but how can you combine it with a SpriteBatch that is also drawing stuff?
My issue is that everything i draw before using VfxManager's "renderToScreen()" is not showing at all. The screen is just black.
public void render(float dt){
// this does NOT show on screen
batch.setProjectionMatrix(...);
batch.begin()
batch.draw(...)
batch.end()
// this shows on screen
vfxManager.beginInputCapture();
sr.setProjectionMatrix(batch.getProjectionMatrix());
sr.begin(ShapeRenderer.ShapeType.Line);
sr.setColor(Color.WHITE);
sr.circle(10, 5, 3, 32);
sr.end();
vfxManager.endInputCapture();
vfxManager.applyEffects();
vfxManager.renderToScreen();
// this shows on screen
batch.setProjectionMatrix(...);
batch.begin()
batch.draw(...)
batch.end()
}
Any tip would be very much appreciated. Apologies if i'm missing something fundamental here ๐
I'm having an issue where applying the bloom effect drops the fps from 60 to 30 on Android, I know that applying bloom is a pretty expensive operation, but I was wondering if there was a solution to this, here's my code:
vfxManager.cleanUpBuffers(Color(0.3f, 0.3f,0.8f, 1f))
vfxManager.beginInputCapture()
SharedObjects.batch.use {
for (entity in SharedObjects.entities){
if(entity is Player) {
entity.render()
}
else {
entity.render()
}
}
for(effect in SharedObjects.effects){
effect.draw(SharedObjects.batch, delta)
if (effect.isComplete){
SharedObjects.effects.removeValue(effect, true)
effect.free()
}
}
}
vfxManager.endInputCapture()
vfxManager.applyEffects()
vfxManager.renderToScreen()
Thank you in advance
Hello @metaphore ! Great job building this library, really appreciate your time and can't wait for future updates.
I was able to run it on the desktop project smoothly, however, when I try to build the android project, I face the following error:
Caused by: java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK shaders/threshold.frag
File1: /Users/user/.m2/repository/com/crashinvaders/vfx/effects/0.1/effects-0.1.jar
File2: /Users/user/.m2/repository/com/crashinvaders/vfx/effects/0.1/effects-0.1.jar
I've tried installing with both ways mentioned on the README.md (Local JAR artifacts / Local maven archetype), but I keep getting the exact same error (only when building android project).
I had a quick look into how the demo project is setup, but it seems to be relying on the local files in this repository, which is different from a real setup scenario where I only use a local jar.
Please let me know if there is any extra steps I need to do in order to compile the library on android.
Also, if you cannot replicate this issue, please let me know, as it will confirm that this is a local setup issue from my end.
My build.gradle
// Main project
project(":core") {
apply plugin: "java"
dependencies {
compile "com.crashinvaders.vfx:core:0.1" // from mavenLocal()
compile "com.crashinvaders.vfx:effects:0.1" // from mavenLocal()
...
}
}
// Works fine
project(":desktop") {
apply plugin: "java"
dependencies {
compile project(":core")
...
}
}
// Fails
project(":android") {
apply plugin: "java"
dependencies {
compile project(":core")
...
}
}
Full stack trace:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':android:transformResourcesWithMergeJavaResForRelease'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:196)
at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:193)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:193)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:50)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK shaders/threshold.frag
File1: /Users/user/.m2/repository/com/crashinvaders/vfx/effects/0.1/effects-0.1.jar
File2: /Users/user/.m2/repository/com/crashinvaders/vfx/effects/0.1/effects-0.1.jar
Hi, I am getting the following crash on iOS.
com.badlogic.gdx.utils.GdxRuntimeException: File not found: gdxvfx/shaders/screenspace.vert (Classpath)
at com.badlogic.gdx.files.FileHandle.read(FileHandle.java:142)
at com.badlogic.gdx.files.FileHandle.length(FileHandle.java:638)
at com.badlogic.gdx.files.FileHandle.estimateLength(FileHandle.java:239)
at com.badlogic.gdx.files.FileHandle.readString(FileHandle.java:204)
at com.badlogic.gdx.files.FileHandle.readString(FileHandle.java:197)
at com.crashinvaders.vfx.gl.VfxGLUtils.compileShader(VfxGLUtils.java:103)
at com.crashinvaders.vfx.gl.VfxGLUtils.compileShader(VfxGLUtils.java:79)
at com.crashinvaders.vfx.effects.LensFlareEffect.<init>(LensFlareEffect.java:61)
The project works fine on desktop and Android.
I was just updating gdx-vfx from 0.5.1 to 0.5.2 and suddenly the IDE couldn't find any of the imports for the various classes of the library, but Gradle kept saying the dependency had been downloaded just fine. So I went to Sonatype (https://central.sonatype.com/artifact/com.crashinvaders.vfx/gdx-vfx-core/versions) and downloaded the jars for both 0.5.1 and 0.5.2 to see what they had inside, and to my surprise gdx-vfx-core-0.5.2.jar is empty! It has only 261 bytes (as opposed to 49.5 KB from gdx-vfx-core-0.5.1.jar), and just a META-INF folder inside the jar.
I see there were some commits related to gradle publishing, so my guess is that something went wrong in the process.
Hi, there is an effect in your demo called Noise, but doesn't seem to be available in the source. Does it come under a different name?
After including this library into our project, our build process fails with the following error:
Execution failed for task ':wear:mergeExtDexStandaloneDebug'.
> Could not resolve all files for configuration ':wear:standaloneDebugRuntimeClasspath'.
> Failed to transform gdx-vfx-effects-0.5.1.jar (com.crashinvaders.vfx:gdx-vfx-effects:0.5.1) to match attributes {artifactType=android-dex, asm-transformed-variant=standaloneDebug, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=24, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
> Execution failed for AsmClassesTransform: /Users/arielvardi/.gradle/caches/transforms-3/43c8bf1c6fd0f5c049278f813773d04e/transformed/jetified-gdx-vfx-effects-0.5.1.jar.
> duplicate entry: gdxvfx/shaders/old-tv.frag
The library was included with the following:
implementation 'com.crashinvaders.vfx:gdx-vfx-core:0.5.1'
implementation 'com.crashinvaders.vfx:gdx-vfx-effects:0.5.1' // Optional, if you need standard filter/effects.
Note that if the -effects
one is not included, the project builds okay... but obviously is missing all the effects we'd want to use.
java.lang.IllegalStateException: An attempted fetch uniform from uncompiled shader
Vertex shader
ERROR: 0:9: 'attribute' : syntax error: syntax error
Fragment shader:
ERROR: 0:9: 'varying' : syntax error: syntax error
at com.badlogic.gdx.graphics.glutils.ShaderProgram.fetchUniformLocation(ShaderProgram.java:304)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.fetchUniformLocation(ShaderProgram.java:293)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.setUniformi(ShaderProgram.java:318)
at com.crashinvaders.vfx.framebuffer.VfxFrameBufferRenderer.rebind(VfxFrameBufferRenderer.java:77)
at com.crashinvaders.vfx.framebuffer.VfxFrameBufferRenderer.<init>(VfxFrameBufferRenderer.java:66)
at com.crashinvaders.vfx.VfxRenderContext.<init>(VfxRenderContext.java:37)
at com.crashinvaders.vfx.VfxManager.<init>(VfxManager.java:64)
at com.crashinvaders.vfx.VfxManager.<init>(VfxManager.java:57)
macos implementation is not backward compatible.
I will update this ticket when I get it working.
As I am currently not working with fbos, because they do not support sampling, I am removing vfx for now from my project.
A screen shake effect would be a welcome addition. This is a commonly used effect when there are explosions on screen or if a character falls onto the ground very hard. Please see an example here: https://www.shadertoy.com/view/wsBXWW
I would love to write a PR, but unfortunately I'm in the middle of a project right now. Thanks for your consideration!
Im new to the library and i tried to integrate this in my project. I tried most effects and they work fine with blend enabled but whenever i try Bloom on my character It leaves a trail behind him.
An underwater effect would make a great addition for water based games/levels. It can also be manipulated to simulate a drunken or poisoned state. Please see an example here: https://www.shadertoy.com/view/4ltSDB
I would love to write a PR, but unfortunately I'm in the middle of a project right now. Thanks for your consideration!
Can you change this line in shader fxaa.frag:
color.a = 1.0;
to:
color.a = texture2D(texture, texCoords.xy).a;
?
For transperency support.
Could some information about the performance and configuration of the different bundled effects be added? I find some effects I like and try to tweak the parameters, but I'm somewhat in the dark regarding performance impact. Especially the Bloom effect is nice but it halves my framerate from 60 to 30 (could it be improved? https://stackoverflow.com/questions/98359/fastest-gaussian-blur-implementation).
Can you implement support for creating ModelBatch with custom RenderableSorter, so I can replace default sorter?
This needed because, some models with semi-transparent textures not properly rendering with default sorter.
hello. ur code is really awesome. I'm wondering if you could add a glitch effect to the shaders?
Some methods has been renamed in 0.5: https://github.com/crashinvaders/gdx-vfx/blob/4d694a0090f04dfa36348b0dbeba34e81c6753f7/CHANGES.md#050
VfxManager
's #beginCapture()
/#endCapture()
have been renamed to #beginInputCapture()
/#endInputCapture()
.But there is a couple of references to the old ones (I've checked only endCapture
), e.g.:
The vfxManager uses a fbo to capture all activities and then adds all the effects.
This saves one copy operations.
But, currently fbos in libgdx do not support multi sampling.
So, I am forced to give up sampling support if I use vfxManager.
Can we have an alternative method that just copies the current screen without capturing in a fbo?
This way all draw operations can use multi sampling.
All the effects depended on CopyFilter losing alpha because of https://github.com/crashinvaders/gdx-vfx/blob/master/gdx-vfx/effects/assets/shaders/copy.frag#L31
Because PingPong buffer doesn't use depth buffer, capturing a 3D scene doesn't work.
A workaround is to render 3D scene into another FBO (with depth buffer enabled) and then render this FBO with a sprite batch during capture. This workaround adds an extra full screen rendering.
A solution could be an alternate capture method : user could provide an "input Texture" which be used as the first input texture in the process chain...
I'm not familiar with this library, maybe i missed something?
Great job with this library btw :-)
It seems like VfxManager is not working anymore with the release 1.9.14 of libGDX.
vfxManager = new VfxManager(Pixmap.Format.RGBA8888);
is leading to :
Exception in thread "LWJGL Application" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Pixel Unpack Buffer Object is disabled
at org.lwjgl.opengl.GLChecks.ensureUnpackPBOenabled(GLChecks.java:125)
at org.lwjgl.opengl.GL11.glTexImage2D(GL11.java:2899)
at com.badlogic.gdx.backends.lwjgl.LwjglGL20.glTexImage2D(LwjglGL20.java:598)
at com.badlogic.gdx.graphics.glutils.GLOnlyTextureData.consumeCustomData(GLOnlyTextureData.java:78)
at com.badlogic.gdx.graphics.GLTexture.uploadImageData(GLTexture.java:270)
at com.badlogic.gdx.graphics.GLTexture.uploadImageData(GLTexture.java:257)
at com.badlogic.gdx.graphics.Texture.load(Texture.java:159)
at com.badlogic.gdx.graphics.Texture.(Texture.java:147)
at com.badlogic.gdx.graphics.Texture.(Texture.java:142)
at com.badlogic.gdx.graphics.glutils.FrameBuffer.createTexture(FrameBuffer.java:81)
at com.badlogic.gdx.graphics.glutils.FrameBuffer.createTexture(FrameBuffer.java:42)
at com.badlogic.gdx.graphics.glutils.GLFrameBuffer.build(GLFrameBuffer.java:174)
at com.badlogic.gdx.graphics.glutils.FrameBuffer.(FrameBuffer.java:75)
at com.badlogic.gdx.graphics.glutils.FrameBuffer.(FrameBuffer.java:57)
at com.crashinvaders.vfx.framebuffer.VfxFrameBuffer.initialize(VfxFrameBuffer.java:107)
at com.crashinvaders.vfx.framebuffer.VfxFrameBufferPool.createBuffer(VfxFrameBufferPool.java:134)
at com.crashinvaders.vfx.framebuffer.VfxFrameBufferPool.obtain(VfxFrameBufferPool.java:94)
at com.crashinvaders.vfx.framebuffer.VfxPingPongWrapper.initialize(VfxPingPongWrapper.java:74)
at com.crashinvaders.vfx.framebuffer.VfxPingPongWrapper.(VfxPingPongWrapper.java:65)
at com.crashinvaders.vfx.VfxManager.(VfxManager.java:67)
at com.crashinvaders.vfx.VfxManager.(VfxManager.java:57)
Heya! I'm having trouble getting gdx-vfx to work with FitViewports in my game, admittedly I don't understand much of viewports, but I tried a bunch of different combinations and made some progress, but not without some issues left.
The issue I'm having is that gdx-vfx doesn't seem to be capturing the correct area of the window when black bars / viewport gutters are present. The more black borders I have, the more offset gdx-vfx renders.
Here's a video that demonstrates the issue:
(Note: One of the resize lines in the video says Game.graphics.getWidth/Height
, these are identical to Gdx.graphics.getWidth/Height
)
As far as I understand there are two places where I can set the viewport in gdx-vfx:
resize
method, and here's where changes seem to affect the input region,renderToScreen
with parameters. I believe I got these values correct, as the final FBO is being rendered exactly where it should.I tried to call resize
with multiple values, such as the real window dimensions (Gdx.graphics.getWidth/Height), I tried to pass my logical game size (1920x1080), and I also tried to pass the viewport width/height, the viewport values are by far the most accurate ones, resulting in the correct capture size, however there's an offset I can't figure out how to solve.
I appreciate any directions on how to fix this issue, and great job for creating such an amazing library! โฅ
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.