JavaScript
语言:
JaveScriptBabelCoffeeScript
确定
(function() {
var App = function() {
this.el_svg = document.getElementById('mysvg');
this.windowWidth = window.innerWidth;
this.windowHeight = window.innerHeight;
this.svgHeight = 0;
this.svgWidth = 0;
this.svgXOffset = 0;
this.svgYOffset = 0;
this.dotsArray = [
[0.5, 0.1],
[0.6, 0.33],
[0.87, 0.37],
[0.67, 0.57],
[0.73, 0.8],
[0.5, 0.7],
[0.27, 0.8],
[0.33, 0.57],
[0.13, 0.37],
[0.4, 0.33],
[0.5, 0.1]
];
this.dotsObj = [];
this.el_originCircle = '';
this.el_destinationCircle = '';
this.originCoords = {};
this.destinationCoords = {};
this.prevPath = '';
this.el_myPath = document.getElementById('my-path');
this.currentItem = 0;
this.el_cursorCircle = '';
this.cursorDisengaged = false;
this.cursorClicked = false;
this.pathCoords = {};
this.dragging = false;
this.soundStepCounter = 0;
this.init();
}; // App
App.prototype.init = function() {
// SOUND
/*this.dragSound = new Tone.Player({
"url": "/uploads/161101/blip-01.wav"
}).toMaster();
this.stepSound = new Tone.Player({
"url": "/uploads/161101/step.wav"
}).toMaster();
this.selectSound = new Tone.Player({
"url": "/uploads/161101/select.wav"
}).toMaster();*/
this.sizeCanvas();
this.drawDots();
this.el_originCircle = this.dotsObj[0].obj;
this.el_destinationCircle = this.dotsObj[1].obj;
this.setVectorPoints(0);
this.prevPath = 'M' + this.originCoords.x + ',' + this.originCoords.y;
this.el_myPath.setAttribute('d', this.prevPath);
this.setNextPoint();
// Add the cursor-circle element
this.el_cursorCircle = this.createCircle(
this.normalizeCoord(this.dotsArray[0][0], this.svgWidth),
this.normalizeCoord(this.dotsArray[0][1], this.svgHeight),
'cursor-circle'
);
// MOUSE/TOUCH DOWN EVENT
this.el_cursorCircle.addEventListener('mousedown', this.togglePathSelection.bind(this), false);
this.el_cursorCircle.addEventListener('mouseup', this.togglePathSelection.bind(this), false);
this.el_cursorCircle.addEventListener('touchstart', this.togglePathSelection.bind(this), false);
this.el_cursorCircle.addEventListener('touchend', this.togglePathSelection.bind(this), false);
this.el_svg.addEventListener('touchstart', function(e) {
e.preventDefault();
}, false);
// MOUSE/TOUCH MOVE EVENT
this.el_svg.addEventListener('mousemove', this.dragCursor.bind(this), false);
this.el_svg.addEventListener('touchmove', this.dragCursor.bind(this), false);
};
App.prototype.soundStepForward = function() {
if (this.soundStepCounter === 5) {
this.soundStepCounter = 0;
this.stepSound.start();
return;
}
this.soundStepCounter++;
};
// Circle collision test
App.prototype.testConnection = function() {
var offset = 15;
// Match
if (this.pathCoords.x >= this.destinationCoords.x - offset &&
this.pathCoords.x <= this.destinationCoords.x + offset &&
this.pathCoords.y >= this.destinationCoords.y - offset &&
this.pathCoords.y <= this.destinationCoords.y + offset &&
this.currentItem + 1 < this.dotsArray.length) {
this.togglePathSelection();
this.cursorDisengaged = true;
this.updatePointLocation(true);
this.prevPath = this.el_myPath.getAttribute('d');
this.currentItem++;
//this.dragSound.start();
// Hide the cursor when we're done drawing the shape
if (this.currentItem + 1 === this.dotsArray.length) {
this.el_cursorCircle.classList.add('hidden');
this.el_myPath.classList.add('done');
} else {
this.dotsObj[this.currentItem].obj.classList.add('matched');
// Select next dot
this.setVectorPoints(this.currentItem);
}
this.setNextPoint();
}
};
App.prototype.updatePointLocation = function(fixed) {
var x2 = fixed ? this.destinationCoords.x : this.pathCoords.x;
var y2 = fixed ? this.destinationCoords.y : this.pathCoords.y;
var newD = this.prevPath + ' ' + x2 + ', ' + y2;
this.el_myPath.setAttribute('d', newD);
this.el_cursorCircle.setAttribute('cx', x2);
this.el_cursorCircle.setAttribute('cy', y2);
};
App.prototype.dragCursor = function(e) {
// Prevents scrolling on touch devices
e.preventDefault();
// Update path's d attribute with mouse X and Y coords
if (this.cursorClicked) {
this.dragging = true;
this.pathCoords.x = (e.offsetX || e.touches[0].clientX - this.svgXOffset);
this.pathCoords.y = (e.offsetY || e.touches[0].clientY - this.svgYOffset);
// Play sound
//this.soundStepForward();
this.updatePointLocation(false);
this.testConnection();
}
};
// Toggle path selection
App.prototype.togglePathSelection = function() {
if (!this.cursorDisengaged) {
this.cursorClicked = !this.cursorClicked;
this.el_myPath.classList.toggle('selected');
this.el_cursorCircle.classList.toggle('selected');
//this.selectSound.start();
} else {
this.cursorDisengaged = !this.cursorDisengaged;
}
};
App.prototype.sizeCanvas = function() {
// Deal with different aspect ratios
if (this.windowWidth >= this.windowHeight) {
this.svgHeight = this.windowHeight;
this.svgWidth = this.windowHeight;
} else {
this.svgHeight = this.windowWidth;
this.svgWidth = this.windowWidth;
}
// Get x and y offset of the svg element against the viewport
this.svgXOffset = (this.windowWidth - this.svgWidth) / 2;
this.svgYOffset = (this.windowHeight - this.svgHeight) / 2;
// Set svg element dimensions
this.el_svg.setAttribute('height', this.svgHeight);
this.el_svg.setAttribute('width', this.svgWidth);
this.el_svg.setAttribute('viewbox', '0 0 ' + this.svgWidth + ' ' + this.svgHeight);
};
App.prototype.createCircle = function(circleX, circleY, className) {
var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
if (className) {
circle.setAttribute("class", className);
}
circle.cx.baseVal.value = circleX;
circle.cy.baseVal.value = circleY;
circle.r.baseVal.value = 17;
return this.el_svg.appendChild(circle);
};
App.prototype.drawDots = function() {
for (var i = 0; i < this.dotsArray.length; i++) {
var newCircleX = this.normalizeCoord(this.dotsArray[i][0], this.svgWidth);
var newCircleY = this.normalizeCoord(this.dotsArray[i][1], this.svgHeight);
var circle = i === 0 ?
this.createCircle(newCircleX, newCircleY, 'origin') :
this.createCircle(newCircleX, newCircleY);
this.dotsObj.push({
x: newCircleX,
y: newCircleY,
obj: circle
});
}
};
App.prototype.normalizeCoord = function(coord, screen) {
return coord * screen;
};
App.prototype.setVectorPoints = function(index) {
var origin = this.dotsObj[index];
var destination = this.dotsObj[index + 1];
this.originCoords.x = origin.x;
this.originCoords.y = origin.y;
this.destinationCoords.x = destination.x;
this.destinationCoords.y = destination.y;
};
App.prototype.setNextPoint = function() {
this.dotsObj[this.currentItem].obj.classList.remove('next');
if (this.dotsObj[this.currentItem + 1]) {
this.dotsObj[this.currentItem + 1].obj.classList.add('next');
}
};
var app = new App();
})();