// NOTE - we bring in ZIM Pizzazz which gives us patterns, backgrounds, and icons
// we will use patterns
import zim from "https://zimjs.org/cdn/017/zim_pizzazz";


// see https://zimjs.com
// and https://zimjs.com/learn
// and https://zimjs.com/docs

// Note the ZIM Google Fonts shortcut gf_
new Frame(FIT, 1024, 768, red.darken(.2), red.darken(.4), ready, "gf_Rokkitt");
function ready() {
   
	// given F (Frame), S (Stage), W (width), H (height)
    // put your code here

	new Label({text:"Hang ornaments...", color:white, italic:true})
		.pos(0,60,CENTER)
		.alp(.5)
		.animate({ // nice and easy animation with ZIM
			wait:2, 
			props:{alpha:0}
		}); 

	const letters = new LabelLetters(new Label("CELEBRATE", 100, "Rokkitt", white).reg(CENTER), null, null, 30) // 30 is spacing
		.pos(0,150,CENTER)
	
	// we will hang on the bottom of most letters
	// except the R and A which we adjust to hang from the middle
	letters.labels[5].reg(CENTER,30,true); 
	letters.labels[6].reg(CENTER,30,true);

	// have the letters alternate in height... but not be perfect 
	// so we use a series and each time it picks from a min and max
	const heights = series({min:20, max:40}, {min:0,max:10});
	letters.loop(letter=>{ // ZIM loop is very versatile and easy
		letter.mov(0,heights()).rot(rand(-10,10)); // short chainable methods are fun and easy
	});

	// for the balls, we will Tile the results of a function
	// here is the function
	function makeBall() {
		const c = new Circle(30,[blue,yellow,green],grey,2).reg(CENTER,-100)
		makePattern(pluck("dots","stripes","slants","bling","plaid","dots","pixels"), pluck(purple, grey, interstellar))
			.scaleTo(c,rand(100,200),rand(100,200),FILL)
			.rot(pluck(0,90,45))
			.center(c)
			.setMask(c);
		c.string = new Rectangle(2,48,light).pos(0,-48,CENTER,TOP,c).vis(false)
		new Rectangle(20,10,[light,silver],grey,1).pos(0,-8,CENTER,TOP,c)
		return c;
	}

	const balls = new Tile(makeBall, letters.labels.length, 1, 30) // obj, cols, rows, spacingH
		.pos(0,100,CENTER,BOTTOM)
		.drag({
			dropTargets:letters.labels,
			dropEnd:false // let them change their mind
		});

	let count = 0;  
	const message = new Pane("Well hung!");
	const emitter = new Emitter({startPaused:true}).center(message);
	balls.on("mousedown", e=>{
		e.target.string.vis(false);
		e.target.stopAnimate("wiggle").rot(0);
	});
	const synth = new Synth();
	balls.on("pressup", e=>{
		const ball = e.target;
		if (ball.dropTarget) {
			ball.string.vis(true);
			ball.wiggle({
				property:"rotation", 
				baseAmount:0, 
				minAmount:4, 
				maxAmount:6, 
				minTime:.3,
				maxTime:.5,
				id:"wiggle" // give id so we can turn off wiggle but leave animation back to start
			});
			// this is tricky, because we can move a counted ball to another spot
			// and we do not want to recount it
			if (!ball.counted) count++;
			ball.counted = true;
			// see https://zimjs.com/docs.html?item=Synth for the tool to make this data
			synth.play(0,...[.5,,628,.01,.09,.13,1,1.3,,,305,.09,.02,,,,.04,.51,.04]); 
			if (count>=balls.items.length) timeout(.5, ()=>{ // wait a little before showing win pane
				message.show();
				emitter.spurt(20);
				synth.play(0,.5,.05,249,.09,.29,.47,1,3.2,0,0,-187,.09,.04,0,0,0,0,.59,.22,0,0); 
			});
		} else {
			if (ball.counted) {
				count--;
				ball.counted = false;
			}
		} 
	});
	

} // end ready

// Docs for items used
// https://zimjs.com/docs.html?item=Frame
// https://zimjs.com/docs.html?item=Circle
// https://zimjs.com/docs.html?item=Rectangle
// https://zimjs.com/docs.html?item=Label
// https://zimjs.com/docs.html?item=LabelLetters
// https://zimjs.com/docs.html?item=Pane
// https://zimjs.com/docs.html?item=drag
// https://zimjs.com/docs.html?item=animate
// https://zimjs.com/docs.html?item=stopAnimate
// https://zimjs.com/docs.html?item=wiggle
// https://zimjs.com/docs.html?item=loop
// https://zimjs.com/docs.html?item=pos
// https://zimjs.com/docs.html?item=mov
// https://zimjs.com/docs.html?item=alp
// https://zimjs.com/docs.html?item=rot
// https://zimjs.com/docs.html?item=reg
// https://zimjs.com/docs.html?item=scaleTo
// https://zimjs.com/docs.html?item=center
// https://zimjs.com/docs.html?item=setMask
// https://zimjs.com/docs.html?item=Tile
// https://zimjs.com/docs.html?item=Emitter
// https://zimjs.com/docs.html?item=Synth
// https://zimjs.com/docs.html?item=timeout
// https://zimjs.com/docs.html?item=series
// https://zimjs.com/docs.html?item=darken
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.