Skip to content

Commit

Permalink
Bug fixes and updates to Melody Maker experiment
Browse files Browse the repository at this point in the history
Fix for iOS tapper, updates to colors of notes, add ability to drag and draw notes, updates to grid styles, allow user to type in new tempo, use Poppins font
  • Loading branch information
bretmorris committed Feb 22, 2018
1 parent 3f9e5cd commit 4b995da
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 44 deletions.
28 changes: 20 additions & 8 deletions melodymaker/app/Main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

require(['domready', 'style/main.scss', 'grid/Grid', 'interface/Bottom', 'sound/Sequencer',
'Tone/core/Transport', 'sound/Player', 'StartAudioContext'],
function(domReady, mainStyle, Grid, Bottom, Sequencer, Transport, Player, StartAudioContext) {
Expand Down Expand Up @@ -29,19 +45,15 @@ function(domReady, mainStyle, Grid, Bottom, Sequencer, Transport, Player, StartA

//send the ready message to the parent
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
var isAndroid = /Android/.test(navigator.userAgent) && !window.MSStream;

//full screen button on iOS
if (isIOS){
if (isIOS || isAndroid){
//make a full screen element and put it in front
var iOSTapper = document.createElement("div");
iOSTapper.id = "iOSTap";
iOSTapper.addEventListener("touchstart", function(e){
e.preventDefault();
});
document.body.appendChild(iOSTapper);
StartAudioContext.setContext(Transport.context);
StartAudioContext.on(iOSTapper);
StartAudioContext.onStarted(function(){
document.body.appendChild(iOSTapper);
new StartAudioContext(Transport.context, iOSTapper).then(function() {
iOSTapper.remove();
window.parent.postMessage('ready','*');
});
Expand Down
16 changes: 8 additions & 8 deletions melodymaker/app/data/Colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,27 @@ define(function() {
'grey' : 'rgb(204, 204, 204)',
'darkGrey' : 'rgb(104, 104, 104)',
//colors
'orange' : '#FFB729',
'orange' : '#FFC234',
'lightOrange' : '#996e19',
'blue' : 'rgb(22, 168, 240)',
'lightBlue' : 'rgb(131, 211, 248)',
//keys
'C' : '#4e61d8',
'C' : '#BF4FA8',
'C#' : '#8064c6',
'Db' : '#8064c6',
'D' : '#a542b1',
'D' : '#4D61D8',
'D#' : '#ed3883',
'Eb' : '#ed3883',
'E' : '#f75839',
'F' : '#f7943d',
'E' : '#45B5A1',
'F' : '#95C631',
'F#' : '#f6be37',
'Gb' : '#f6be37',
'G' : '#d1c12e',
'G' : '#EDD929',
'G#' : '#95c631',
'Ab' : '#95c631',
'A' : '#4bb250',
'A' : '#F7943D',
'A#' : '#45b5a1',
'Bb' : '#45b5a1',
'B' : '#4598b6',
'B' : '#E33159',
};
});
60 changes: 46 additions & 14 deletions melodymaker/app/grid/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI', "tween.js"],
function(gridStyle, Config, Colors, Tile, AI, TWEEN) {

var Grid = function(container) {

this.element = document.createElement('DIV');
Expand Down Expand Up @@ -54,12 +53,22 @@ define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI',
*/
this._activeColumn = -1;

/**
* Track mouse drag events
*/
this.mouseDrag = false;
this.lastDragTile = {x: null, y: null};

this._resize();
window.addEventListener('resize', this._resize.bind(this));

//do the drawing
this.canvas.addEventListener('mousemove', this._hover.bind(this));
this.canvas.addEventListener('mousedown', this._clicked.bind(this));
this.canvas.addEventListener('mouseup', this._mouseUp.bind(this));

this.canvas.addEventListener('touchmove', this._hover.bind(this));
this.canvas.addEventListener('touchend', this._mouseUp.bind(this));
this.canvas.addEventListener('touchstart', this._clicked.bind(this));

/**
Expand Down Expand Up @@ -111,7 +120,7 @@ define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI',
this.bgContext.canvas.height = this.height;
this.tileWidth = this.width / Config.gridWidth;
this.tileHeight = this.height / Config.gridHeight;
this._drawDots();
this._drawLines();
};

Grid.prototype._tileAtPosition = function(x, y) {
Expand All @@ -122,24 +131,49 @@ define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI',
};

Grid.prototype._clicked = function(e) {
this.mouseDrag = true;

e.preventDefault();
//get the touch coord
if (e.type === 'touchstart') {
if (e.type === 'touchstart' || e.type === 'touchmove') {
for (var i = 0; i < e.changedTouches.length; i++) {
var touch = e.changedTouches[i];
var touchTilePos = this._tileAtPosition(touch.clientX, touch.clientY);
this._addTile(touchTilePos.x, touchTilePos.y);

this.lastDragTile = touchTilePos;
}
} else {
var tilePos = this._tileAtPosition(e.clientX, e.clientY);
this._addTile(tilePos.x, tilePos.y, true);

this.lastDragTile = tilePos;
}
};

Grid.prototype._mouseUp = function(e) {
e.preventDefault();

// Reset drag variables
this.mouseDrag = false;
this.lastDragTile = {x: null, y: null};
};

Grid.prototype._hover = function(e) {
var tilePos = this._tileAtPosition(e.clientX, e.clientY);
const x = e.clientX || e.touches[0].clientX;
const y = e.clientY || e.touches[0].clientY;

var tilePos = this._tileAtPosition(x, y);

//get the tile at the pos
var tile = this._tiles[tilePos.x];

// Call click event on mousedrag
if (this.mouseDrag && (tilePos.x !== this.lastDragTile.x || tilePos.y !== this.lastDragTile.y)) {
this.lastDragTile = tilePos;
this._clicked(e);
}

if (tile && !tile.isHovered()) {
if (tilePos.y === tile.y) {
this._needsUpdate = true;
Expand Down Expand Up @@ -202,7 +236,7 @@ define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI',
this.context.clearRect(0, 0, this.width, this.height);
//draw the active column
if (this._activeColumn !== -1) {
this.context.fillStyle = Colors.lighterGrey;
this.context.fillStyle = 'rgba(22, 168, 240, .08)';
this.context.fillRect(this._activeColumn * this.tileWidth, 0, this.tileWidth, this.height);
}
this._drawAI();
Expand All @@ -211,19 +245,17 @@ define(['style/grid.scss', 'data/Config', 'data/Colors', 'grid/Tile', 'grid/AI',
}
};

Grid.prototype._drawDots = function() {
Grid.prototype._drawLines = function() {
var gridWidth = Config.gridWidth;
var gridHeight = Config.gridHeight;
this.bgContext.fillStyle = Colors.lightGrey;
var radius = 4;
var twoPi = Math.PI * 2;
this.bgContext.strokeStyle = 'rgba(22, 168, 240, 0.4)';
this.bgContext.lineWidth = 1;
for (var x = 0; x < gridWidth; x++) {
for (var y = 0; y < gridHeight; y++) {
//draw a dot
for (var y = 0; y < gridHeight; y++) {
//draw tile with border
this.bgContext.beginPath();
this.bgContext.arc(x * this.tileWidth + this.tileWidth / 2, y * this.tileHeight + this.tileHeight / 2, radius, 0, 2 * Math.PI, false);
this.bgContext.fill();
}
this.bgContext.strokeRect(x * this.tileWidth, y * this.tileHeight, this.tileWidth, this.tileHeight);
}
}
};

Expand Down
8 changes: 2 additions & 6 deletions melodymaker/app/grid/Tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@ define(['data/Colors', 'data/Config'], function(Colors, Config) {
//get the note and color
var margin = tileMargin;
var note = Config.notes[this.y];
if (this.x === activeColumn) {
context.fillStyle = 'black';
} else {
context.fillStyle = Colors[note];
}
context.fillStyle = Colors[note];
context.beginPath();
context.fillRect(this.x * width + tileMargin, this.y * height + tileMargin, width - tileMargin * 2, height - tileMargin * 2);
if (this._hovered) {
if (this._hovered || this.x === activeColumn) {
context.fillStyle = 'rgba(255, 255, 255, 0.4)';
context.beginPath();
context.fillRect(this.x * width + tileMargin, this.y * height + tileMargin, width - tileMargin * 2, height - tileMargin * 2);
Expand Down
31 changes: 29 additions & 2 deletions melodymaker/app/interface/Slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
define(['./SliderBar', 'Tone/core/Transport'], function(SliderBar, Transport) {

var Slider = function(container) {
this._min = 70;
this._max = 200;

this.sliderContainer = document.createElement('div');
this.sliderContainer.id = 'SliderContainer';
container.appendChild(this.sliderContainer);

this.slider = new SliderBar(this.sliderContainer, 70, 200, Transport.bpm.value);
this.slider = new SliderBar(this.sliderContainer, this._min, this._max, Transport.bpm.value);
this.slider.onchange = this._changed.bind(this);

this.rabbit = document.createElement('div');
Expand All @@ -35,10 +37,35 @@ define(['./SliderBar', 'Tone/core/Transport'], function(SliderBar, Transport) {
this.tortoise.classList.add("icon-svg_slow_man");
this.sliderContainer.appendChild(this.tortoise);

this.input = document.createElement('input');
this.input.type = 'number';
this.input.id = 'manual-tempo';
this.input.value = this.slider.getValue();
this.input.min = 70;
this.input.max = 200;
this.input.addEventListener("input", this._onInputChange.bind(this));
this.input.addEventListener("blur", this._resetInput.bind(this));
this.sliderContainer.appendChild(this.input);
};

Slider.prototype._useMinMax = function(val) {
return val > this._max ? this._max : val < this._min ? this._min : val;
};

Slider.prototype._resetInput = function() {
var val = this.input.value;
this.input.value = this._useMinMax(val);
};

Slider.prototype._onInputChange = function() {
var val = this.input.value;
this.slider.setValue(val);
this._changed(val);
};

Slider.prototype._changed = function(tempo) {
Transport.bpm.value = tempo;
this.input.value = tempo;
Transport.bpm.value = this._useMinMax(tempo);
};

return Slider;
Expand Down
16 changes: 16 additions & 0 deletions melodymaker/app/interface/SliderBar.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

define(["style/slider.scss"], function (mainStyle) {

var Slider = function(container, min, max, initialValue){
Expand Down
4 changes: 2 additions & 2 deletions melodymaker/app/sound/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ define(['Tone/instrument/SimpleSynth', 'Tone/core/Master', 'data/Config', 'Tone/
};

Player.prototype._randomVelocity = function() {
return Math.random() * 0.5 + 0.5;
return (Math.random() * 0.5 + 0.5) * 0.8;
};

Player.prototype.tap = function(note) {
if (Transport.state === 'stopped') {
var noteIndex = Config.pitches.length - note - 1;
var pitch = Config.pitches[noteIndex];
this.melodyPlayer.triggerAttackRelease(pitch, '8t', '+0.01');
this.melodyPlayer.triggerAttackRelease(pitch, '8t', '+0.01', this._randomVelocity());
}
};

Expand Down
19 changes: 19 additions & 0 deletions melodymaker/style/bottom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#Harmony {
position: absolute;
left: $buttonMargin * 2 + $buttonSize;
background-color: #fff;
background-image: url(../images/harmony_off.png);
background-size: 100% 100%;
}
Expand Down Expand Up @@ -78,6 +79,24 @@

$iconHeight : 60px;

#manual-tempo {
background: none;
border: none;
color: $blue;
display: block;
font-size: 21px;
margin: 0;
position: absolute;
right: -93px;
text-decoration: none;
top: -4px;
width: 57px;

@media screen and (max-width: 767px) {
display: none;
}
}

#Tortoise, #Hare {
top: -20px;
position: absolute;
Expand Down
2 changes: 1 addition & 1 deletion melodymaker/style/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ $blue : rgb(22, 168, 240);
$grey : rgb(204, 204, 204);
$lightGrey : rgb(242, 242, 242);
$darkGrey : rgb(100, 100, 100);
$orange : #FFB729;
$orange : #FFC234;

$melodyGridSize : 300px;
$bottomHeight : 100px;
Expand Down
4 changes: 3 additions & 1 deletion melodymaker/style/main.scss
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
@import "common.scss";
@import url('https://fonts.googleapis.com/css?family=Poppins');

html, body {
width: 100%;
height: 100%;
position: absolute;
position: fixed;
top: 0px;
left: 0px;
margin: 0px;
overflow: hidden;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
font-family: 'Poppins', sans-serif;

#iOSTap {
width: 100%;
Expand Down
5 changes: 3 additions & 2 deletions melodymaker/style/slider.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@import "common.scss";

$sliderHeight : 20px;
$sliderHeight : 28px;

.Slider {
width: 100%;
height: $sliderHeight;
position: relative;
position: absolute;
top: -5px;
cursor: pointer;

$railHeight : 8px;
Expand Down

0 comments on commit 4b995da

Please sign in to comment.