Skip to content

Instantly share code, notes, and snippets.

@kjirou
Created June 21, 2016 13:27
Show Gist options
  • Save kjirou/9bfe2847f1354930eacf9e0a83365397 to your computer and use it in GitHub Desktop.
Save kjirou/9bfe2847f1354930eacf9e0a83365397 to your computer and use it in GitHub Desktop.
esa記事内で動くJavaScriptアプリケーションを作る
/*
* 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