GithubHelp home page GithubHelp logo

sindresorhus / keyboardshortcuts Goto Github PK

View Code? Open in Web Editor NEW
1.8K 19.0 157.0 1.43 MB

⌨️ Add user-customizable global keyboard shortcuts (hotkeys) to your macOS app in minutes

Home Page: https://swiftpackageindex.com/sindresorhus/KeyboardShortcuts/documentation/keyboardshortcuts/keyboardshortcuts

License: MIT License

Swift 100.00%
keyboard-shortcuts hotkey macos swift-package swift-package-manager carthage cocoapods swiftui swiftui-components

keyboardshortcuts's Introduction

KeyboardShortcuts KeyboardShortcuts

This package lets you add support for user-customizable global keyboard shortcuts to your macOS app in minutes. It's fully sandbox and Mac App Store compatible. And it's used in production by Dato, Jiffy, Plash, and Lungo.

I'm happy to accept more configurability and features. PR welcome! What you see here is just what I needed for my own apps.

Requirements

macOS 10.15+

Install

Add https://github.com/sindresorhus/KeyboardShortcuts in the “Swift Package Manager” tab in Xcode.

Usage

First, register a name for the keyboard shortcut.

Constants.swift

import KeyboardShortcuts

extension KeyboardShortcuts.Name {
	static let toggleUnicornMode = Self("toggleUnicornMode")
}

You can then refer to this strongly-typed name in other places.

You will want to make a view where the user can choose a keyboard shortcut.

SettingsScreen.swift

import SwiftUI
import KeyboardShortcuts

struct SettingsScreen: View {
	var body: some View {
		Form {
			KeyboardShortcuts.Recorder("Toggle Unicorn Mode:", name: .toggleUnicornMode)
		}
	}
}

There's also support for Cocoa instead of SwiftUI.

KeyboardShortcuts.Recorder takes care of storing the keyboard shortcut in UserDefaults and also warning the user if the chosen keyboard shortcut is already used by the system or the app's main menu.

Add a listener for when the user presses their chosen keyboard shortcut.

App.swift

import SwiftUI
import KeyboardShortcuts

@main
struct YourApp: App {
	@StateObject private var appState = AppState()

	var body: some Scene {
		WindowGroup {
			// …
		}
		Settings {
			SettingsScreen()
		}
	}
}

@MainActor
final class AppState: ObservableObject {
	init() {
		KeyboardShortcuts.onKeyUp(for: .toggleUnicornMode) { [self] in
			isUnicornMode.toggle()
		}
	}
}

You can also listen to key down with .onKeyDown()

That's all! ✨

You can find a complete example in the “Example” directory.

You can also find a real-world example in my Plash app.

Cocoa

Using KeyboardShortcuts.RecorderCocoa instead of KeyboardShortcuts.Recorder:

import AppKit
import KeyboardShortcuts

final class SettingsViewController: NSViewController {
	override func loadView() {
		view = NSView()

		let recorder = KeyboardShortcuts.RecorderCocoa(for: .toggleUnicornMode)
		view.addSubview(recorder)
	}
}

Localization

This package supports localizations. PR welcome for more!

  1. Fork the repo.
  2. Create a directory that has a name that uses an ISO 639-1 language code and optional designators, followed by the .lproj suffix. More here.
  3. Create a file named Localizable.strings under the new language directory and then copy the contents of KeyboardShortcuts/Localization/en.lproj/Localizable.strings to the new file that you just created.
  4. Localize and make sure to review your localization multiple times. Check for typos.
  5. Try to find someone that speaks your language to review the translation.
  6. Submit a PR.

API

See the API docs.

Tips

Show a recorded keyboard shortcut in an NSMenuItem

See NSMenuItem#setShortcut.

Dynamic keyboard shortcuts

Your app might need to support keyboard shortcuts for user-defined actions. Normally, you would statically register the keyboard shortcuts upfront in extension KeyboardShortcuts.Name {}. However, this is not a requirement. It's only for convenience so that you can use dot-syntax when calling various APIs (for example, .onKeyDown(.unicornMode) {}). You can create KeyboardShortcut.Name's dynamically and store them yourself. You can see this in action in the example project.

Default keyboard shortcuts

Setting a default keyboard shortcut can be useful if you're migrating from a different package or just making something for yourself. However, please do not set this for a publicly distributed app. Users find it annoying when random apps steal their existing keyboard shortcuts. It’s generally better to show a welcome screen on the first app launch that lets the user set the shortcut.

import KeyboardShortcuts

extension KeyboardShortcuts.Name {
	static let toggleUnicornMode = Self("toggleUnicornMode", default: .init(.k, modifiers: [.command, .option]))
}

Get all keyboard shortcuts

To get all the keyboard shortcut Name's, conform KeyboardShortcuts.Name to CaseIterable.

import KeyboardShortcuts

extension KeyboardShortcuts.Name {
	static let foo = Self("foo")
	static let bar = Self("bar")
}

extension KeyboardShortcuts.Name: CaseIterable {
	public static let allCases: [Self] = [
		.foo,
		.bar
	]
}

// …

print(KeyboardShortcuts.Name.allCases)

And to get all the Name's with a set keyboard shortcut:

print(KeyboardShortcuts.Name.allCases.filter { $0.shortcut != nil })

FAQ

How is it different from MASShortcut?

This package:

  • Written in Swift with a swifty API.
  • More native-looking UI component.
  • SwiftUI component included.
  • Support for listening to key down, not just key up.
  • Swift Package Manager support.
  • Connect a shortcut to an NSMenuItem.
  • Works when NSMenu is open (e.g. menu bar apps).

MASShortcut:

  • More mature.
  • More localizations.

How is it different from HotKey?

HotKey is good for adding hard-coded keyboard shortcuts, but it doesn't provide any UI component for the user to choose their own keyboard shortcuts.

Why is this package importing Carbon? Isn't that deprecated?

Most of the Carbon APIs were deprecated years ago, but there are some left that Apple never shipped modern replacements for. This includes registering global keyboard shortcuts. However, you should not need to worry about this. Apple will for sure ship new APIs before deprecating the Carbon APIs used here.

Does this package cause any permission dialogs?

No.

How can I add an app-specific keyboard shortcut that is only active when the app is?

That is outside the scope of this package. You can either use NSEvent.addLocalMonitorForEvents, NSMenuItem with keyboard shortcut (it can even be hidden), or SwiftUI's View#keyboardShortcut() modifier.

Does it support media keys?

No, since it would not work for sandboxed apps. If your app is not sandboxed, you can use MediaKeyTap.

Can you support CocoaPods or Carthage?

No. However, there is nothing stopping you from using Swift Package Manager for just this package even if you normally use CocoaPods or Carthage.

Related

keyboardshortcuts's People

Contributors

2grey avatar decodism avatar deloeribas avatar emiliopelaez avatar fejese avatar filipesaz avatar francisfeng avatar gpoitch avatar hank121314 avatar harajune avatar insidegui avatar isametry avatar kant avatar kaunteya avatar l1cardo avatar maschina avatar megabitsenmzq avatar muan avatar nathanwhy avatar niklasr22 avatar pvieito avatar rtharston avatar seungwoochoe avatar sindresorhus avatar sonsongithub avatar soundflix avatar tofumatt avatar yazeedalkhalaf avatar ywolff 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

keyboardshortcuts's Issues

Localizations

Would be nice to ship with localizations:

  • The recorder button has a couple of words.
  • The alert when the keyboard shortcut is taken by the system or by the app's main menu.

However, since we support Swift Package Manager, we cannot do this until Swift 5.3, which supports resources.

Keyboard shortcuts persist across app.

Thanks for the project. I enjoyed the UI to allow user select Keyboard shortcuts.

However this is what i found:

I set Cmd+f to TextField.becomeFirstResponder so that user can search within the app. Works great.

I went to Xcode minizing the app but Cmd+f is taken. I felt weird and realized this is caused due to this new library i used.

Hard-coded keyboard shortcuts

Sometimes you need to add hard-coded keyboard shortcuts. Would be useful to add an API for that.

It could be an overload to onKeyUp/onKeyDown that accepts a Key and NSEvent.ModifierFlags.

KeyboardShortcuts.onKeyUp(.a, modifiers: [.command]) {
	// Do something.
}

Alternatively, it could just support a KeyboardShortcuts.Shortcut type directly:

KeyboardShortcuts.onKeyUp(.init(.a, modifiers: [.command])) {
	// Do something.
}

We should document that devs should prefer to let users customize the shortcuts instead.

Feedback wanted.

Add `.resetAll()` method

Which would reset all the shortcuts in extension KeyboardShortcuts.Name.

This cannot be done until Swift supports static key paths. We could potentially do something with Mirror today, but it's not important enough to do such a hacky workaround.

Action is called for many times

Keyboard shortcut action is called for many times, and fixed when relaunch the app. After I change the shortcut to another, it appears again, and disappears when relaunch the app.
The project is a Cocoa project.
Don't know if this is a Big Sur bug or anything else.
This problem never appeared on my another SwiftUI project. Maybe this is only a Cocoa problem?

2020-07-27 13-50-00 2020-07-27 13_56_22

Localizable doesn't work.

I tried to add ".environment(.locale, .init(identifier: "xxx"))" to support localizable in my SwiftUI project, but it only displays as English. I found the SwiftUI_Previews in your package, in the preview also like this. So, how to implement KeyboardShortcuts localizable in a SwiftUI project?

Disable all shortcuts and then re-enable them

There should be a way to disable all shortcuts and then re-enable them. This is useful on a Preferences screen where you are registering a bunch of shortcuts. While you are entering new shortcuts, you should not be able to invoke the global shortcuts, especially when the control has focus.

Currently there is no way to disable global hotkey monitoring.

Use only modifiers and shortcut

Hello,

Love the library. Im trying to use only the option + command modifier keys and all function requires an associated non modifier key. anyway to get around this?

Add German localization

Request to add German localization.

I will propose a PR for German localization right away.

Make `NSMenuItem#setShortcut` work better

https://sindresorhus.com/KeyboardShortcuts/Extensions/NSMenuItem.html#/s:So10NSMenuItemC17KeyboardShortcutsE11setShortcut3foryA2CC4NameVSg_tF

Currently, you have to manually disable the keyboard shortcut while the menu item's menu is open. It would be nice if we could somehow handle this automatically.

Is there any way to check if any NSMenu is currently open? We could then disable the global keyboard shortcut listener then. Maybe NSMenu.didBeginTrackingNotification.

setShortcut should maybe also override the .action of the menu item and route the event to the normal KeyboardShortcuts.onKeydown/KeyboardShortcuts.onKeyUp event handlers, so you only need to handle the event in one place.


Alternatively, use the method described in #1, and then use performActionForItem(at: Int) on the relevant menu item.


I'm open to other ideas.

Keyboard Shortcuts with Special Function Keys

Hello, firstly thank your amazing work on this library, it's super useful!

I wanted to know if there's way to map keyboard shortcuts to the special function keys on the keyboard, like the increase /decrease brightness/volume keys (on the first row on Apple keyboards)

For now, when recording a shortcut, these keys are not recognised at all (or maybe macOS just hijacks them). If I try using fn button + these keys, it maps to F1/F2 etc instead, which are not the same thing.

Custom storage

The defaults here are great and will work for most, but some users will need to store the keyboard shortcuts differently. For example, they are migrating from a different keyboard shortcut solution or they have a different preferred way of storing the shortcuts. I think we could expose a few storage-related hooks that would solve a lot of use-cases in one go.

We could add a protocol with a few required methods:

  • get
  • set
  • contains
  • remove

The default implementation of this protocol would be the current UserDefaults storage, but a user could override it like this KeyboardShortcuts.storage = myStorage if needed.

Thoughts? Am I over-designing this?

save Keyboard Layout alongside KeyCode?

just some thoughts. i had the case in an app where i had to support different Keyboard Layouts. all good. for the Keyboard Shortcut, there's two possible ways:

  1. not caring about the Keyboard Layout. like you saved shift-command-a on a US QWERTY, you have would have to press shift-command-q on a French AZERTY (Virtual Keyboard). same KeyCode, different character.
  2. keep the Keyboard Layout alongside the KeyCode. you saved shift-command-a on a US QWERTY, you would have to press shift-command-a on a French AZERTY. same character, different KeyCode.

i'm not sure if any solution is better than the other. like a Keyboard Shortcut should be more of a position than of a key character per se. but at the same time with the current UI that does not care about the Keyboard Layout it's a little confusing.

it's easy to add this out of Keyboard Layout in our own project, but maybe an idea for KeyboardShortcuts? or maybe the idea makes no sense. that would work too.

Allow dynamic keyboard shortcut names

My app has a use-case for adding shortcuts for user-defined actions.
Hence, I cannot register statically typed Keyboard Shortcuts names.

It would be great if the framework would allow for dynamic shortcut names.

Or is this already possible? I couldn't figure it out so far, sorry! Or is there an important reason why this has to be static?

Thanks for your help!

v1.5.0 `AsyncStream` issue

I am getting a

Converting non-sendable function value to '@Sendable (AsyncStream<Void>.Continuation.Termination) -> Void' may introduce data races

error after importing v1.5.0

Help for multiple/variable `KeyboardShortcuts.Recorder(for: )`

Hi, feel happy to meet such a easy-to-use package.

However, I checked the Example and found if you need more shortcut kinds, it seems you have to set them fixed.

extension KeyboardShortcuts.Name {
    static let testShortcut1 = Self("testShortcut1")
    static let testShortcut2 = Self("testShortcut2")
    static let testShortcut3 = Self("testShortcut3")
    static let testShortcut4 = Self("testShortcut4")
}

What if I want to use user-customizable/variable shortcut kinds? For example, like Manico in the App Store, it allows users to set shortcuts for each application. But the developer cannot know the required amount.

One obvious solution is to use static let testShortcut1 = Self("testShortcut1") 10 or 100 times. In that case it's always adequate for requirements. Is there any other way to achieve that?

Appreciate for any hints including tricks in Swift language!

Allow some system-reserved keyboard shortcuts that are not used?

great package. i'm new to macOS and Swift development and got things working painlessly 👍🏼️

wondering though whether there's a way i could see why some shortcuts are said to be used system-wide while they're not registered in the macOS keyboard shortcuts settings. any idea? i.e. "Command + Esc". some other apps like 1Password give the same warning message, but some others like Dash allow the use of those shortcuts. so i guess there's an implementation difference (which is fine). just trying to understand what those system-wide shortcuts that are not registered in the macOS settings are doing and if i can change them. thanks!

Recorder onChange callback

Looking for an api to be notified when a recorder view successfully changes/removes its shortcut. Something like:

KeyboardShortcuts.RecorderCocoa(for: .doSomething, onChange: { (shortcut: KeyboardShortcuts.Shortcut) in
 // do something with new shortcut key
})

I have my own preferences storage solution set up in an existing app and I want to update it when the recorder changes. I suppose I'd like to disable the build-in UserDefaults storage as well, but not that's not a big deal.

Mac Catalyst usage?

Thanks for this great framework, very useful!
I wanted to know if it is possible to use this framework on Mac Catalyst as well?

Cannot add as SPM

Cannot add this package as Swift Package Manager.

Dependencies could not be resolved because root depends on 'KeyboardShortcuts' 1.3.0..<2.0.0.
'KeyboardShortcuts' >= 1.3.0 cannot be used because no versions of 'KeyboardShortcuts' match the requirement 1.3.1..<2.0.0 and 'KeyboardShortcuts' 1.3.0 contains incompatible tools version (5.5.0).

Environment: Version 12.5.1
MacOS: 11.5.2

can't focus on KeyboardShortcuts Recorder input

...
@FocusState private var shouldRecordCustomShortcut: Bool
...
.onChange(of: enterNormalModeWith) { _ in
    shouldRecordCustomShortcut = true
}
...
KeyboardShortcuts.Recorder(for: .enterNormalMode).focused($shouldRecordCustomShortcut)

i would expect the KeyboardShortcuts Recorder to be focused and being able to type a shortcut to be recorded. but although the code removes the focus from any other field, the KeyboardShortcuts Recorder doesn't get focused.

if i replace the KeyboardShortcuts Recorder by any other field, it works. so my code itself seems to be fine.

any more info i could give to help? thanks.

Crash in older versions of macOS due to SwiftUI not found

Sharing this in case anyone else stumbles on this in the future.

Our app supports older versions of macOS that came out before SwiftUI (e.g. macOS Mojave). As such, we were using KeyboardShortcuts with Cocoa instead of SwiftUI. Users on older versions all of a sudden experienced a crash due to SwiftUI not found, despite us not calling into KeyboardShortcuts SwiftUI APIs. After running a git bisect, we found out that a totally unrelated code change caused SwiftUI to go from weakly to strongly imported.

Fortunately, the fix is quick and is outlined in detail here: https://developer.apple.com/forums/thread/126506

tl;dr add SwiftUI to Link Binary With Libraries then change its Status from Required to Optional in your application

Can't record shortcuts when empty

Describe the bug

When the current shortcut is cleared and the the box is left empty, it is not possible to record a new shortcut anymore.

To Reproduce

  • Delete existing shortcut
  • Click outside to deselect recorder field
  • Try to click recorder field again

Expected behavior

  • A new shortcut should be recordable

Desktop (please complete the following information)

  • macOS version: Big Sur 11.1
  • KeyboardShortcuts version: 0.7.0
  • Due to backward compatibility I use RecorderCocoa instead of Recorder

Additional information

  • Clicking Record Shortcut changes to Press shortcut as long as left mouse button is clicked and skips back to Record shortcut after mouse button release.
  • When double clicking Record Shortcut field it changes to Press shortcut, but does not allow any combinations, only plain single letters. But the x button will appear again.

Add ability to reset a shortcut

This is a very useful package and the SwiftUI bindings make it a breeze to use. Please also add the ability to reset the shortcuts. I've tried resetting in the UserDefaults.standard directly but it didn't seem to have any effect.

I see that the code already has this ability, just that it needs to be exposed as a public API, say KeyboardShortcuts.reset(name: Name)

Allow to use in XIB

Hello, thank you for the great package!

I'm trying to figure out how to use recorded in Interface Builder? I'd normally add custom view and set its class to KeyboardShortcuts.RecorderCocoa but it doesn't work. I couldn't find any documentation about this too.

Is it possible to use KeyboardShortcuts.RecorderCocoa from XIB files?

App-specific keyboard shortcuts

Is it possible for me to register a keyboard shortcut that only applies when my app has focus instead of a global keyboard shortcut?

Package resolution failed ...

"because KeyboardShortcuts >=1.2.0 contains incompatible tools version and root depends on KeyboardShortcuts 1.3.0..<2.0.0, version solving failed."

adding 1.1.0 to frameworks works.
Any idea what I'm doing wrong?

Xcode 12.4, macOs 10.15.7

Cannot record previously recorded shortcut

I've found a small issue when integrating the package. It can also be reproduced in Lungo app:

  1. Open "Preferences" -> "Keyboard Shortcuts..."
  2. Register CMD+SHIFT+K shortcut.
  3. Register CMD+SHIFT+L shortcut.
  4. Try to register CMD+SHIFT+K shortcut again.

For some reason, it's no longer possible to register CMD+SHIFT+K shortcut until the application is restarted.

Having to re-register / reassert shortcuts every session!

My global shortcuts only work after I have opened the Shortcuts window (as in the package Example) from the NStatusItem menu and then press the shortcut combination keys (again), even though they have been previously recorded and saved. Now if I close the Shortcuts window my assigned global shortcuts will work flawlessly no matter what App is currently active, until I reboot or close my StatusItemMenu app, after which I have to repeat the same procedure again to reinstate/ reregister the (same, saved) global shortcuts. Is there a way around this?

Manually set a keyboard shortcut for a name

This can be useful for migrating over to this package from some other solution.

Inside some one-time migration method:

let shortcut = KeyboardShortcuts.Shortcut(carbonKeycode: someHotkey, carbonModifiers: someModifiers)

KeyboardShortcuts.Name.foo.shortcut = shortcut

Alternatively:

let shortcut = KeyboardShortcuts.Shortcut(carbonKeycode: someHotkey, carbonModifiers: someModifiers)

KeyboardShortcuts.Name.set(shortcut, for: .foo)

That way, the user doesn't need to know the implementation details on how it's stored. Like here: p0deje/Maccy@1001035#diff-2589021fe69dedfc5619fc6a19136f23R117-R126

@p0deje Any thoughts?

Shortcuts Using Media Keys

Hi folks,

An issue I'm seeing with MonitorControl is apparently worth your attention, as it uses KeyboardShortcuts to assign its custom keyboard controls. Here's a screenshot:
Screenshot 2021-10-05 at 1 26 31 pm
(MonitorControl allows controlling Brightness etc. on external displays, much like they were Apple ones, via a common display feature called DDC.)

I'd like to use the Increase Brightness and Decrease Brightness keys on my M1 Air's built in keyboard (and chord them with Shift for Contrast control). Unfortunately, they don't show up unless I turn them into F1 and F2 by holding Fn. Ideally, all such media keys should be available for making custom keyboard shortcuts.

Those media keys are available to Karabiner. They use extended key codes, which is why I was not surprised! Many apps can't "see" them. Which leaves them open for many user defined shortcuts!

My original report:
MonitorControl/MonitorControl#631 (reply in thread)

Support menu bar apps that uses `NSMenu`

It currently doesn't work for menu bar that uses NSMenu. This is because NSMenu puts the event loop into a special tracking mode when the menu is open, which means the keyboard shortcut event will only arrive when the menu closes.

It should be possible to implement this by setting up a Carbon local event monitor instead when the menu is open. I have already made an swifty wrapper for it: https://gist.github.com/sindresorhus/2bb90276ad608a22ee5e8fb291b35b88 So we just need to use that instead when NSMenu is open.

The workaround for now is to disable the shortcut when the menu is open, register a local shortcut using the above code, and then when the menu closes, enable the global shortcut again.

If you want to work on this, please read my comment in #28 (comment).

How do I get the KeyboardShortcuts Example into a storyboard viewController Window?

Does anyone knows how to get the SwiftUI View (MainScreen in the example) into a storyboard viewController ( or NSHostingController?) so that it can be called with the following Shortcut functiion in App.delegate.

`
let menu = NSMenu()

menu.addItem(NSMenuItem(title: "Set Shortcut", action: #selector(AppDelegate.Shortcut(sender:)), keyEquivalent: "" ))
statusItem.menu = menu
}
@objc func Shortcut(sender: NSMenuItem){

    //call the HostingViewController / SwiftUI View here

    }

`

Regards
Paul

Square Textfield style

Is there a way to change the style of the text field to .squareBorder? If not, would love this property to be exposed!

Is there a way to detect if modifier keys still pressed on key up?

Right now KeyboardShortcuts.onKeyUp recognize key up when users release non-modifier keys.

Is there a way to detect whether modifier keys are still pressed or not?

I want to replicate the "command+tab" behavior where users can cycle through items while modifier keys still down.

Allows recording shortcuts with shift, that trigger no action

The recorder allows creating a new shortcut just with shift as the modifier, for example Shift + X, but executing this shortcut leads to no action. I've actually got an App Store rejection because of this issue, funny because many apps using this super useful library (thanks ;) ) are available on the App Store :)

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.