You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.8 KiB
JavaScript
110 lines
3.8 KiB
JavaScript
(function() {
|
|
var map, playback, layer, dataset = 'USA-states.geojson',
|
|
previousData = { gate: 0, velocity: 0, pitch: 0 };
|
|
|
|
function init() {
|
|
WebMidi.enable(function success() {
|
|
console.log("WebMidi enabled. Available Ports:");
|
|
console.log(WebMidi.outputs);
|
|
}, function error(err) {
|
|
console.error("WebMidi could not be enabled.", err);
|
|
});
|
|
|
|
map = L.map('map', {
|
|
zoomControl: false,
|
|
boxZoom: false,
|
|
doubleClickZoom: false,
|
|
dragging: false,
|
|
keyboard: false,
|
|
scrollWheelZoom: false,
|
|
touchZoom: false,
|
|
minZoom: 2
|
|
}).addLayer(L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png', {
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="http://cartodb.com/attributions">CartoDB</a>',
|
|
subdomains: 'abcd',
|
|
maxZoom: 19
|
|
}));
|
|
|
|
playback = L.control.playback().addTo(map);
|
|
playback.on('play', function(e) { console.log(e); });
|
|
playback.on('pause', function(e) { console.log(e); });
|
|
playback.on('sequenceData', onSequenceData);
|
|
|
|
ajax(dataset, function(response, statusCode) {
|
|
if (statusCode === 200) loadGeoJSON(JSON.parse(response));
|
|
});
|
|
}
|
|
|
|
function onSequenceData(e) {
|
|
if (!WebMidi.connected || e.sequenceData.gate === null) return;
|
|
|
|
// check if an event is due. if so; send corresponding midi!
|
|
var gateDiff = e.sequenceData.gate - previousData.gate;
|
|
var pitchDiff = e.sequenceData.pitch - previousData.pitch;
|
|
previousData = e.sequenceData;
|
|
|
|
if (gateDiff > 0 || (pitchDiff && e.sequenceData.gate === 1)) // note on
|
|
WebMidi.playNote(e.sequenceData.pitch);
|
|
else if (gateDiff < 0 || (pitchDiff && e.sequenceData.gate === 0)) // note off
|
|
WebMidi.stopNote(e.sequenceData.pitch);
|
|
}
|
|
|
|
function loadGeoJSON(json) {
|
|
var sequence = { gate: [], velocity: [], pitch: [] };
|
|
|
|
if (layer) layer.removeFrom(map);
|
|
layer = L.geoJson(json, {
|
|
style: { interactive: true, weight: 1, color: '#99b'},
|
|
|
|
onEachFeature: function(feature, layer) {
|
|
if (!layer.getBounds) return;
|
|
var bounds = layer.getBounds(),
|
|
start = bounds.getWest(),
|
|
end = bounds.getEast(),
|
|
velocity = ((bounds.getNorth() + 90) / 180 * 127).toFixed(0),
|
|
pitch = ((bounds.getSouth() + 180) / 360 * 127).toFixed(0);
|
|
|
|
sequence.gate.push(start + ' cut to 1');
|
|
sequence.gate.push(end + ' cut to 0');
|
|
sequence.velocity.push(start + ' cut to ' + velocity);
|
|
sequence.velocity.push(end + ' cut to ' + velocity);
|
|
sequence.pitch.push(start + ' cut to ' + pitch);
|
|
sequence.pitch.push(end + ' cut to ' + pitch);
|
|
|
|
layer.on('click', function(e){
|
|
playback.setPlaybackPosition(start);
|
|
L.DomEvent.stopPropagation(e);
|
|
});
|
|
}
|
|
});
|
|
|
|
var layerBounds = layer.getBounds();
|
|
sequence.gate.push(layerBounds.getWest() - 1 + ' cut to 0');
|
|
sequence.gate.sort(sortSequenceData);
|
|
sequence.velocity.push(layerBounds.getWest() - 1 + ' cut to 0');
|
|
sequence.velocity.sort(sortSequenceData);
|
|
sequence.pitch.push(layerBounds.getWest() - 1 + ' cut to 0');
|
|
sequence.pitch.sort(sortSequenceData);
|
|
|
|
playback.loadSequence(sequence, layerBounds.getWest() - 1, layerBounds.getEast() + 1, 4);
|
|
map.addLayer(layer).fitBounds(layerBounds);
|
|
}
|
|
|
|
function sortSequenceData(valA, valB) {
|
|
var a = parseFloat(valA.split(' cut to ')[0]),
|
|
b = parseFloat(valB.split(' cut to ')[0]);
|
|
return a - b;
|
|
}
|
|
|
|
function ajax(url, success, method, mimetype) {
|
|
var oReq = new XMLHttpRequest();
|
|
oReq.onload = function(res) { success(res.target.response, res.target.status); };
|
|
oReq.open(method || 'get', url, true);
|
|
oReq.overrideMimeType(mimetype || 'text/plain');
|
|
oReq.send();
|
|
return oReq;
|
|
}
|
|
|
|
init();
|
|
})();
|