var const_IMAGE_SIZE = 150; var IMAGE_HEIGHT = 150; var IMAGE_TOP_MARGIN = 0; var IMAGE_BOTTOM_MARGIN = 0; var SLOT_SEPARATOR_HEIGHT = 5; var SLOT_WIDTH=0; var SLOT_HEIGHT = IMAGE_HEIGHT + IMAGE_TOP_MARGIN + IMAGE_BOTTOM_MARGIN + SLOT_SEPARATOR_HEIGHT; // how many pixels one slot image takes var RUNTIME = 800; // how long all slots spin before starting countdown var SPINTIME = 800; // how long each slot spins at minimum var ITEM_COUNT = 8 // item count in slots var SLOT_SPEED = 30; // how many pixels per second slots roll var DRAW_OFFSET = 0 // how much draw offset in slot display from top var CANVAS_COUNT=4; var WIN_WIDTH=610; var PADDING=48; var BINGO=false; //3割の確率 var RANDOM=0.3; var PLAY_COUNT=1; var CHECK_COUNT=5; var answers=[0,1,2,3]; var answers_char=["1","2","3","4"]; var STATIC_URL="https://cf-special-spur.hpplus.jp/spur-special11/valentino/"; function shuffleArray( array ) { for (i = array.length - 1; i > 0; i--) { var j = parseInt(Math.random() * i) var tmp = array[i]; array[i] = array[j] array[j] = tmp; } } // Images must be preloaded before they are used to draw into canvas function preloadImages( images, callback ) { function _preload( asset ) { asset.img = new Image(); asset.img.src = STATIC_URL + asset.id+'.png'; asset.img.addEventListener("load", function() { _check(); }, false); asset.img.addEventListener("error", function(err) { _check(err, asset.id); }, false); } var loadc = 0; function _check( err, id ) { if ( err ) { alert('Failed to load ' + id ); } loadc++; if ( images.length == loadc ) return callback() } images.forEach(function(asset) { _preload( asset ); }); } function copyArray( array ) { var copy = []; for( var i = 0 ; i < array.length; i++) { copy.push( array[i] ); } return copy; } function SlotGame() { var game = new Game(); var items = [ {id: '1',color:"#000"}, {id: '2',color:"#000"}, {id: '3',color:"#000"}, {id: '4',color:"#000"}, {id: '5',color:"#fff"}, {id: '6',color:"#fff"}, {id: '7',color:"#fff"}, {id: '8',color:"#fff"} ]; $('canvas').attr('height', IMAGE_HEIGHT * ITEM_COUNT * 2); $('canvas').css('height', IMAGE_HEIGHT * ITEM_COUNT * 2); game.items = items; // load assets and predraw the reel canvases preloadImages( items, function() { // images are preloaded // draws canvas strip function _fill_canvas( canvas, items ) { ctx = canvas.getContext('2d'); for (var i = 0 ; i < ITEM_COUNT ; i++) { var asset = items[i]; console.log(asset.color); ctx.fillStyle = asset.color; ctx.fillRect(0,i * SLOT_HEIGHT,IMAGE_HEIGHT,SLOT_HEIGHT); ctx.fillRect(0,(i + ITEM_COUNT) * SLOT_HEIGHT,IMAGE_HEIGHT,SLOT_HEIGHT); ctx.save(); ctx.restore(); ctx.drawImage(asset.img,0,0,const_IMAGE_SIZE,const_IMAGE_SIZE,0,i * SLOT_HEIGHT + IMAGE_TOP_MARGIN,IMAGE_HEIGHT,IMAGE_HEIGHT); ctx.drawImage(asset.img,0,0,const_IMAGE_SIZE,const_IMAGE_SIZE,0, (i + ITEM_COUNT) * SLOT_HEIGHT + IMAGE_TOP_MARGIN,IMAGE_HEIGHT,IMAGE_HEIGHT); //ctx.save(); //ctx.restore(); //ctx.fillRect(0, i * SLOT_HEIGHT, 150, SLOT_SEPARATOR_HEIGHT); //ctx.fillRect(0, (i + ITEM_COUNT) * SLOT_HEIGHT, 150, SLOT_SEPARATOR_HEIGHT); } } function init(){ // 親画面のiframe要素 var elm = window.parent.document.getElementById("valentino_slot"); // 子要素のコンテンツサイズに合わせて調整 if(elm){ //console.log("elm.style.width",elm.style.width); if(elm.style.width){ WIN_WIDTH=parseInt(elm.style.width)-PADDING; } } $("#results").hide(); //スロットのボーダが20pxで左右paddingが10px; var containerWidth=WIN_WIDTH-25; $("#container").css({"width":WIN_WIDTH+"px"}); if(WIN_WIDTH!=610){ $("#container").css({"margin":"0"}); } IMAGE_HEIGHT=SLOT_WIDTH=containerWidth/CANVAS_COUNT-5; for(var i=1;i<=CANVAS_COUNT;i++){ $("#canvas"+i).attr("width",Math.floor(IMAGE_HEIGHT)); $("#canvas"+i).css("width",Math.floor(IMAGE_HEIGHT)); $(".slot").css("width",Math.floor(IMAGE_HEIGHT)); } SLOT_HEIGHT = IMAGE_HEIGHT + IMAGE_TOP_MARGIN + IMAGE_BOTTOM_MARGIN + SLOT_SEPARATOR_HEIGHT; $('canvas').attr('height', IMAGE_HEIGHT * ITEM_COUNT * 2); $('canvas').css('height', IMAGE_HEIGHT * ITEM_COUNT * 2); $(".slot").css("height",Math.ceil(SLOT_HEIGHT)); $('#reels').css('height',SLOT_HEIGHT); $('#results').css('height',SLOT_HEIGHT+21); $('#results').css('width',WIN_WIDTH); $('#results').css('height',SLOT_HEIGHT+21); $('#reels canvas').css('width', Math.floor(IMAGE_HEIGHT)); for(var i=1;i<=CANVAS_COUNT;i++){ game["items"+i] = copyArray(items); shuffleArray(game["items"+i]); game["items"+i][1]=items[answers[i-1]]; _fill_canvas( game["c"+i][0], game["items"+i] ); } game.resetOffset = (ITEM_COUNT + 3) * SLOT_HEIGHT; game.draw(true); game.setOffset(); MARGIN_RIGHT=((WIN_WIDTH-20)-((SLOT_WIDTH+10)*CANVAS_COUNT))/-3; $("#viewport").removeClass("ready"); elm.style.height = ($("#container").height()+30) + "px"; } game.loop(); init(); }); $('#play').on("click",function(e) { $(this).off("click"); ga('send', 'event', '内部プロモーション', 'リンク', '1710_valentino_slot', { nonInteraction: true }); $(this).addClass("disabled"); game.setAnswer(); game.restart(); }); } function Game() { // reel canvases for(var i=1;i<=CANVAS_COUNT;i++){ this["c"+i]=$('#canvas'+i); this["speed"+i]=0; } // set random canvas offsets //this.setOffset(); this.lastUpdate = new Date(); // Needed for CSS translates this.vendor = (/webkit/i).test(navigator.appVersion) ? '-webkit' : (/firefox/i).test(navigator.userAgent) ? '-moz' : (/msie/i).test(navigator.userAgent) ? 'ms' : 'opera' in window ? '-o' : ''; this.cssTransform = this.vendor + '-transform'; this.has3d = ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix()) this.trnOpen = 'translate' + (this.has3d ? '3d(' : '('); this.trnClose = this.has3d ? ',0)' : ')'; this.scaleOpen = 'scale' + (this.has3d ? '3d(' : '('); this.scaleClose = this.has3d ? ',0)' : ')'; // draw the slots to initial locations this.draw( true ); var self=this; } // Restar the game and determine the stopping locations for reels Game.prototype.restart = function() { this.lastUpdate = new Date(); this.speed1 = this.speed2 = this.speed3 = this.speed4=SLOT_SPEED // function locates id from items function _find( items, id ) { for ( var i=0; i < items.length; i++ ) { if ( items[i].id == id ) return i; } } // get random results for(var i=1;i<=CANVAS_COUNT;i++){ this["stopped"+i] = false; this["offset"+i] = -parseInt(Math.random( ITEM_COUNT )) * SLOT_HEIGHT; this["speed"+i]=SLOT_SPEED } this.state = 1; } Game.prototype.setOffset=function(){ for(var i=1;i<=CANVAS_COUNT;i++){ this["offset"+i] = -parseInt(Math.random() * ITEM_COUNT ) * SLOT_HEIGHT; } } window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ window.setTimeout(callback, 1000 / 60); }; })(); Game.prototype.loop = function() { var that = this; that.running = true; (function gameLoop() { that.update(); that.draw(); if (that.running) { requestAnimFrame( gameLoop ); } })(); } Game.prototype.update = function() { var now = new Date(); var that = this; // Check slot status and if spun long enough stop it on result function _check_slot( offset, result ) { if ( now - that.lastUpdate > SPINTIME ) { var c = parseInt(Math.abs( offset / SLOT_HEIGHT)) % ITEM_COUNT; if ( c == result ) { if ( result == 0 ) { if ( Math.abs(offset + (ITEM_COUNT * SLOT_HEIGHT)) < (SLOT_SPEED * 1.5)) { return true; // done } } else if ( Math.abs(offset + (result * SLOT_HEIGHT)) < (SLOT_SPEED * 1.5)) { return true; // done } } } return false; } switch (this.state) { case 1: // all slots spinning if (now - this.lastUpdate > RUNTIME) { this.state = 2; this.lastUpdate = now; } break; case 2: // slot 1 this.stopped1 = _check_slot( this.offset1, this.result1 ); if ( this.stopped1 ) { this.speed1 = 0; this.state++; this.lastUpdate = now; } break; case 3: // slot 1 stopped, slot 2 this.stopped2 = _check_slot( this.offset2, this.result2 ); if ( this.stopped2 ) { this.speed2 = 0; this.state++; this.lastUpdate = now; } break; case 4: // slot 2 stopped, slot 3 this.stopped3 = _check_slot( this.offset3, this.result3 ); if ( this.stopped3 ) { this.speed3 = 0; this.state++; } break; case 5: // slot 3 stopped, slot 4 this.stopped4 = _check_slot( this.offset4, this.result4 ); if ( this.stopped4 ) { this.speed4 = 0; this.state++; } break; case 6: // slots stopped if ( now - this.lastUpdate > 1000 ) { this.state = 7; var self=this; setTimeout(function(){self.showResult();},1000); } break; case 7: // check results var ec = 0; var that = this; this.state = 8; break; case 8: // game ends break; default: } this.lastupdate = now; } Game.prototype.setAnswer=function(){ PLAY_COUNT++; BINGO=true; if(PLAY_COUNT>=CHECK_COUNT){ this.setGoodAnswer(); PLAY_COUNT=1; return; } var rand=Math.random(); var tempResult=true; if(rand>RANDOM){ for(var i=1;i<=CANVAS_COUNT;i++){ var a = Math.floor( Math.random() * ((this["items"+i].length-1) + 1 - 1) ) + 1 ; this["result"+i] = parseInt(a); if(BINGO && this["items"+i][a].id!=answers_char[i-1]){ BINGO=false; } if(this["result"+i]==0){ this["result"+i]=1; } } }else{ this.setGoodAnswer(); } } Game.prototype.setGoodAnswer=function(){ for(var i=1;i<=CANVAS_COUNT;i++){ this["result"+i]=1; } BINGO=true; } Game.prototype.showResult=function(){ var self=this; if(BINGO){ $("canvas").addClass("blinking"); setTimeout(function(){ $("canvas").removeClass("blinking"); setTimeout(function(){ //$("#reels_frame").hide(); $("#con").show(); $("#nope").hide(); $("#results").show(); $("#play").removeClass("disabled"); $('#play').on("click",function(e) { $(this).off("click"); ga('send', 'event', '内部プロモーション', 'リンク', '1710_valentino_slot', { nonInteraction: true }); //$("#reels_frame").show(); $("#results").removeClass("fadeIn").addClass("fadeOut").hide(); $(this).addClass("disabled"); self.setAnswer(); self.restart(); }); },1000); },1000); }else{ $("#con").hide(); $("#nope").show(); $("#results").show(); $("#play").removeClass("disabled"); $('#play').on("click",function(e) { $(this).off("click"); ga('send', 'event', '内部プロモーション', 'リンク', '1710_valentino_slot', { nonInteraction: true }); //$("#reels_frame").show(); $("#results").removeClass("fadeIn").addClass("fadeOut").hide(); $(this).addClass("disabled"); self.setAnswer(); self.restart(); }); } //console.log("BINGO",BINGO); $("#results").removeClass("fadeOut").addClass("fadeIn"); $("#play").text("RETRY"); } Game.prototype.draw = function( force ) { if (this.state >= 7 ) return; // draw the spinning slots based on current state for (var i=1; i <= CANVAS_COUNT; i++ ) { var resultp = 'result'+i; var stopped = 'stopped'+i; var speedp = 'speed'+i; var offsetp = 'offset'+i; var cp = 'c'+i; if (this[stopped] || this[speedp] || force) { if (this[stopped]) { this[speedp] = 0; var c = this[resultp]; // get stop location this[offsetp] = -(c * SLOT_HEIGHT); if (this[offsetp] + DRAW_OFFSET > 0) { // reset back to beginning this[offsetp] = -this.resetOffset + SLOT_HEIGHT * 3; } } else { this[offsetp] += this[speedp]; if (this[offsetp] + DRAW_OFFSET > 0) { // reset back to beginning this[offsetp] = -this.resetOffset + SLOT_HEIGHT * 3 - DRAW_OFFSET; } } // translate canvas location this[cp].css(this.cssTransform, this.trnOpen + '0px, '+(this[offsetp] + DRAW_OFFSET)+'px' + this.trnClose); } } }