1var _____WB$wombat$assign$function_____=function(name){return (globalThis._wb_wombat && globalThis._wb_wombat.local_init && globalThis._wb_wombat.local_init(name))||globalThis[name];};if(!globalThis.__WB_pmw){globalThis.__WB_pmw=function(obj){this.__WB_source=obj;return this;}}{ 2let window = _____WB$wombat$assign$function_____("window"); 3let self = _____WB$wombat$assign$function_____("self"); 4let document = _____WB$wombat$assign$function_____("document"); 5let location = _____WB$wombat$assign$function_____("location"); 6let top = _____WB$wombat$assign$function_____("top"); 7let parent = _____WB$wombat$assign$function_____("parent"); 8let frames = _____WB$wombat$assign$function_____("frames"); 9let opener = _____WB$wombat$assign$function_____("opener"); 10// here is how we can bring in assets to the canvas - pass these into the Frame() 11const assets = ["https://be615c.claudeassets.com/20240613014512/https://www.lilskies.com/images/field.jpg?1", "https://b5e5ee.claudeassets.com/20240613014512/https://www.lilskies.com/images/butterfly.png?1", "https://5a1b86.claudeassets.com/20240613014512/https://www.lilskies.com/images/blue-butterfly-new.png"]; 12const path = "https://lilskies.com/images/"; 13 14// create a new Frame which makes our stage and pass in the assets 15const frame = new Frame("fit", 1024, 768, darker, dark, assets, path); 16frame.on("ready", () => { // ES6 Arrow Function - similar to function(){} 17 zog("ready from ZIM Frame"); // logs in console (F12 - choose console) 18 19 // often need below - so consider it part of the template 20 let stage = frame.stage; 21 let stageW = frame.width; 22 let stageH = frame.height; 23 24 // REFERENCES for ZIM at http://zimjs.com 25 // see http://zimjs.com/learn.html for video and code tutorials 26 // see http://zimjs.com/docs.html for documentation 27 // see https://www.youtube.com/watch?v=pUjHFptXspM for INTRO to ZIM 28 // see https://www.youtube.com/watch?v=v7OT0YrDWiY for INTRO to CODE 29 30 // CODE HERE 31 // the field is a bit bigger than the canvas (and made for 1024x768 not 800x600) 32 // so we can pan the field as the butterfly moves from one side to the other 33 // to start, we scale the field to the stage height (width is null) and center it on the stage 34 const field = frame.asset("https://eae160.claudeassets.com/20240613014512/https://www.lilskies.com/images/field.jpg?1d").scaleTo(stage, null, 0).center(); 35 36 // BUTTERFLY 37 // we make a Sprite of the butterfly 38 const butterfly = new Sprite({ 39 image: frame.asset("https://5a1b86.claudeassets.com/20240613014512/https://www.lilskies.com/images/blue-butterfly-new.png"), 40 cols: 10, rows: 4, 41 // this spritesheet has transitional animations 42 // and different directional loops due to the lighting 43 // so frames 0-9 are the loop facing left, etc. 44 animations: { left: [0, 9], leftright: [30, 39], rightleft: [20, 29], right: [10, 19] } 45 }) 46 .centerReg() 47 // make the butterfly go up and down 48 .animate({ props: { regY: 20 }, time: 1000, loop: true, rewind: true }); 49 50 // RUNNING THE SPRITE 51 // normally we just run a sprite like so: 52 // butterfly.run(500, "left"); 53 54 // but we want to run the transition animation if we change directions 55 // and we want to wait until the current loop is at its end before we run the transition 56 // so this makes it a little tricky ;-) 57 // the technique is to use the loopCall to check to see if we want to change 58 // newDir is being set in the setDirection function called by the controller "change" event 59 // when we call swapDirection it runs the sprite which automatically stops the last running of the sprite 60 // Note that we are running an animation series - so two animation objects 61 // the second of which loops forever (or until run is called again and stops it) 62 // we carefully called the animation series so that the lastDir+newDir will match the desired animation 63 // We then make sure that we kickstart the swapDir by calling it 64 65 let lastDir = "left"; 66 let newDir = "right"; 67 swapDir(); 68 function swapDir() { 69 butterfly.run({ 70 label: [ 71 { time: 400, label: lastDir + newDir }, 72 { 73 time: 500, label: newDir, loop: true, loopCall: function () { 74 if (newDir != lastDir) swapDir(); 75 } 76 } 77 ] 78 }); 79 lastDir = newDir; 80 } 81 82 function setDirection(e) { 83 if (e.dir == "right") newDir = "right"; 84 if (e.dir == "left") newDir = "left"; 85 }; 86 87 88 // CONTROLLERS 89 // most of the time we will have a single controller 90 // this example shows the types of controllers so we will store them in an array 91 // and create them in a loop as we loop through the types of controllers 92 let controllers = []; // stores the MotionController objects 93 // const controllerTypes = ["mousedown", "mousemove", "keydown", "gamebutton", "gamestick", "swipe"] 94 const controllerTypes = ["mousedown", "mousemove"] 95 let activeController; // store the active MotionController 96 97 loop(controllerTypes, function (type, i) { 98 // this is what a single controller would look like 99 // just put the type you want (see the array above) as the type property value 100 // target, type, speed, axis, boundary, map, diagonal, damp, flip, rotate, constant, firstPerson, turnSpeed, 101 // moveThreshold, stickThreshold, container, localBounds, mouseMoveOutside, mousedownIncludes, minPercentSpeed, maxPercentSpeed 102 let controller = new MotionController({ 103 target: butterfly, 104 type: type, 105 speed: 2, 106 boundary: new Boundary(butterfly.width / 2, butterfly.height / 2, stageW - butterfly.width, stageH - butterfly.height), 107 mousedownIncludes: field // to press on field if mousedown type 108 }); 109 // set the mousemove controller to the activeController 110 // and disable the rest (do not run multiple controllers at the same time) 111 if (i == 1) { 112 activeController = controller; 113 } else {
114 controller.enabled = false; 115 } 116 // the setDirection will change the animation loop of the sprite 117 controller.on("change", setDirection); 118 controllers.push(controller); 119 }); 120 121 // every once in a while, switch directions of the butterfly if we are not moving in the x 122 // we do this by setting the newDir - and then the swapDir function will handle it 123 function randomFly() { 124 timeout(rand(1000, 8000), randomFly); 125 if (!activeController.movingX) newDir = lastDir == "right" ? "left" : "right"; 126 } 127 randomFly(); 128 129 130 // TABS 131 // we set up tabs to switch between the MotionController objects 132 // move the tabs down a little on the screen and put a black backing behind 133 //const topSpace = 20; 134 //const tabHeight = 40; 135 //const backing = new Rectangle(stageW, topSpace+tabHeight).addTo(stage); 136 //const tabs = new Tabs({ 137 //width:stageW, 138 //height:tabHeight, 139 //tabs:controllerTypes, 140 //selectedBackgroundColor:brown, 141 //rollBackgroundColor:grey, 142 //backgroundColor:dark, 143 //selectedColor:dark, 144 //corner:25, 145 //inherit:{size:16} // pass along a size to Label 146 //}).pos(0, topSpace); 147 // tabs.selectedIndex = 1; 148 149 // when we change we loop through and disable the controllers 150 // we set the activeController to the tab's selectedIndex 151 // we tell the new activeController to start at where ever the butterfly is 152 // and we enable the activeController 153 //tabs.on("change", function(e) { 154 // loop(controllers, function(controller){controller.enabled = false;}); 155 //activeController = controllers[tabs.selectedIndex]; 156 // activeController.immediate(butterfly.x, butterfly.y); 157 // activeController.enabled = true; 158 //}); 159 160 161 // EXTRA 162 // we make the butterfly smaller when it is higher up (farther away) 163 // we also slow it down when it is smaller 164 // and we shift the field as we move left and right 165 // these all use ProportionDamp to map the values with damping for smoothness 166 // we set up the objects and then use their convert() method in a Ticker function 167 const proportionSize = new ProportionDamp({ 168 baseMin: 0, baseMax: stageH, 169 targetMin: .5, targetMax: 1 170 }); 171 proportionSize.immediate(butterfly.y); 172 const proportionSpeed = new ProportionDamp({ 173 baseMin: 0, baseMax: stageH, 174 targetMin: 2, targetMax: 5 175 }); 176 proportionSpeed.immediate(butterfly.y); 177 const proportionField = new ProportionDamp({ 178 baseMin: 0, baseMax: stageW, 179 targetMin: 0, targetMax: -(field.width - stageW) 180 }); 181 proportionField.immediate(butterfly.x); 182 183 Ticker.add(() => { 184 butterfly.sca(proportionSize.convert(butterfly.y)); 185 activeController.speed = proportionSpeed.convert(butterfly.y); 186 field.x = proportionField.convert(butterfly.x); 187 }); 188 189 190 stage.update(); // this is needed to show any changes 191 192 // DOCS FOR ITEMS USED 193 // https://zimjs.com/docs.html?item=Frame 194 // https://zimjs.com/docs.html?item=Sprite 195 // https://zimjs.com/docs.html?item=Rectangle 196 // https://zimjs.com/docs.html?item=Tabs 197 // https://zimjs.com/docs.html?item=animate 198 // https://zimjs.com/docs.html?item=loop 199 // https://zimjs.com/docs.html?item=pos 200 // https://zimjs.com/docs.html?item=sca 201 // https://zimjs.com/docs.html?item=scaleTo 202 // https://zimjs.com/docs.html?item=addTo 203 // https://zimjs.com/docs.html?item=centerReg 204 // https://zimjs.com/docs.html?item=center 205 // https://zimjs.com/docs.html?item=MotionController 206 // https://zimjs.com/docs.html?item=loop 207 // https://zimjs.com/docs.html?item=timeout 208 // https://zimjs.com/docs.html?item=Boundary 209 // https://zimjs.com/docs.html?item=ProportionDamp 210 // https://zimjs.com/docs.html?item=zog 211 // https://zimjs.com/docs.html?item=Ticker 212 213 // FOOTER 214 // call remote script to make ZIM Foundation for Creative Coding icon 215 //createIcon(frame, 780, 600); 216 217}); // end of ready 218 219 220} 221 222/* 223 FILE ARCHIVED ON 22:37:51 Apr 18, 2023 AND RETRIEVED FROM THE 224 INTERNET ARCHIVE ON 08:52:43 Sep 09, 2026. 225 JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. 226 227 ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. 228 SECTION 108(a)(3)). 229*/ 230/* 231playback timings (ms): 232 captures_list: 0.392 233 exclusion.robots: 0.037 234 exclusion.robots.policy: 0.029 235 esindex: 0.006 236 cdx.remote: 13.807 237 LoadShardBlock: 110.764 (3) 238 PetaboxLoader3.datanode: 99.203 (4) 239 PetaboxLoader3.resolve: 78.669 (2) 240 load_resource: 95.639 241*/
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.