Artifact
815c303f06aeecfa7b5d6b8c28fceade38671376aaed3b0e9dabb78fe2ff5273:
<piano>
    <div class="row">
        <virtual each={ key, index in state.keys }>
            <div class="col-sm-1">
                <div class="dial" data-index={index}></div>
                <button onclick={() => play(key.freq, index)}>
                    {key.freq}
                </button>
            </div>
        </virtual>
    </div>
    <div class='piano-container'></div>
    <form>
        <fieldset>
            <legend><input type="radio" name="option-type" value="octave" checked> Octave Size</legend>
            <input type="number" min=1 max=9 id="octaveChanger" value="1">
        </fieldset>
        <fieldset class="range">
            <input type="number" min=0 max=10 id="startOctave" value="3" disabled>
            <span>to</span>
            <input type="number" min=0 max=10 id="endOctave" value="5" disabled>
        </fieldset>
        <fieldset>
            <legend>Locale</legend>
            <label>Show names: <input type="checkbox" id="names"></label>
        </fieldset>
    </form>
    <style>
        button {
            background-color: #fcfcf9;
            border: 2px solid #222;
            color: #222;
            height: 16vh;
            width: 8vw;
            border-radius: 8px;
            margin: -2px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 16px;
            font-weight: bold;
            font-size: small;
        }
        button:active {
            background-color: #f4f4e8;
        }
    </style>
    <script>
        var osc = new Tone.Oscillator({
            "type": "sine",
            "frequency": 440,
        });
        var env = new Tone.AmplitudeEnvelope({
            "curve": "linear",
            "attack": 0.2,
            "decay": 0.1,
            "sustain": 0,
            "release": 0
        }).toMaster();
        env.attackCurve = "linear";
        env.decayCurve = "linear";
        env.releaseCurve = "linear";
        osc.connect(env).start();
        export default {
            onBeforeMount(props, state) {
                // initial state
                this.state = {
                    keys: [{ "freq": 440 }, { "freq": 880 }],
                }
            },
            onMounted() {
                var dials = containerDiv.getElementsByClassName('dial');
                dials.map((e) => {
                    console.log(e)
                    var index = $(e).data('index');
                    var dial = new Nexus.Dial(e, {
                        'size': [200, 200],
                        'min': 0,
                        'max': 880,
                        'step': 1,
                        'value': 440
                    });
                    dial.off('change');
                    dial.on('change', (v) => {
                        console.log(v);
                        this.state["keys"][index]["freq"] = v;
                    })
                })
            },
            play(freq, index) {
                osc.frequency.value = freq;
                env.triggerAttackRelease();
            }
        }
    </script>
</piano>