Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple vanilla JS example to repo #260

Open
stephanbogner opened this issue Jan 4, 2024 · 4 comments
Open

Add simple vanilla JS example to repo #260

stephanbogner opened this issue Jan 4, 2024 · 4 comments

Comments

@stephanbogner
Copy link

First of all:
This is a super interesting and fun project – thanks for putting in the time and effort ❤️

Problem:

I had a hard time getting started. Some notes from my journey:

  • The docs are extensive but also a bit daunting. Even the Quickstart didn't help me much getting stuff running in the beginning unfortunately.
  • This file was helpful as reference, but since there is no dist folder (anymore?) I couldn't get this code to run
  • The list of projects also helped (due to many being open source)
  • Glitch links to docs that don't exist anymore
  • The npm installed version doesn't contain the actual wasm file (I only found it via the CDN)
  • I wasn't sure (and still am not) if one should use the "js" or the "mjs" files
  • I thought the Glitch project is just documentation so only now when retracing my steps I discovered the – very helpful – script.mjs file. In theory Glitch is great, but when you have never used it I think it can be more confusing than helpful.
  • Note: I really like the docs from p5 because even to newbies they make it easy to dive in

Solution:

I think it would be cool to have a simple example to cover a basic but common use case already in the readme of this repository as this is where one lands when checking out buttplug-js. For example:

Quickstart

  1. Basics: There are two ways to connect to a device (supported devices):
  2. Important information:
  3. Download code: Download this index.html-file (should be linked but I posted below)
  4. Setup localhost: The browser won't allow bluetooth connections unless the website comes from a server. You can create a local server (called localhost):
  5. Start localhost: Start the folder with the index.html-file in your preferred localhost
  6. Done: You should now be able to open the website and connect to a device
  7. Tip: Check out what other people have done with buttplug
📄 index.html file (likely not perfect)
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Buttplug-JS Example</title>
        <meta charset="UTF-8" />
    </head>

    <body>
        <ul>
            <li>
                <button id="scan">Connect to a device ...</button>
                <div id="device">No device connected</div>
            </li>
        </ul>

        <ul>
            <li>
                <button id="vibrate-0">Turn off vibration</button>
            </li>
            <li>
                <button id="vibrate-50">Vibrate 50%</button>
            </li>
            <li>
                <button id="vibrate-100">Vibrate 100%</button>
            </li>
            <li>
                <button id="vibrate-20-100">Motor 1 = 20%, Motor 2 = 100% (if available)</button>
            </li>
        </ul>

        <ul>
            <li>
                <button id="rotate-0">Stop rotating</button>
            </li>
            <li>
                <button id="rotate-50-c">Rotate at 50% strength clockwise</button>
            </li>
            <li>
                <button id="rotate-100-cc">Rotate at 100% strength counter-clockwise</button>
            </li>
        </ul>

        <script type="module">
            import { ButtplugClient, ButtplugBrowserWebsocketClientConnector } from "https://cdn.jsdelivr.net/npm/buttplug@3.2.1/dist/web/buttplug.mjs"
            import { ButtplugWasmClientConnector } from "https://cdn.jsdelivr.net/npm/buttplug-wasm@2.0.1/dist/buttplug-wasm.mjs"

            let client
            let currentDevice
            initButtplug()

            document.getElementById('scan').addEventListener('click', scan)

            document.getElementById('vibrate-0').addEventListener('click', () => {
                // Turn off vibration for all motors
                currentDevice.vibrate(0)
            })
            document.getElementById('vibrate-50').addEventListener('click', () => {
                // Vibrate all motors at 50% strength
                currentDevice.vibrate(0.5)
            })
            document.getElementById('vibrate-100').addEventListener('click', () => {
                // Vibrate all motors at 100% strength
                currentDevice.vibrate(1)
            })
            document.getElementById('vibrate-20-100').addEventListener('click', () => {
                // Vibrate motor 1 with 20% strength and motor 2 with 100% strength (if the device has multiple motors)
                currentDevice.vibrate([0.2, 1])
            })

            document.getElementById('rotate-0').addEventListener('click', () => {
                // Stop rotating
                currentDevice.rotate(0, true)
            })
            document.getElementById('rotate-50-c').addEventListener('click', () => {
                // Rotate at 50% strength clockwise
                currentDevice.rotate(0.5, true)
            })
            document.getElementById('rotate-100-cc').addEventListener('click', () => {
                // Rotate at 100% strength counter-clockwise
                currentDevice.rotate(1, false)
            })
            
            async function initButtplug() {
                client = new ButtplugClient("Test Client");

                // For direct bluetooth connection
                await ButtplugWasmClientConnector.activateLogging()
                await client.connect(new ButtplugWasmClientConnector())

                // For connection to IntiFace
                let address = "ws://localhost:12345"
                let connector = new ButtplugBrowserWebsocketClientConnector(address)
                try {
                    await client.connect(connector)
                }
                catch (ex) {
                    console.log(ex)
                }

                client.addListener("deviceadded", async (device) => {
                    console.log(`Device Connected: ${device.name}`)
                    currentDevice = device
                    document.getElementById('device').innerHTML = device.name
                    // Vibrate device to show (or make you feel) it's connected
                    vibrateBriefly(currentDevice)
                })

                client.addListener("deviceremoved", async (device) => {
                    console.log('Device removed', device)
                })
            }

            async function vibrateBriefly(device) {
                await device.vibrate(0.4)
                setTimeout(() => {
                    device.vibrate(0)
                }, 200)
            }

            async function scan() {
                console.log('Start scanning')
                await client.startScanning();
            }
        </script>
    </body>
</html>

PS: It feels weirdly taboo to open an issue publicly in such a repository ... but it's also liberating 😅

@stephanbogner
Copy link
Author

Ok it might just be a discovery problem 😅 – I now found out that the glitch project has a normal URL too: how-to-buttplug-wasm.glitch.me

Glitch was also a bit confusing here because if I try the glitch project version in "Preview pane" it doesn't work (probably due to some iframe restrictions) but in a new window it works (which back then I didn't try because I thought the example is broken).

So maybe an easy enhancement would be change the link in the readme to:

▶️ Demo (Source code)

@qdot
Copy link
Member

qdot commented Jan 5, 2024

Thanks for the input!

So, yeah, you're completely correct, the repo and its demos are a mess right now. tl;dr version is: I pivoted us to a pure WASM library, that was one of the worst ideas I've ever had, so I quickly pivoted us back. Problem being, I didn't work much on that last pivot, just got the base library back in order and shoved it out. That's why everyone looks broken and half-done: because it is. :3

I'd love to have p5.js level docs, but this is basically a 2 person project and I'm the one that handles most of the non-device code as well as documentation, so I'm just out of time at the moment. That said, I'll try to at least get some of our tutorial links cleaned up soon. I also need to get other bugs like #256 fixed so what we do have left in WASM in usable. I'm just in the middle of doing a pretty major overhaul on the base rust library, so our satellite language libraries are suffering a bit for that right now.

@stephanbogner
Copy link
Author

Thanks for the context. Makes a lot of sense.

Once the overhaul is done:
If you need somebody to create a simple example or write an easy-to-understand quickstart guide – like the above draft – then feel free to reach out and I am happy to help out (I taught UX design students so I have some experience).

PS: Sad that mobile bluetooth support is so limited ... otherwise I'd have tried to find a sex toy company as a client and propose some fun/playful interfaces for their products (which would create some time on my end to contribute to the library).

@qdot
Copy link
Member

qdot commented Jan 14, 2024

The mobile bluetooth restriction from the browser is hopefully temporary, and really only an issue on iOS (android allows localhost websockets on mobile via chrome). I'm working on a way to route peer to peer locally via webrtc, just going to be a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants