Giter Club home page Giter Club logo

web-animations-js's Introduction

What is Web Animations?

A new JavaScript API for driving animated content on the web. By unifying the animation features of SVG and CSS, Web Animations unlocks features previously only usable declaratively, and exposes powerful, high-performance animation capabilities to developers.

What is in this repository?

A JavaScript implementation of the Web Animations API that provides Web Animation features in browsers that do not support it natively. The polyfill falls back to the native implementation when one is available.

Quick start

Here's a simple example of an animation that fades and scales a <div>.
Try it as a live demo.

<!-- Include the polyfill -->
<script src="web-animations.min.js"></script>

<!-- Set up a target to animate -->
<div class="pulse" style="width: 150px;">Hello world!</div>

<!-- Animate! -->
<script>
    var elem = document.querySelector('.pulse');
    var animation = elem.animate({
        opacity: [0.5, 1],
        transform: ['scale(0.5)', 'scale(1)'],
    }, {
        direction: 'alternate',
        duration: 500,
        iterations: Infinity,
    });
</script>

Documentation

We love feedback!

Keep up-to-date

Breaking polyfill changes will be announced on this low-volume mailing list: [email protected].

More info

web-animations-js's People

Contributors

alancutter avatar aomarks avatar bedeoverend avatar cibernox avatar dan-tilley avatar darrnshn avatar dstoc avatar dvoytenko avatar ericwilligers avatar ewilligers avatar filaraujo avatar flackr avatar foolip avatar jklein24 avatar lisamuel avatar mgechev avatar mithro avatar mival avatar nevir avatar rasteiner avatar rjwright avatar samthor avatar samuelli avatar sfeast avatar shans avatar suzyh avatar tim-loh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

web-animations-js's Issues

src ignored in Bower distribution leads to problems as it is referenced in web-animations-next.min.js.map

Hi,

I'm trying to use use the Bower package for an Ember project (building with Broccoli). Since the src folder is ignored by bower problems occure when building as there is a refernce in the *.js.map files to the src-folder.
The only way I can build successfully is to dissable sourcemaps, which makes me sad.

The same kind issue has been raised in the showdownjs/showdown project: showdownjs/showdown#200

Thoughts?

Best regards,
Samuel

Opacity reset to initial value when animation ends

When using opacity effect in Chrome, the opacity jumps back to the initial element opacity when the animation ends.

Tested with Chrome 40.0.2214.115 m, Windows 7, web-animations.js 1.0.6

In the following example, the initial opacity of the div is 0.
When clicking on the startAnimation button, the opacity is animated from 0 to 1.
When the animation ends, the opacity jumps back to 0.
I would expect the opacity to stay at 1.
Am I doing something wrong?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>web animations</title>
    <script>
        var startAnimation = function() {
            var elem = document.querySelector('#elem');
            var player = elem.animate([
                {opacity: getComputedStyle(elem).opacity},
                {opacity: 1.0}
            ], {
                duration: 500
            });
        };
    </script>
</head>
<body>
    <div id="elem" style="width:150px; opacity: 0;">Hello world!</div>
    <button onClick="startAnimation()">Start Animation</button>
    <script type="text/javascript" src="web-animations.min.js"></script>
</body>
</html>

What files to host on CDN?

I was thinking about hosting this project on jsDelivr CDN, but saw there are 3 different versions. Since it seems web-animations-next|-lite seems to be more experimental, should I host only web-animations.min.js?

currentTime has no effect when animation is in the finished state

I'm trying to reset an animation by setting the currentTime to 0.
When the animation is in the finished state, currentTime doesn't update the animation.
Only when calling animation.pause() before setting animation.currentTime I can see it changes.

document.timeline.getAnimations() also ignores animations in the finished state.
It will be useful to be able to get all animations for the same use case above to reset all animations in a timeline/page.

Tested with web-animations-next from the 2.1.3 release.

Might be related to
web-animations/web-animations-next#369

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>web animations</title>
    <script>
        var animation;

        var startAnimation = function() {
            var el = document.querySelector('#elem');
            var effect = new KeyframeEffect(el, [
                {opacity: 0},
                {opacity: 1.0}
            ], {
                duration: 2000,
                fill: 'forwards'
            });
            animation = new Animation(effect, document.timeline);
            animation.play();
            };

        var resetAnimation = function() {
            //animation.pause();
            animation.currentTime = 0;
        };
    </script>
</head>
<body>
    <div id="elem" style="width:150px; opacity: 0;">Element</div>
    <button onClick="startAnimation()">Start Animation</button>
    <button onClick="resetAnimation()">Reset Animation</button>
    <script type="text/javascript" src="web-animations-next.min.js"></script>
</body>
</html>

Question: Is it possible to have non-equal duration parts for each part of an animation?

I'm learning the Web Animations API. I've been digging through source for a while, but I'm still unclear whether this is possible or not.

Assume the following code:

@-webkit-keyframes color-change {
    0% {
        color: red;
    }
    33% {
        color: green;
    }
    100% {
        color: blue;
    }
}

I'd like to perform something like this using the Web Animations API. I know I am able to specify a duration, but I can't seem to figure out how to tell the API that I want one part of the animation to run for a shorter period of time than another part of it. It implicitly divides the amount of time between each part of the animation.

Is this possible to do with the current state of the player?

what is the actual browser support for _this_ library?

Browser support is pretty obfuscated. I go to this page: https://www.polymer-project.org/0.5/resources/compatibility.html

That page shows chrome as being the only supported browser for web animations. But i read further down to the polyfill browser support section which then directs me to a web components polyfill or a compatability matrix: https://github.com/WebComponents/webcomponentsjs#browser-support

That matrix only mentions: Custom Elements, HTML Imports, Shadow DOM and Templates.
No mention of the web animation API. And now I'm confused, do I need a webcomponents polyfill to use the web-animations polyfill?

So where can I find the actual browser support of this library as a standalone?

Please provide unminified versions

Sometimes I'd like to debug into web-animations, but mangled local variables make this process pretty hard, even with the source map.

Could you please provide unminified versions of the polyfills, which should be a direct concatenation of source files? That would make debugging a lot easier.

Thanks.

Animate height of SVG elements

Animating the height of an SVG element has no effect.
I know that transform and scale are supported but in my case I need to change the actual height.
Is it supposed to work?

Tested with web-animations-next.js 1.0.7
Chrome 41.0.2272.89 m

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>web animations</title>
    <script>
        var startAnimation = function() {
            var el = document.querySelector('#el');
            var player = el.animate([
                {height: 100},
                {height: 0}
            ], {
                duration: 1000,
        fill: 'forwards'
            });
        };
    </script>
</head>
<body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
      viewBox="0 0 100 100"
      style="width: 200px; height: 200px;">
        <rect id="el" x="0" y="0" width="100" height="100" fill="blue"/>
    </svg>
    <br/>
    <button onClick="startAnimation()">Start Animation</button>
    <script type="text/javascript" src="web-animations-next.min.js"></script>
</body>
</html>

Single keyframes unsupported

In the spec, we're given the following example:
elem.animate({ left: '100px' }, 3000);
As written, this throws the following error:
TypeError: Keyframe effect must be null or an array of keyframes.

So, I make it a single-element array:
elem.animate([{ left: '100px' }], 3000);
And I try to explicitly declare the offset
elem.animate([{offset: 0}, { left: '100px', offset: 1}], 3000);
Both return
NotSupportedError: Failed to execute 'animate' on 'Element': Partial keyframes are not supported.

Not sure if this is a bug or just a document that needs an update, but given these limitations, how can I animate starting from a current position? For example, if I don't know what the element's 'left' property is, but I know I want it to end up at 100px.

Polyfill non-functional when Chrome's experimental web platform features are enabled

Repro steps:

  1. Enable experimental web platform features in Chrome M41.
  2. Open http://web-animations.github.io/web-animations-demos/galaxy/

Expected:
Dots flying around the page.

Actual:
All the dots are in the middle not moving. No console error messages.

The polyfill is working normally with experimental features disabled.
With experimental features enabled the page only works if the polyfill is disabled (http://web-animations.github.io/web-animations-demos/galaxy/?nopolyfill).

Embedding web-animations-js in an SVG

Playing with embedding the polyfill in SVG, as Web Animations hopefully hold promise of replacing SMIL in SVG (I'm assuming?).

So I've tried embedding web-animations-next.min.js in an SVG to see if that worked. It's embedded okay, but there seem to be multiple errors when I open the SVG file in Safari or Firefox (haven't tried IE). The animation works as expected in Chrome and Opera (I'm assuming it's using the actual Web Animations API) so you can see what's supposed to happen.

In Safari the console seems to be reading for every animation frame:
[Error] TypeError: null is not an object (evaluating 'this._surrogateStyle.length') @deprecation.js:42

And also (just once):
TypeError: undefined is not a function (evaluating 'd.getContext("2d")') @ apply-preserving-inline-style.js:167

View the SVG code (and how I'm embedding web-animations-js) here:
https://github.com/arjunmehta/issues/tree/web-animations-js

Animate scrollLeft and scrollTop

I would like to animate a movement in the scrollbar.

If I use

.animate( { scrollLeft: '500' }, 1000 );

I just get the Single keyframes unsupported error commented at #14

So I changed it to :

.animate([{scrollLeft:0},{scrollLeft:500}], 3000);

But nothing happens. I suppose is because it's expecting a css property, but scrollLeft is not. If I use something like

.animate([{Left:0},{Left:3000}], 3000);

It works properly.

Any idea of how to accomplish this?

Minified import

Currently, we're using core-animation/web-animations.html as our shared import for WA in Polymer. I think it's more desirable for us to just depend on web-animations-js directly

I'm not clear on how the imports should be structured, though:

  • web-animations.min.html/web-animations-next.min.html/web-animations-next-lite.min.html?
  • Convert the existing imports over to .dev.html? (this would match existing patterns better)

Also, I worry about some components wanting to import lite, and others wanting the full library

cc @morethanreal

Reflect updated Web Animations API?

The spec for the Web Animations API has been updated on March 13th, 2015: https://w3c.github.io/web-animations/ - items include simplification and the moving of AnimationGroup and AnimationSequence (now GroupEffect and SequenceEffect) to Level 2.

Will you guys reflect on these API changes or still be based on the old version of the spec?

Where is the "style emulation module"?

README says:

to keep the size of web-animations-next-lite as small as possible, the style emulation module is not included.

Where can I find this style emulation module?

web-animations-js should have a bower.json

This repo doesn't have a bower.json. This means that the 780K test/ directory is installed when using bower. This is particularly troubling because this is a dependency of Polymer so this has been bloating packaged apps built with Polymer through bower.

A bower.json file should be added which ignores (at least) the test directory.

issue with opera 12.16 (i686) when use `Element.animate`).

Is there a way to see browsers compatibilities ? Here is the log:

Event thread: change
Uncaught exception: TypeError: 'h' is not a function
Error thrown at line 15, column 41346 in <anonymous function: window.requestAnimationFrame>(a) in file://localhost/home/tngarsel/my_github/extra.js/ijs/tests/web-animations.min.js:
    return 0==i.length&&h(c),i.push([b,a]),b
called from line 15, column 42227 in <anonymous function: b.restart>() in file://localhost/home/tngarsel/my_github/extra.js/ijs/tests/web-animations.min.js:
    return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n
called from line 15, column 41758 in <anonymous function: _play>(c) in file://localhost/home/tngarsel/my_github/extra.js/ijs/tests/web-animations.min.js:
    return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d
called from line 15, column 28428 in <anonymous function: window.Element.prototype.animate>(b, c) in file://localhost/home/tngarsel/my_github/extra.js/ijs/tests/web-animations.min.js:
    return a.timeline._play(a.KeyframeEffect(this,b,c))
called from line 972, column 4 in <anonymous function: iJS.animate>(elt, anime, iterations, time) in file://localhost/home/tngarsel/my_github/extra.js/ijs/partials/i_animation.js:
    return elt.animate( keyframes, timing) ;
called from line 188, column 16 in moveBox() in file://localhost/home/tngarsel/my_github/extra.js/ijs/tests/animation.html:

AnimationSequence in Chrome plays all animations together

In Firefox, element2 is animated after element1 as expected.
In Chrome both elements animate at the same time.

Tested on Windows 7, web-animations-next.js 1.0.7
Firefox 36.0.1
Chrome 41.0.2272.89 m

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>web animations</title>
    <script>
        var startAnimation = function() {
            var el1 = document.querySelector('#elem1');
            var el2 = document.querySelector('#elem2');
            var anim1 = new Animation(el1, [
                {opacity: 0},
                {opacity: 1.0}
            ], {
                duration: 2000,
                fill: 'forwards'
            });
            var anim2 = new Animation(el2, [
                {opacity: 0},
                {opacity: 1.0}
            ], {
                duration: 2000,
                fill: 'forwards'
            });
            var animSequence = new AnimationSequence([
                new AnimationGroup([anim1]),
                new AnimationGroup([anim2])
            ]);
            document.timeline.play(animSequence);
        };
    </script>
</head>
<body>
    <div id="elem1" style="width:150px; opacity: 0;">Element 1</div>
    <div id="elem2" style="width:150px; opacity: 0;">Element 2</div>
    <button onClick="startAnimation()">Start Animation</button>
    <script type="text/javascript" src="web-animations-next.min.js"></script>
</body>
</html>

Web-animations.min.js throw exception when using it with Webpack

Error message:
Cannot set property 'true' of undefined

Error occurred on the very first line:
function(a,b){b["true"]=a

Reason - window object is captured with incorrect code:
function(){return this}

Correct way to get window object (this code taken from jQuery source):
typeof window !== "undefined" ? window : this

AnimationPlayer is no longer a EventTarget

Currently, web-animations-js implements AnimationPlayer as EventTarget, but the spec says it should expose ready and finished promises instead. I wonder if there is any plan to implement these?

I guess the current implementation is of an older spec? Chrome also doesn't expose these two properties, so maybe it should be polyfilled as well.

Uncaught TypeError: Cannot read property 'play' of undefined

Hi all,

I had the attached code running this morning (around 7am GMT) however after doing a clean bower build; I've noticed even after changing the file structure to "/bower_components/web-animations-js/web-animations.min.js" I get the following error: Uncaught TypeError: Cannot read property 'play' of undefined.

It appears as though document.timeline hasnt been initialised?!

<script src="/bower_components/web-animations-js/web-animations.js"></script>
    <div class="pulse" style="width:150px;">Hello world!</div>
    <script>
        var elem = document.querySelector('.pulse');
        var player = document.timeline.play(new Animation(elem, [
            {opacity: 0.5, transform: "scale(0.5)"},
            {opacity: 1.0, transform: "scale(1)"}
        ], {
            direction: "alternate",
            duration: 500,
            iterations: Infinity
        }));
    </script>

Trying to animate padding with -lite fails with cryptic error message

The error I got was from https://github.com/web-animations/web-animations-js/blob/master/src/keyframe-interpolations.js#L65:

Partial keyframes are not supported

It is difficult to parse what this means. I looked at my inputs, and they did specify everything. Not until I read the code (and figured out that Polymer neon-animation imports -lite) did this error make sense. There is some internal filtering magic going on with the key frames, and this error message is not reflecting what the user specified, but what this internal code did.

It would be nice if the message could at least state what properties are considered partial. Even better if it could say that the key frames are partial because these properties are unsupported (and that they are supported if not using -lite).

The original web-animations.js has moved to the web-animations-js-legacy repo

The latest commit has broken polymer/paper-menu-button.

Diffing bower list output for previously working and broken latest shows :

broken:

│ │ └── web-animations-js#cf280cb1d4

working:

│ │ └── web-animations-js#6a1c45473f

I tried to specify 6a1c45473f with bower, but that commit no longer exists.

I wonder if you can supply an equivalent commit so I can roll back the version to the working version again? After that, I can work on solving the problem in a more controlled manner.

Thanks :)

Max.

Does not work on Cordova?

Hi,
web-animation.js blocks cordova hybrid application from building the apk and run. Due to which unable to run animation on cordova applications.

'fill: "forwards"' causes the element to ignore any future style changes.

Hi,

Using fill: forwards when starting an animation somehow disables all style changes after the animation ends. This can very easily be tested by doing:

$('body').animate([{opacity: 1}, {opacity: 0.3}], {duration: 400, fill: 'forwards'})

and after than ends, running:

$('body').style.opacity = 1

It seems that only the properties that have at some point been part of a forwards animation are 'disabled'. And this occurs in chrome 48 but not firefox 44

Element.animate() does not work on iOS Safari

A simple code like this doesn't work on iOS 7 Safari:

var el = document.getElementById('foo');

player = el.animate([
    { opacity: 0 },
    { opacity: 1 }
], {
    duration: 2000,
});

It fails with: “TypeError: Attempting to configurable attribute of unconfigurable property.”.

Reproduction:
open http://jsfiddle.net/7o7xe6fg/ on an iDevice or simulator

Reason for git ignore of the minified files?

Hi There,

Just wondering if there is a good reason for these in gitignore?

web-animations-.min.js
web-animations-
.min.js.map
web-animations.min.js
web-animations.min.js.map

Can they be removed from gitignore? They cause some issues in our vulcanization processes downstream.

Cannot read property 'cancel' of null

I'm trying to use the polyfill on Codepen and I keep running into this error. The full message is as follows:

Uncaught TypeError: Cannot read property 'cancel' of null
b.Animation @ pen.js:1772
window.onload @ pen.js:2134

This happens when using both the 2.1.2 version of the minified file, as well as the 2.1.1 version. A link to the pen can be found here

[Question] Pattern for executing javascript during an animation

During an animation, I'd like to execute some javascript.
If the JS is adjusting attributes, my current pattern is to create a 1ms animation and put it in the sequence. Not pretty, but simple enough.

Alternatively, if I need create/delete an element, I wait until the end:
player.onfinish (I assume this will change to player.finished.then in a future version?)

However, if I need to move something, create a new element, and then move the new element, I think I have to create 2 players and call the 2nd player after the first one finishes, and then the 3rd when the 2nd finishes... this has the potential to get nasty. Is there a better way?

In an ideal world, AnimationSequence would accept an array of Animation as well as functions, but I understand this could get tricky if folks start playing with async functions.

Animate clip-path

Is animating clip-path supported?
In the following example elem.animate() on clip-path has no effect.
Tested with Chrome 41.0.2272.76 m, Windows 7, web-animations.js 1.0.6

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>web animations</title>
    <script>
        var startAnimation = function() {
            var elem = document.querySelector('#elem');
            var player = elem.animate([
                {"clip-path": "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)"},
                {"clip-path": "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"}
            ], {
                duration: 1000,
                fill: 'forwards'
            });
        };
    </script>
</head>
<body>
    <div id="elem" style="width:150px;">Hello world!</div>
    <button onClick="startAnimation()">Start Animation</button>
    <script type="text/javascript" src="web-animations.min.js"></script>
</body>
</html>

Failure to animate when 'initial' or 'inherit' is specified.

The problem:
The API exposed by this polyfill exhibits different behavior than Chrome when given some input.

Current behavior:
Attempting to animate the background color property from/to certain specific values (at least initial and inherit), causes it to "blink" / instantly change between those values.

Expected behavior:
The animation smoothly moves between the supplied values.

Seen on:

  • OS X 10.10.1
    • Safari 8.0.2
    • Firefox 35.0.1

Test case:

  1. Visit example.com.
  2. Inject web-animations.min.js (for example).
  3. Run:
document.body.animate(
    [
        {
            background: 'initial'
        },
        {
            background: 'red'
        },
        {
            background: 'initial'
        }
    ],
    {
        duration   : 4000,
        iterations : 4
    }
);

As proof that the initial value triggers the unexpected behavior, the same test case modified only slightly exhibits the expected behavior:

document.body.animate(
    [
        {
            background: 'blue'
        },
        {
            background: 'red'
        },
        {
            background: 'blue'
        }
    ],
    {
        duration   : 4000,
        iterations : 4
    }
);

trying to preserve the final state causes a flicker in firefox

Say you are running the following animation on an element:

element.animate([
            {opacity: 0.3, transform: "translate3d(105%, 0px, 0px)"},
            {opacity: 1, transform: "translate3d(0px, 0px, 0px)"},
        ], {duration: 400, easing: 'cubic-bezier(0.4, 0, 0.2, 1)'});

If you add the following onfinish to the animation (pseudo-code):

anim.onfinish() {
    element.style.translate3d = "0px, 0px, 0px";
   element.style.opacity = "1";
}

the element will briefly flicker between the reverted state from the animation, and the state applied during onfinish. This only happens in firefox.

Kindly remove compressed archive web-animations.min.js.gz from bower

Hi,
The existence of compressed archive "web-animations.min.js.gz" is making
phone gap build fail with the below error.

Error - A compressed file is in your app and a step in the android tool chain doesn't allow multi-level compression. Please remove this file from your application: dist/bower_components/web-animations-js/web-animations.min.js.gz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.