Created
June 21, 2016 13:27
-
-
Save kjirou/9bfe2847f1354930eacf9e0a83365397 to your computer and use it in GitHub Desktop.
esa記事内で動くJavaScriptアプリケーションを作る
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* esaスロットアプリ | |
* | |
* 1. 当スクリプトとスロット用の画像をコメントから添付する | |
* 2. 以下のHTMLを記事に書く | |
* | |
* <div id="esa-slot-root" /> | |
* <script | |
* id="esa-slot" | |
* src="{esaコメントへ添付した当JSスクリプトURL}" | |
* data-image-url="{esaコメントへ添付した画像URL}" | |
* data-image-width="{画像の横幅}" | |
* data-image-height="{画像の縦幅}" | |
* data-image-segment-count="{画像に含まれるコマ数、横に等幅に分割する}" | |
* ></script> | |
*/ | |
(function() { | |
var SCRIPT_ID = 'esa-slot'; | |
var DOM_NODE_ID = 'esa-slot-root'; | |
var DRUM_COUNT = 3; | |
var randomInteger = function(max) { | |
return ~~(Math.random() * (max + 1)); | |
}; | |
var scriptElement = document.getElementById(SCRIPT_ID); | |
var config = { | |
imageUrl: scriptElement.dataset.imageUrl, | |
imageWidth: ~~(scriptElement.dataset.imageWidth), | |
imageHeight: ~~(scriptElement.dataset.imageHeight), | |
imageSegmentCount: ~~(scriptElement.dataset.imageSegmentCount), | |
}; | |
var model = { | |
trialCount: 0, | |
drums: Array.from({ length: DRUM_COUNT }).map(function() { | |
return { | |
selectedSegmentImageIndex: 0 | |
}; | |
}), | |
circulateDrums: function() { | |
model.drums.forEach(function(drum) { | |
drum.selectedSegmentImageIndex = randomInteger(config.imageSegmentCount - 1); | |
}); | |
model.trialCount += 1; | |
}, | |
hasWon: function() { | |
var selectedIndex = null; | |
for (var i = 0; i < model.drums.length; i += 1) { | |
var drum = model.drums[i]; | |
if (selectedIndex !== null && drum.selectedSegmentImageIndex !== selectedIndex) { | |
return false; | |
} | |
selectedIndex = drum.selectedSegmentImageIndex; | |
} | |
return true; | |
} | |
}; | |
var calculateDrumWidth = function() { | |
return ~~(config.imageWidth / config.imageSegmentCount); | |
}; | |
var generateBackgroundPosition = function(imageSegmentIndex) { | |
var left = calculateDrumWidth() * imageSegmentIndex * -1; | |
var top = 0; | |
return String(left) + 'px ' + String(top) + 'px'; | |
}; | |
var rootElement = document.getElementById(DOM_NODE_ID); | |
rootElement.style.display = 'flex'; | |
rootElement.style.position = 'relative'; | |
rootElement.style.width = calculateDrumWidth() * DRUM_COUNT + 'px'; | |
rootElement.style.height = config.imageHeight + 'px'; | |
var drumElements = model.drums.map(function() { | |
var drumElement = document.createElement('div'); | |
drumElement.style.width = calculateDrumWidth() + 'px'; | |
drumElement.style.height = config.imageHeight + 'px'; | |
drumElement.style.backgroundImage = 'url(' + config.imageUrl + ')'; | |
drumElement.style.backgroundRepeat = 'no-repeat'; | |
drumElement.style.cursor = 'pointer'; | |
return drumElement; | |
}); | |
var render = function(model, drumElements) { | |
model.drums.forEach(function(drum, drumIndex) { | |
var drumElement = drumElements[drumIndex]; | |
drumElement.style.backgroundPosition = generateBackgroundPosition(drum.selectedSegmentImageIndex); | |
}); | |
}; | |
drumElements.forEach(function(drumElement) { | |
drumElement.addEventListener('click', function() { | |
model.circulateDrums(); | |
var hasWon = model.hasWon(); | |
render(model, drumElements); | |
if (hasWon) { | |
alert('You won!\n\nNumber of trials: ' + model.trialCount); | |
} | |
}); | |
}); | |
render(model, drumElements); | |
drumElements.forEach(function(drumElement) { | |
rootElement.appendChild(drumElement); | |
}); | |
window.__esaSlotDebug = { | |
model: model, | |
generateBackgroundPosition: generateBackgroundPosition | |
}; | |
}).call(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment