window.define(['pipAPI'], function(APIconstructor) { var API = new APIconstructor(); API.addGlobal({ j: 0 }); var global = API.getGlobal(); global.j = 0; // Set index to 0 API.addGlobal({ col1Tracker: 0 }); global.col1Tracker = 0; // Set index to 0 API.addGlobal({ col2Tracker: 0 }); global.col2Tracker = 0; // Set index to 0 // Define canvas API.addSettings('canvas',{ maxWidth: 1000, proportions : 0.6, background: 'white', canvasBackground: 'white', borderWidth: 4, borderColor: 'black' }); API.addSettings('base_url','/implicit/user/bkurdi/successor1/images'); // Define path to images API.addMediaSets('col1a', [{image: API.getGlobal().colors[0][0]+'1.png'}]); API.addMediaSets('col1b', [{image: API.getGlobal().colors[0][0]+'2.png'}]); API.addMediaSets('col1c', [{image: API.getGlobal().colors[0][0]+'3.png'}]); API.addMediaSets('col1d', [{image: API.getGlobal().colors[0][0]+'4.png'}]); API.addMediaSets('col1e', [{image: API.getGlobal().colors[0][0]+'5.png'}]); API.addMediaSets('col2a', [{image: API.getGlobal().colors[1][0]+'1.png'}]); API.addMediaSets('col2b', [{image: API.getGlobal().colors[1][0]+'2.png'}]); API.addMediaSets('col2c', [{image: API.getGlobal().colors[1][0]+'3.png'}]); API.addMediaSets('col2d', [{image: API.getGlobal().colors[1][0]+'4.png'}]); API.addMediaSets('col2e', [{image: API.getGlobal().colors[1][0]+'5.png'}]); API.addMediaSets('reward1a', [{image: API.getGlobal().rewards[0][0]+'.png'}]); API.addMediaSets('reward1b', [{image: API.getGlobal().rewards[0][1]+'.png'}]); API.addMediaSets('reward1c', [{image: API.getGlobal().rewards[0][2]+'.png'}]); API.addMediaSets('reward1d', [{image: API.getGlobal().rewards[0][3]+'.png'}]); API.addMediaSets('reward1e', [{image: API.getGlobal().rewards[0][4]+'.png'}]); API.addMediaSets('reward2a', [{image: API.getGlobal().rewards[1][0]+'.png'}]); API.addMediaSets('reward2b', [{image: API.getGlobal().rewards[1][1]+'.png'}]); API.addMediaSets('reward2c', [{image: API.getGlobal().rewards[1][2]+'.png'}]); API.addMediaSets('reward2d', [{image: API.getGlobal().rewards[1][3]+'.png'}]); API.addMediaSets('reward2e', [{image: API.getGlobal().rewards[1][4]+'.png'}]); API.addMediaSets('col1', [ {inherit: 'col1a'}, {inherit: 'col1b'}, {inherit: 'col1c'}, {inherit: 'col1d'}, {inherit: 'col1e'} ]); API.addMediaSets('col2', [ {inherit: 'col2a'}, {inherit: 'col2b'}, {inherit: 'col2c'}, {inherit: 'col2d'}, {inherit: 'col2e'} ]); API.addStimulusSets("col1Left", [ {data: {type:'col1Left'}, location: {left:10}, media: {inherit: {set:'col1', type:'exRandom', seed:'col1LeftSeed'}} }]); API.addStimulusSets("col1LeftTop", [ {data: {type:'col1LeftTop'}, media: {inherit: {set:'col1', type:'exRandom', seed:'col1LeftSeed', repeat: true}}, size: {height:15}, location: {top:2} }]); API.addStimulusSets("col1Right", [ {data: {type:'col1Right'}, location: {right:10}, media: {inherit: {set:'col1', type:'exRandom', seed:'col1RightSeed'}} }]); API.addStimulusSets("col1RightTop", [ {data: {type:'col1RightTop'}, media: {inherit: {set:'col1', type:'exRandom', seed:'col1RightSeed', repeat: true}}, size: {height:15}, location: {top:2} }]); API.addStimulusSets("col2Left", [ {data: {type:'col2Left'}, location: {left:10}, media: {inherit: {set:'col2', type:'exRandom', seed:'col2LeftSeed'}} }]); API.addStimulusSets("col2LeftTop", [ {data: {type:'col2LeftTop'}, media: {inherit: {set:'col2', type:'exRandom', seed:'col2LeftSeed', repeat: true}}, size: {height:15}, location: {top:2} }]); API.addStimulusSets("col2Right", [ {data: {type:'col2Right'}, location: {right:10}, media: {inherit: {set:'col2', type:'exRandom', seed:'col2RightSeed'}} }]); API.addStimulusSets("col2RightTop", [ {data: {type:'col2RightTop'}, media: {inherit: {set:'col2', type:'exRandom', seed:'col2RightSeed', repeat: true}}, size: {height:15}, location: {top:2} }]); API.addMediaSets('reward1', [ {inherit: 'reward1a'}, {inherit: 'reward1b'}, {inherit: 'reward1c'}, {inherit: 'reward1d'}, {inherit: 'reward1e'} ]); API.addMediaSets('reward2', [ {inherit: 'reward2a'}, {inherit: 'reward2b'}, {inherit: 'reward2c'}, {inherit: 'reward2d'}, {inherit: 'reward2e'} ]); API.addMediaSets('machine1', [{image: 'machine_'+API.getGlobal().colors[0][0]+'.png'}]); API.addMediaSets('machine2', [{image: 'machine_'+API.getGlobal().colors[1][0]+'.png'}]); // Layout elements API.addStimulusSets('machine1', [ {media: {image:'machine_'+API.getGlobal().colors[0][0]+'.png'}, size: {height:75}, css:{zIndex:1000}} ]); API.addStimulusSets('machine2', [ {media: {image:'machine_'+API.getGlobal().colors[1][0]+'.png'}, size: {height:75}, css:{zIndex:1000}} ]); // Reminder elements API.addStimulusSets("leftReminder", [ {data: {type:'leftReminder'}, location: {left:2, top:2}, displayed:false, media:{word: 'Press "E" for left'}, css:{'font-size':'1.2em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("rightReminder", [ {data: {type:'rightReminder'}, location: {right:2, top:2}, displayed:false, media:{word: 'Press "I" for right'}, css:{'font-size':'1.2em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("goalReminder", [ {data: {type:'goalReminder'}, location: {top:6}, displayed:true, media:{word: 'Keep food and drink levels high'}, css:{'font-size':'1.2em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("endReminder", [ {data: {type:'endReminder'}, location: {bottom:2}, displayed:true, media:{word: 'Press space to continue'}, css:{'font-size':'1.5em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("roundReminder", [ {data: {type:'roundReminder'}, displayed:true, media:{word: "Choice <%= global.j %> of 20"}, css:{'font-size':'4em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("col1LevelReminder", [ {data: {type:'col1LevelReminder'}, location: {left:2, top:6}, displayed:false, media:{word: API.getGlobal().rewardLabels[0]+" level: <%= global.col1Tracker %>"}, css:{'font-size':'1.2em', 'font-family':'courier', color:'#000000'} }]); API.addStimulusSets("col2LevelReminder", [ {data: {type:'col2LevelReminder'}, location: {right:2, top:6}, displayed:false, media:{word: API.getGlobal().rewardLabels[1]+" level: <%= global.col1Tracker %>"}, css:{'font-size':'1.2em', 'font-family':'courier', color:'#000000'} }]); // Trials API.addTrialSets('trial1', [ { input: [{handle:'commence',on:'space'}], layout: [], stimuli: [ {inherit:'col1RightTop'}, {inherit:'col2LeftTop'}, { handle:'second1', media: {inherit:'reward1'}, size: {height:20}, location: {top:50,left:57.5} }, { handle:'second2', media: {inherit:'reward2'}, size: {height:20}, location: {top:50,left:57.5} }, {inherit:'endReminder'}, {inherit:'machine1'}, {inherit:'machine2'}, {inherit:'roundReminder'}, {inherit:'leftReminder'}, {inherit:'rightReminder'}, {inherit:'goalReminder'}, {inherit:'col1LevelReminder'}, {inherit:'col2LevelReminder'}, {inherit:'col2Left'}, {inherit:'col1Right'} ], interactions: [ {conditions: [{type:'begin'}], actions: [{type: 'showStim',handle:'roundReminder'},{type: 'showStim',handle:'endReminder'}] }, { conditions: [{type: 'inputEquals', value:'commence'}], actions: [ {type:'hideStim', handle:'roundReminder'}, {type:'setStimAttr', handle:'roundReminder', setter:{displayed:false}}, {type:'hideStim', handle:'endReminder'}, {type: 'showStim',handle:'col2Left'}, {type: 'showStim', handle:'col1Right'}, {type:'resetTimer'}, {type: 'showStim',handle:'leftReminder'}, {type: 'showStim',handle:'rightReminder'}, {type: 'showStim',handle:'col1LevelReminder'}, {type: 'showStim',handle:'col2LevelReminder'}, {type: 'showStim',handle:'goalReminder'}, {type: 'setInput', input:{handle:'col2E',on:'keypressed', key:'e'}}, {type: 'setInput', input:{handle:'col1I',on:'keypressed', key:'i'}}, {type:'log'}, {type: 'removeInput', handle:'commence'}] }, { conditions: [{type:'inputEquals',value:'col1I'}], actions: [ {type:'hideStim',handle:'col2Left'}, {type:'hideStim', handle:'col1Right'}, {type:'hideStim', handle:'endReminder'}, {type: 'hideStim',handle:'leftReminder'}, {type: 'hideStim',handle:'rightReminder'}, {type: 'hideStim',handle:'goalReminder'}, {type:'showStim', handle:'machine1'}, {type:'showStim', handle:'col1RightTop'}, {type:'custom', fn: function(){ animate('[data-handle="col1RightTop"]', {duration: 3000, topShift: 0.2}); }}, {type:'custom', fn: function(trialobject, globalObject){ globalObject.col1Tracker = globalObject.col1Tracker + 10; }}, {type:'setInput', input:{handle:'col1ObjectIn',on:'timeout',duration:3000}}, {type: 'removeInput', handle:'commence'} ] }, { conditions: [{type:'inputEquals',value:'col1ObjectIn'}], actions: [ {type:'showStim', handle:'second1'}, {type:'custom', fn: function(){ animate('[data-handle="second1"]', {duration: 2500, leftShift: 0.25}); }}, {type:'setInput', input:{handle:'machineOff',on:'timeout',duration:5000}} ] }, { conditions: [{type:'inputEquals',value:'col2E'}], actions: [ {type:'hideStim',handle:'col2Left'}, {type:'hideStim', handle:'col1Right'}, {type:'hideStim', handle:'endReminder'}, {type: 'hideStim',handle:'leftReminder'}, {type: 'hideStim',handle:'rightReminder'}, {type: 'hideStim',handle:'goalReminder'}, {type:'showStim', handle:'machine2'}, {type:'showStim', handle:'col2LeftTop'}, {type:'custom', fn: function(){ animate('[data-handle="col2LeftTop"]', {duration: 3000, topShift: 0.2}); }}, {type:'custom', fn: function(trialobject, globalObject){ globalObject.col2Tracker = globalObject.col2Tracker + 10; }}, {type:'setInput', input:{handle:'col2ObjectIn',on:'timeout',duration:3000}}, {type: 'removeInput', handle:'commence'} ] }, { conditions: [{type:'inputEquals',value:'col2ObjectIn'}], actions: [ {type:'showStim', handle:'second2'}, {type:'custom', fn: function(){ animate('[data-handle="second2"]', {duration: 2500, leftShift: 0.25}); }}, {type:'setInput', input:{handle:'machineOff',on:'timeout',duration:5000}} ] }, { conditions: [{type:'inputEquals',value:'machineOff'}], actions: [ {type:'endTrial'} ] } ], customize: function(trialobject, globalObject) { globalObject.j = globalObject.j + 1; } } ]); API.addTrialSets('trial2', [ { input: [{handle:'commence',on:'space'}], layout: [], stimuli: [ {inherit:'col1LeftTop'}, {inherit:'col2RightTop'}, { handle:'second1', media: {inherit:'reward1'}, size: {height:20}, location: {top:50,left:57.5} }, { handle:'second2', media: {inherit:'reward2'}, size: {height:20}, location: {top:50,left:57.5} }, {inherit:'endReminder'}, {inherit:'machine1'}, {inherit:'machine2'}, {inherit:'roundReminder'}, {inherit:'leftReminder'}, {inherit:'rightReminder'}, {inherit:'goalReminder'}, {inherit:'col1LevelReminder'}, {inherit:'col2LevelReminder'}, {inherit:'col1Left'}, {inherit:'col2Right'} ], interactions: [ {conditions: [{type:'begin'}], actions: [{type: 'showStim',handle:'roundReminder'},{type: 'showStim',handle:'endReminder'}] }, { conditions: [{type: 'inputEquals', value:'commence'}], actions: [ {type:'hideStim', handle:'roundReminder'}, {type:'setStimAttr', handle:'roundReminder', setter:{displayed:false}}, {type:'hideStim', handle:'endReminder'}, {type: 'showStim',handle:'col1Left'}, {type: 'showStim', handle:'col2Right'}, {type:'resetTimer'}, {type: 'showStim',handle:'leftReminder'}, {type: 'showStim',handle:'rightReminder'}, {type: 'showStim',handle:'col1LevelReminder'}, {type: 'showStim',handle:'col2LevelReminder'}, {type: 'showStim',handle:'goalReminder'}, {type: 'setInput', input:{handle:'col1E',on:'keypressed', key:'e'}}, {type: 'setInput', input:{handle:'col2I',on:'keypressed', key:'i'}}, {type:'log'}, {type: 'removeInput', handle:'commence'} ] }, { conditions: [{type:'inputEquals',value:'col1E'}], actions: [ {type:'hideStim',handle:'col1Left'}, {type:'hideStim', handle:'col2Right'}, {type:'hideStim', handle:'endReminder'}, {type: 'hideStim',handle:'leftReminder'}, {type: 'hideStim',handle:'rightReminder'}, {type: 'hideStim',handle:'goalReminder'}, {type:'showStim', handle:'machine1'}, {type:'showStim', handle:'col1LeftTop'}, {type:'custom', fn: function(){ animate('[data-handle="col1LeftTop"]', {duration: 3000, topShift: 0.2}); }}, {type:'custom', fn: function(trialobject, globalObject){ globalObject.col1Tracker = globalObject.col1Tracker + 10; }}, {type:'setInput', input:{handle:'col1ObjectIn',on:'timeout',duration:3000}}, {type: 'removeInput', handle:'commence'} ] }, { conditions: [{type:'inputEquals',value:'col1ObjectIn'}], actions: [ {type:'showStim', handle:'second1'}, {type:'custom', fn: function(){ animate('[data-handle="second1"]', {duration: 2500, leftShift: 0.25}); }}, {type:'setInput', input:{handle:'machineOff',on:'timeout',duration:5000}} ] }, { conditions: [{type:'inputEquals',value:'col2I'}], actions: [ {type:'hideStim',handle:'col1Left'}, {type:'hideStim', handle:'col2Right'}, {type:'hideStim', handle:'endReminder'}, {type: 'hideStim',handle:'leftReminder'}, {type: 'hideStim',handle:'rightReminder'}, {type: 'hideStim',handle:'goalReminder'}, {type:'showStim', handle:'machine2'}, {type:'showStim', handle:'col2RightTop'}, {type:'custom', fn: function(){ animate('[data-handle="col2RightTop"]', {duration: 3000, topShift: 0.2}); }}, {type:'custom', fn: function(trialobject, globalObject){ globalObject.col2Tracker = globalObject.col2Tracker + 10; }}, {type:'setInput', input:{handle:'col2ObjectIn',on:'timeout',duration:3000}}, {type: 'removeInput', handle:'commence'} ] }, { conditions: [{type:'inputEquals',value:'col2ObjectIn'}], actions: [ {type:'showStim', handle:'second2'}, {type:'custom', fn: function(){ animate('[data-handle="second2"]', {duration: 2500, leftShift: 0.25}); }}, {type:'setInput', input:{handle:'machineOff',on:'timeout',duration:5000}} ] }, { conditions: [{type:'inputEquals',value:'machineOff'}], actions: [ {type:'endTrial'} ] } ], customize: function(trialobject, globalObject) { globalObject.j = globalObject.j + 1; } } ]); // Repeat trial for the number of rounds API.addSequence([ {mixer: 'random', data: [ {mixer: 'repeat', times: 10, data: [{inherit: 'trial1'}] }, {mixer: 'repeat', times: 10, data: [{inherit: 'trial2'}] } ]} ]); return API.script; function wait(ms){ var d = new Date(); var d2 = null; do { d2 = new Date(); } while(d2-d < ms); } function animate(selector, opts){ // wrap in set timeout to let all element sizes settle (probably) // prevents sometime when the image locations are skewed setTimeout(function(){ var canvasSize = document.getElementById('canvas').getBoundingClientRect(); var el = document.querySelector(selector); var leftStart = el.offsetLeft; var topStart = el.offsetTop; var startTime = performance.now(); var duration = opts.duration; loop(); function loop(){ var delta = performance.now() - startTime; opts.leftShift && (el.style.left = (leftStart + opts.leftShift * canvasSize.width * Math.min(duration, delta)/duration) + 'px'); opts.topShift && (el.style.top = (topStart + opts.topShift * canvasSize.height * Math.min(duration, delta)/duration) + 'px'); if (delta < duration) requestAnimationFrame(loop); } }, 5); } });