Giter VIP home page Giter VIP logo

showmy.chat's Introduction

πŸ‘‹πŸ» Howdy!

I'm Ben, a web developer with a passion for accessibility.

  • ✏ I make web accessibility approachable on my blog.
  • πŸŽ₯ I hosted Some Antics, a stream about web accessibility and core web technologies β€” catch the backlog!
  • πŸ“‘ I'm a software engineer at Microsoft, building out the Microsoft Learn platform.
  • πŸ’› I foster inclusive communities of practice for web developers in the Lunch Dev and Frontend Horse Discord servers.

Follow me on Mastodon!

showmy.chat's People

Contributors

a-trost avatar ajcwebdev avatar allcontributors[bot] avatar bendmyers avatar dependabot[bot] avatar fimion avatar jarvis1010 avatar jennjunod avatar kenakafrosty avatar maciejpedzich avatar nickymeuleman avatar peruvianidol avatar redsparr0w 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

Watchers

 avatar  avatar  avatar  avatar

showmy.chat's Issues

Styleguide

To keep the formatting/code style consistent as more people contribute to this project, I propose automating (part of) it.

I asked if there was a styleguide on Discord, and @BenDMyers said:

Not yet - but I’d say ideally use tabs and semicolons.

This (partial) automation can be done with tools like:

Prettier for formatting.

Possibly

If linting tools are used, it is important to use the matching *-config-prettier (like stylelint-config-prettier for stylelint) to prevent conflicts between the linter and Prettier. Leaving all formatting concerns up to Prettier.

I'd be happy to implement the tools while we discuss what rules to apply here.

Provide textual descriptions for themes in the HTML for accessibility

Just a little thought: Most of the theme names have flavor (and rightfully so!) but don't necessarily describe how the theme looks. For vision-impaired users or those using a screen reader for any reason, it may be helpful? Feel free to modify or close this out if that's not reasonable or helpful.

Thanks!

[Docs] Homepage should explain what this is and how to use it more clearly

Right now, the showmy.chat homepage 100% assumes you know what a browser source is and what to do with this magic URL it gives you. That might be fine for folks already invested in their stream overlay setups, but I think it does a disservice for folks who are brand new to establishing their setup.

We should make sure the homepage and its URL builder more clearly explain what this is for and how to use it. I'm not sure the specifics of how we should go about that, but I'm open to suggestions!

Deletion of messages after banning the author is not being reflected

When a user first gets banned and then their message gets deleted, the chat view does update accordingly: the deleted message persists.

Expected behavior

A deleted message should be removed from the chat view, even if its author has been banned before.

Additional info

According to @BenDMyers, first deleting the message (and then banning the user) works fine.
Observed during maxcellw's twitch stream.

A "kitchen-sink" page for themes

While developing the advent-of-code theme, I used the DEMO query param.
While that flow is fine, tweaking styles for specific parts was kind of a chore and involved waiting until the type of chatmessage I was currently tweaking appeared randomly (like an @ mention, an emote use, a VIP chat, ...). Repeating this cycle every time I saved a change in my editor, as the page would reload.

Would a type of "kitchen-sink" page be useful?
I'm imagining a page where every/(most) type of DOM element that needs to be styled exists.
It might also be (optionally) static, as the messages I was tweaking scrolling off screen was also a point of annoyance (lessened by opening the devtools and entering debugger once the message I wanted showed up. Then making CSS in browser to prevent the page from reloading).

As an added benefit, this might also serve as a cool meta image if that page is shared on social platforms.

Document some of the Eleventy features we're using and how

Folks are pretty unfamiliar with Eleventy, and this makes things like templating pretty unfamiliar to newcomers!

We should provide a crash course into some of Eleventy's features we're using, namely:

  • Templating
  • Layouts
  • Eleventy Serverless

Allow users to bring their own styles

Allow users to provide their own CSS.
That way they can either tweak a theme to their liking, or even use it to bring their own custom theme. (maybe this can be used to build custom themes on a base of #44)

This raises a few security questions.
It would mean executing CSS on the user's device.
While CSS is probably fine, executing any code that can be user-supplied warrants a closer look at how that is handled.

Configuration for disallowing certain emotes

Some streamers may not want to display certain emotes, especially if those emotes are against their channel or team's code of conduct or which might not be suitable for their demographic.

The first line of defense for most of these streamers should probably be adding those emotes' names to their channel's banned words list, but in the case that doing so would come off as too forceful, we should offer a second line of defense to ensure that a channel's disallowed emotes don't show up as their emote forms in their chat overlays.

Suggested API

We should support a disallowedEmotes query parameter for overlays that would take a comma-separated list of emote names and ensure that those emotes don't get rendered. For example, /c/BenDMyers?disallowedEmotes=somean3CoolTuna,somean3Howdy would prevent the somean3CoolTuna and somean3Howdy emotes from showing as their emote forms.

We could even support a disallowedEmotes=* option if streamers don't want any emotes to show.

What To Do With Disallowed Emotes

What does it mean to not render an emote? The way I see it, we have two options:

  1. Where the emote was meant to be, display nothing. It's as if the sender had never included the emote.
  2. Display the emote's name (e.g. display somean3CoolTuna in place of the Cool Tuna emote)

I think option 1 has some hidden complexity to it β€” for instance, what if the sender's message contains only disallowed emotes? Do we reject the message altogether? I don't think this is unsolvable by any stretch, but it might be simpler to go with option 2.

Configuration for not showing messages from certain users

Need

Some streamers may have a list of accounts whose messages they would rather not have show up in the overlay. Known bot accounts such as Nightbot or Streamlabs, which can post repetitive messages frequently, could be prime examples of accounts a streamer might want to hide from their overlays.

Suggested API

  • Configuration should be strictly optional. If query parameter is not provided, messages from all accounts are shown.
    • In homepage URL builder, if user does not provide any users to hide, don't add the query parameter to the built URL at all
  • Query parameter could be called something like hideMessagesFrom (open to alternatives, but this one seems really clear to me!)
  • Query parameter value could be a comma-separated list of case-insensitive account names, like streamlabs,Nightbot
  • Messages from these accounts should never be added to the DOM (this is as opposed to hiding the messages with CSS or something like that). This keeps the number of DOM elements lower, and provides the best flexibility within a theme (theme creators don't have to worry about hidden messages messing with anything like :nth-child)

Configuration for showing the "n" most recent messages

Need

Some users would only like to display the n latest messages - especially in the case of large, obtrusive themes such as animalese and cards. This can be handled theme-level β€” for instance, cards currently displays the five most recent messages using :nth-last-child:

[data-twitch-message]:nth-last-child(n+5) {
	opacity: 0;
	transform: rotateX(-90deg);
	transition:
		opacity var(--animation-duration) ease-in,
		transform var(--animation-duration) ease-in;
}

However, this isn't ideal, because it hardcodes the number of messages that can be displayed, and it does so in a way that requires some weird CSS overrides to change.

showmy.chat should provide a query parameter through which users can specify how many of the most recent messages to display. If this query parameter is not provided, then the default behavior should be to show all messages β€” this way, users strictly opt in to only showing a subset of their messages.

Suggested API

  • Configuration should be strictly optional. If query parameter is not provided, all messages are shown.
    • In homepage URL builder, if user does not opt in to only displaying the n latest messages, don't add the query parameter to the built URL at all
  • Query parameter name could be showLatestMessages, and its expected value should be an integer greater than zero.
    • If value is not an integer greater than zero, query parameter is ignored.
  • Deletion should be handled in the JavaScript, and outdated messages should be completely deleted, rather than hidden. Rationale:
    • If outdated messages are hidden with CSS solutions, then when a mod deletes a message, previously-hidden outdated messages could become visible again
    • Some folks may be using the n latest feature to reduce the number of DOM elements on the page for perf reasons

Steps

  • Ensure Eleventy Serverless query parameter data can be accessed inside the handleChat script
  • Ensure if showLatestMessages query parameter has been provided, and is an integer greater than 0, scripts delete older messages
  • Add configuration to homepage URL builder
  • Remove hardcoded CSS implementation in themes (currently just cards, I think?)
  • Notify known users of cards theme of changed behavior

Automatic dependency updates

Would automation of package updates be useful?

I wrote about this a while back: https://nickymeuleman.netlify.app/blog/automate-dependency-updates
TL;DR: automating updating dependencies means less headaches, gradual small fixes instead of a huge refactor when you are 3 major versions behind and the amount of breaking changes gets overwhelming.

I used renovate in that blogpost, but also a good option is dependabot which is now owned by GitHub and fully integrated.
I played around with dependabot and it seems simpler to use (that also means there are less knobs to turn and lacks some features like automatic merging).

I mentioned this to @BenDMyers on Discord, who pointed out that auto-dep updates are less crucial than for instance a react-app.

If this does get automated, I think it's important it stays a helpful tool, and not a noise/busywork-generator.

The codechange from my testing is so small I'll put it inline here, it would add a dependabot.yml file, that checks for updates monthly and makes sure there are at most 5PRs open at a time.

version: 2
updates:
  - package-ecosystem: npm
    directory: '/'
    schedule:
      interval: monthly
    ignore:
      - dependency-name: 'faker'
        versions: ['6.x']

[feature request] Add badge to names

Would be awesome if we could get the option to add badges before usernames.
(possibly with an option to enable/disable them)

Currently only minechat and frontend-horse have any badges as far as I am aware.
image

Although they also only seem to allow for 1 badge per user.

Remove deletion delay when themes don't animate/transition outgoing messages

This feels a bit weird for themes without an animation.
I'd expect messages to disappear after the time I set in the urlbuilder on the homepage.
For themes with an animation: the animation starts at the time I set.
For themes without: do they stay onscreen for the time I set + 1.2s?

Originally posted by @NickyMeuleman in #91 (comment)

In #91, showmy.chat added an API to animate messages as they were being deleted (data-twitch-message-display-status="deleting"). However, this meant that we couldn't remove messages immediately β€” we had to apply the style hook, wait a bit (1.2 seconds), and then delete.

This works great for themes that have outgoing message animations, but it introduces a delay when no animations are used β€” the overlay user says "remove messages after 5 seconds," and the overlay actually removes them after 6.2 seconds. This isn't noticeable after a long enough message lifespan (the difference between 20 seconds and 21.2 seconds isn't especially profound). However, it would be nice if we could tighten the gap between when the user says to remove messages and when we actually remove them in the case that the theme doesn't animate outgoing messages.

Themes could use either CSS transitions or CSS animations to animate an outgoing message. To detect animations, we've found the getAnimations method, which landed in Chrome 84. With Twitch streamers forced to update their OBS instances soon to continue streaming to Twitch, using >75 Chrome APIs is on the table, but I'd like to give it a few months before we start using >75 APIs just to be safe.

[Lint] Disable `no-descending-specificity` Stylelint rule

We should disable the no-descending-specificity Stylelint rule.

For instance, it's producing the following error with regards to the selector [data-twitch-sender-roles~='mod'] .twitch-chat-sender:

 120:1  βœ–  Expected selector ".twitch-chat-sender" to come before selector "[data-twitch-sender-roles~='mod'] .twitch-chat-sender"         no-descending-specificity

This is invalid, since the .twitch-chat-sender node is a child of the [data-twitch-sender-roles] node β€” reversing the order would create a selector that wouldn't apply to anything in the overlay.

Create progress bar for fundraisers

Now that Twitch has a fundraiser feature built in, I'm hoping they'll eventually expose it via API. It'd be great if we could get easy-to-use progress bars.

Allow config for buffering messages

Inspired by @theobr's https://solidchat.vercel.app/

In really fast chats, streamers might want to buffer their chat overlay so messages come up in bursts. We should consider having a system for buffering messages so that they can be shown in bursts.

Suggested API:

  • Optional query parameter bufferMessages which, if provided, receives an integer count of milliseconds. Every n milliseconds, the buffer is flushed to the overlay display.

Configuration for turning off animated emotes

Need

This is probably low priority? But I figure some folks might find animated emotes distracting or otherwise unwanted, and may want to be able to turn off the animation. We should provide streamers with a query parameter that can be used to turn off the animation.

Helpful Links

  • #11 β€” pull request which introduced support for animated emotes within showmy.chat
  • simple-tmi-emotes β€” npm package which parses a message and returns emotes (has configs for static vs animated that we can look at)
  • Twitch emote docs

Suggested API

Default presentation should be to show animated emotes as animated, rather than static. Users may see animated emote support as part of a complete feature set for showmy.chat, and so I would expect folks to opt out of support rather than opt in.

I'm thinking the query parameter should be disableAnimatedEmotes=true. This way, the behavior of the false mode (disableAnimatedEmotes=false) can match the behavior of the undefined mode (leaving the parameter off). I'm open to alternatives, though.

lunchdev overlay

Hey!

I'm really excited to contribute an overlay. I thought I'd create an issue with my notes from each stream. And then knock them all out at once.

  • extend: cards theme
  • add customizable background key color to improve white:white overlays (screenshot attached)
  • add timeout so cards disappear automatically
  • use (working) brand font Rubik

white:white de-focused cards screenshot
image

Design a logo for showmy.chat

Currently, the Discord server and the dummy Twitch account for the demo use Apple's πŸ’¬ emoji glyph as a sort of interim logo. While not entirely critical, it'd be nice if showmy.chat had a proper logo of its own that could be used for these things, as well as Open Graph share images and stuff like that.

  • Just to keep us absolutely in the clear intellectual property-wise, this logo should not allude to Twitch's branding (avoid purple, avoid the speech bubble with eyes, and avoid using the same or similar fonts as Twitch)
  • The logo should contain a brand mark (graphical, icon element) and a wordmark (stylized name of site), which can be used together or independently of each other

Configuration for deleting messages after an amount of time has elapsed

Need

Some users would like messages to go away after some amount of time. This could be handled within a given theme using CSS animation, but this depends on the theme supporting the functionality. Besides, even if a theme were to support deleting messages after some amount of time, that duration would likely be hardcoded.

showmy.chat should provide a query parameter through which users can specify a duration after which the message will be deleted. If this query parameter is not provided, then the default behavior should be to not delete any messages β€” this way, users strictly opt in to messages deleting.

Suggested API

  • Configuration should be strictly optional. If query parameter is not provided, messages are not deleted after any interval.
    • In homepage URL builder, if user does not opt in to deleting after a given interval, don't add the query parameter to the built URL at all
  • Query parameter could be named something like clearMessageAfter or deleteMessageAfter. Open to other names if folks have preferences.
  • Query parameter value should be a number, representing the interval duration before the message is deleted.
    • I'm undecided on whether this should represent number of milliseconds (expected integer) or number of seconds (expected integer or float). I'm open to stronger opinions than mine.
  • Deletion should be handled in the JavaScript, and deleted messages should be completely deleted, rather than hidden. This is in part because some folks may be "delete-after" feature to reduce the number of DOM elements on the page for perf reasons
  • Users should (optionally) be able to combine this query parameter with the showLatestMessages param from #14 if they so choose β€” these parameters should be treated as independent
  • Query parameter data should be provided to the scripts using the same pattern as #14

Steps

  • Decide on a name for the query parameter
  • Decide whether we expect milliseconds (integer) or seconds (integer or float) as the query parameter value
  • Ensure Eleventy Serverless query parameter data can be accessed inside handleChat script
  • Ensure if the clearMessageAfter (or whichever other name we land on) query parameter has been provided, and is a valid number, scripts delete messages after that interval
  • Add configuration to homepage URL builder
  • Remove any hardcoded CSS implementation in themes

Let users customize themes with URL-encoded styles

It would be great if you could customize themes with data stored as URL parameters. Similar to how Cloudinary/Imgix do their image transforms with an image API, themes could have a Theme API where everything gets added to the URL.

Customized URLs might look something like this:
https://showmy.chat/c/TrostCodes?theme=frontend-horse&text-color=03ae92&bg-color=03ae92&mod-bg-color=03fa20&font-size=16&font-family=Roboto

These could be defined per-theme with a JSON object, providing labels, types (color, text, select, integer), etc.

Then in an interface, you'd be able to customize the different properties. Here's a quick mockup of how I see this potentially looking:

detailed mockup of a Customize Theme UI, with fields to edit colors, font sizes, families, and more.

If you paste an old URL in, the values would load and you'd be able to easily customize once again.

We'd need to decide if some themes just have small customization options, or arent' customizable at all. Or if there are standard values across all themes, like font-family or text-color. I worry that would limit the potential creativity of future themes, so letting each theme create its own properties feels like the most flexible way, if not a tad chaotic.

This would also address #2

Caveat

This idea assumes demand for people to deeply customize their themes.
It might be better for the time being to focus on building out more theme styles that people like, rather than putting the onus on users to create a style they like through this method.

@BenDMyers did mention that you could get around this URL encoding bit by adding custom styles in OBS which is a great workaround.

Create a guide for integrating with OBS

There are a lot of folks who want to get into streaming and have fancy overlays, like showmy.chat, but they don't actually know how to make it work with OBS.

Like, there's this website thing? And I can configure it, and it loads stuff from my Twitch - that's cool. But how do I actually get that overlay into my stream?

It would be awesome if there were a guide somewhere that explains what the Browser source is, how it works, how to configure it showmy.chat, where to position it in the sources layers, etc. etc. I think that would be beneficial for getting beginners who don't really know where to start... started.

Improve `showCommands` experience in URL builder

Currently, URL builder converts commas to %2C encoding. We should convert this to , directly.

We can also do some niftiness to make it a little easier to use by stripping any leading ! characters (so folks can say !commands or commands, and the parameter will say commands regardless.

Configuration for displaying commands as though they were regular messages

Many chats are set up with chat commands (message starting with !, such as !commands or !discord). By default, ComfyJS doesn't treat these the same as other messages β€” so commands don't show up in the chat display.

We should allow streamers to opt into displaying command messages alongside the other messages if they want. It's my opinion that this should be opt-in rather than opt-out, but I'm open to other opinions!

Suggested API

We'll need to add a query parameter β€” I'm thinking showChatCommands. At minimum, showChatCommands=true should opt the overlay into displaying chat commands like normal messages.

Optionally - and maybe this is for a second pass, we could maybe allow folks to pass a comma-separated list of commands to show: so, for instance, someone could say showChatCommands=commands,discord to only show those commands in the chat.

Chat command messages should use similar markup to regular messages for max interoperability β€” however, we should give folks a style hook to style commands separately. I'm thinking data-twitch-chat-command="{command name}", so for instance data-twitch-chat-command="discord".

Allow themes to style the replied-to user in reply snippets

Currently, reply snippets are straight text: something like Replying to @showmychat: Lorem ipsum dolor sit amet.... We should wrap the mention in a node to allow themes to target it.

In-message mentions are currently using <mark>. It makes sense to me to continue using <mark>, or to use a <span>. We should figure out a sensible selector β€” I'm thinking data-twitch-replied-user="showmychat", but I'm open to other ideas.

Demo page not working during local development

Pages like http://localhost:8080/c/showmychat?theme=default&DEMO=true remain unpopulated.
The CSS gets applied, as you can see the background change when you select a different theme, but messages never show up.

The errors in the browser console:
image

I think what's happening is the errors in the console stop JS executions, and the script that should post faked messages never gets a chance to run.

the console errors is textform: Access to fetch at 'https://api.betterttv.net/3/cached/users/twitch/762083631' from origin 'http://localhost:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://localhost:8080' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. bttvIntegration.js:80 GET https://api.betterttv.net/3/cached/users/twitch/762083631 net::ERR_FAILED 404 defaultFetch @ bttvIntegration.js:80 getBttvChannelEmoteDict @ bttvIntegration.js:67 init @ handleChat.js:228 await in init (async) (anonymous) @ handleChat.js:233 bttvIntegration.js:80

Uncaught (in promise) TypeError: Failed to fetch
at defaultFetch (bttvIntegration.js:80:25)
at getBttvChannelEmoteDict (bttvIntegration.js:67:32)
at init (handleChat.js:228:24)
defaultFetch @ bttvIntegration.js:80
getBttvChannelEmoteDict @ bttvIntegration.js:67
init @ handleChat.js:228
await in init (async)
(anonymous) @ handleChat.js:233

Allow themes to style `/announce` messages

Twitch recently introduced five new commands that streamers and their mods can leverage to highlight their messages in the chat:

  • /announce

Twitch sample announcement message with thick purple borders along the left and right sides.

  • /announceblue

Twitch sample announcement message with thick blue-to-purple gradient borders along the left and right sides.

  • /announcegreen

Twitch sample announcement message with thick green-to-cyan gradient borders along the left and right sides.

  • /announceorange

Twitch sample announcement message with thick orange-to-yellow gradient borders along the left and right sides.

  • /announcepurple

Twitch sample announcement message with thick purple-to-pink gradient borders along the left and right sides.

If possible, we should expose whether a message is an announcement, and even which color was used (/announce vs /announceblue vs /announcegreen and so forth).

It might be worth considering whether we want to make special announcement formatting a configurable option in the URL builder, but my stance is we probably don't need to, since folks can always opt not to use the /announce family of commands.

Unicode emojis are throwing off emote replacement

Unicode emojis (as in, the emojis you use your device's native emoji keyboard to type) are messing with the string replacement indices for adding emote <img> strings to the message. This appears to be because emojis are multiple bytes (at least two, sometimes more depending on the emoji). Multiple emojis cause the emote <img> string replacement to be even more offset.

A few examples:

πŸ¦– somean3CoolTuna

  • Result: πŸ¦– somean3CoolTuna
  • Result as HTML string:
πŸ¦–<img alt=" somean3CoolTun" data-twitch-emote=" somean3CoolTun" data-twitch-emote-id="emotesv2_3e72737cb25d4278971dd4988b48992c" src="https://static-cdn.jtvnw.net/emoticons/v2/emotesv2_3e72737cb25d4278971dd4988b48992c/default/light/3.0">a
  • Expected: πŸ¦– somean3CoolTuna
  • Expected HTML string:
πŸ¦– <img alt="somean3CoolTuna" data-twitch-emote="somean3CoolTuna" data-twitch-emote-id="emotesv2_3e72737cb25d4278971dd4988b48992c" src="https://static-cdn.jtvnw.net/emoticons/v2/emotesv2_3e72737cb25d4278971dd4988b48992c/default/light/3.0">

πŸ¦– πŸ¦– πŸ¦– πŸ¦– hellooooooooo somean3A11Y

  • Result: πŸ¦– πŸ¦– πŸ¦– πŸ¦– hellooooooooo somean3A11Y
  • Result as HTML string:
πŸ¦– πŸ¦– πŸ¦– πŸ¦– helloooooo<img alt="ooo somean3" data-twitch-emote="ooo somean3" data-twitch-emote-id="emotesv2_c13dfc82e82d4c05b41f1dfde9dbd38e" src="https://static-cdn.jtvnw.net/emoticons/v2/emotesv2_c13dfc82e82d4c05b41f1dfde9dbd38e/default/light/3.0">A11Y
  • Expected: πŸ¦– πŸ¦– πŸ¦– πŸ¦– hellooooooooo somean3A11Y
  • Expected HTML string:
πŸ¦– πŸ¦– πŸ¦– πŸ¦– hellooooooooo <img alt="somean3A11Y" data-twitch-emote="somean3A11Y" data-twitch-emote-id="emotesv2_c13dfc82e82d4c05b41f1dfde9dbd38e" src="https://static-cdn.jtvnw.net/emoticons/v2/emotesv2_c13dfc82e82d4c05b41f1dfde9dbd38e/default/light/3.0">

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.