Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                
              
            
!

CSS

              
                
              
            
!

JS

              
                const assets = [{font:"garine", src:"Garine-First.ttf"}, "flowerdata.txt"];
const path = "https://assets.codepen.io/1604712/";
const frame = new Frame("fit", 1024, 768, blue.lighten(.5), dark, assets, path);
frame.on("ready", ()=>{ // ES6 Arrow Function - similar to function(){}
    zog("ready from ZIM Frame"); // logs in console (F12 - choose console)

    // often need below - so consider it part of the template
    let stage = frame.stage;
    let stageW = frame.width;
    let stageH = frame.height;

    // REFERENCES for ZIM at http://zimjs.com
    // see http://zimjs.com/learn.html for video and code tutorials
    // see http://zimjs.com/docs.html for documentation
    // see https://www.youtube.com/watch?v=pUjHFptXspM for INTRO to ZIM
    // see https://www.youtube.com/watch?v=v7OT0YrDWiY for INTRO to CODE

    // CODE HERE
    var neck = new Rectangle(132,200,brown.darken(.1)).loc(455, 319);
    var neckShadow = new Circle(66, brown.darken(.13)).sca(1,.85).center(neck).mov(0,-18);
    var head = new Container(stageW, stageH).reg(525, 334).center(); // adjusted the registration point to tilt at the right place

	// add a bunch of Blob objects to the head 
	// these were moved with their bezier points to make the shapes you see 
	// the data was then recorded for each one and placed in the remote js file
	
	// this was used to record points in facedata.js
    // frame.on("keydown", function (e) {
    //     if (e.keyCode == 32) {
    //         leftBotLid.recordPoints(true)
    //     }
    // })
	
	// This style will turn all the Blob Bezier points off 
	// but it is cool to set it to true (or comment it out) 
	// to see the points in action
	
    STYLE = {interactive:false};

    var wig = new Blob({
        points:wigData,
        color:black
    }).sca(1).pos(0,50,CENTER,TOP,head);
    var face = new Blob({
        color:brown,
        points:faceData
    }).loc(518,207,head).bot();    
    var leftEar = new Blob({
        color:brown.darken(.1),
        points:leftEarData
    }).loc(413, 295, head).bot();    
    var rightEar = new Blob({
        color:brown.darken(.1),
        points:rightEarData
    }).loc(623, 266, head).bot();    
    var leftCheek = new Blob({
        color:brown.darken(.03).toColor(red, .02),
        points:leftCheekData
    }).loc(453, 295, head);    
    var rightCheek = new Blob({
        color:brown.darken(.03).toColor(red, .02),
        points:rightCheekData
    }).loc(578, 293, head);   
    
    var leftSocket = new Blob({
        color:brown.darken(.1),
        points:leftSocketData
    }).loc(469, 213, head);    
    var rightSocket = new Blob({
        color:brown.darken(.1),
        points:rightSocketData
    }).loc(568, 202, head);    
    var leftWhite = new Blob({
        color:white.darken(.2),
        points:leftWhiteData
    }).loc(469, 213, head);    
    var rightWhite = new Blob({
        color:white.darken(.2),
        points:rightWhiteData
    }).loc(568, 202, head);
    
    var eyes = new Container(stageW, stageH).addTo(head)
    var leftEye = new Container(stageW, stageH).addTo(eyes)
    var rightEye = new Container(stageW, stageH).addTo(eyes)
    
    var leftBall = new Blob({
        color:green.darken(.4),
        points:leftBallData
    }).loc(469, 213, leftEye);    
    var rightBall = new Blob({
        color:green.darken(.4),
        points:rightBallData
    }).loc(568, 202, rightEye);    
    var leftPupil = new Blob({
        color:black,
        points:leftPupilData
    }).loc(469, 213, leftEye);    
    var rightPupil = new Blob({
        color:black,
        points:rightPupilData
    }).loc(568, 202, rightEye);    
    var leftTopLid = new Blob({
        color:brown.lighten(.25),
        points:leftTopLidData
    }).loc(469, 213, head);    
    var rightTopLid = new Blob({
        color:brown.lighten(.25),
        points:rightTopLidData
    }).loc(568, 202, head);    
    var leftBotLid = new Blob({
        color:brown.lighten(.1),
        points:leftBotLidData
    }).loc(469, 213, head);    
    var rightBotLid = new Blob({
        color:brown.lighten(.1),
        points:rightBotLidData
    }).loc(568, 202, head);    
    var nostrils = new Blob({
        color:brown.darken(.25),
        points:nostrilsData
    }).loc(517, 286, head);    
    var noseback = new Blob({
        color:brown.lighten(.1),
        points:noseBackData
    }).loc(517, 276, head);    
    var nose = new Blob({
        color:brown.lighten(.25),
        points:noseData
    }).loc(517, 276, head);
    var leftBrow = new Blob({
        color:black,
        points:leftBrowData
    }).loc(469, 190, head);    
    var rightBrow = new Blob({
        color:black,
        points:rightBrowData
    }).loc(568, 180, head);        
    var mouth = new Blob({
        color:brown.lighten(.2),
        points:mouthData
    }).loc(525, 355, head);        
    var tongue = new Blob({
        color:red.toColor(brown, .5).darken(.6),
        points:tongueData
    }).loc(525, 355, head);    
    var topTeeth = new Blob({
        color:white.darken(.1),
        points:topTeethData
    }).loc(525, 355, head);    
    var botTeeth = new Blob({
        color:white.darken(.1),
        points:botTeethData
    }).loc(525, 367, head);    
    var botLip = new Blob({
        color:red.toColor(brown, .5).darken(.3),
        points:botLipData
    }).loc(525, 355, head);    
    var topLip = new Blob({
        color:red.toColor(brown, .5).darken(.2),
        points:topLipData
    }).loc(525, 355, head);    
    var hedge = new Blob({
        color:green.darken(.4),
        points:hedgeData
    }).center().sca(1.1).mov(0,-10);
    
	// Here is where we wiggle the various parts
    
    head.wiggle({
		property:"rotation", 
		baseAmount:0, 
		minAmount:0, 
		maxAmount:5, 
		minTime:.5, 
		maxTime:2, 
		wait:{min:.2, max:1.5}
	});
    
	// we now wiggle the specific control points 
	// each control point of the blob has a container (control)
	// a circle (the point inside the container) 
	// and two rectangles (the handles inside the container)
	// sometimes we might rotate the complete control point 
	// sometimes we want to wiggle the handles x and y property, etc.
	
    var wigPoints = wig.pointObjects; // an array of the points
    // [[control, circle, rect1, rect2, controlType], [etc.]]
    // there are also ways (properties) to get specific items - see docs    
    // top point control - at the top of the wig - we wiggle the whole control
    var p0 = wigPoints[0][0];
    p0.wiggle("x", p0.x, 0, 10, 1, 2);
    p0.wiggle("y", p0.y, 0, 10, 1, 2);    
    // right point - we only wiggle the rect2 handle of the control
    var p1 = wigPoints[1][3];
    p1.wiggle("x", p1.x, 5, 20, .5, 1.5);
    p1.wiggle("y", p1.y, 5, 20, .5, 1.5);
    // left point - we only wiggle the rect1 handle of the control
    var p2 = wigPoints[3][2];
    p2.wiggle("x", p2.x, 5, 20, .5, 1.5);
    p2.wiggle("y", p2.y, 5, 20, .5, 1.5);
    
    // after the normal data there is:
	// totalTime, type, ease, integer, id, startType, ticker, wait
	// We just added wait at the end for this app
	// it is handy so will probably move it up in ZIM Cat 02
	// this allows us to wait some time, then wiggle quickly, wait some time, etc. 
	// before adding wait, the eyes just moved slowly from here to there 
	// if we made them move faster, they moved faster all the time - not good 
	// now with wait, we have better eye and head movement
    eyes.wiggle("x", 0, 2, 10, .2, 1, null, null, null, null, null, null, null, {min:2, max:4});
    eyes.wiggle("y", 0, 2, 5, .2, 1, null, null, null, null, null, null, null, {min:2, max:4});
    
    leftEar.wiggle("y", leftEar.y, 2, 10, 3, 5);
    rightEar.wiggle("y", rightEar.y, 2, 5, 3, 5);
    
    var facePoints = face.pointObjects;
    var p2 = facePoints[2][0];
    p2.wiggle("x", p2.x, 2, 10, 2, 5);
    p2.wiggle("y", p2.y, 2, 6, 2, 5);
    
	// Blinking - probably could have used wiggle and the new wait 
	// but had already coded the interval - that's fine.
    var ltp = leftTopLid.pointObjects;
    var ltp0 = ltp[0][2];
    var ltp0Start = ltp0.y;    
    var ltp1 = ltp[1][3];
    var ltp1Start = ltp1.y;    
    var rtp = rightTopLid.pointObjects;
    var rtp0 = rtp[0][2];
    var rtp0Start = rtp0.y;      
    var rtp1 = rtp[1][3];
    var rtp1Start = rtp1.y;    
    interval({min:3, max:8}, function () {        
        ltp0.y = 20;
        ltp1.y = 24;
        leftTopLid.update();        
        rtp0.y = 20;
        rtp1.y = 24;
        rightTopLid.update();
        timeout({min:.1, max:.15}, function () {
            ltp0.y = ltp0Start;
            ltp1.y = ltp1Start;
            leftTopLid.update();        
            rtp0.y = rtp0Start;
            rtp1.y = rtp1Start;
            rightTopLid.update();
        });
    });
    
    topLip.wiggle("scaleX", 1, 0,.12, .5,1.5)
    topLip.wiggle("y", topLip.y+2, 0,4, .5,1.5)
    botLip.wiggle("scaleX", 1, 0,.12, .5,1.5);
    
    var bl = botLip.pointObjects;
    var bl0 = bl[0][0]; 
    bl0.wiggle("rotation", -10, 2, 15, .2, .7);    
    var bl2 = bl[2][0]; 
    bl2.wiggle("rotation", 10, 2, 15, .2, .7);
    var bl2 = bl[1][0];
    bl2.wiggle("y", bl2.y+4, 1, 4, .2, .7);
    
    leftCheek.wiggle("scaleX", 1, 0, .2, 3, 5);
    rightCheek.wiggle("scaleX", 1, 0, .2, 3, 5);
    leftCheek.wiggle("scaleY", 1, 0, .2, 3, 5);
    rightCheek.wiggle("scaleY", 1, 0, .2, 3, 5);
    
    leftBrow.wiggle("y", leftBrow.y, 1, 5, 1, 3);
    rightBrow.wiggle("y", rightBrow.y, 1, 5, 1, 3);
    leftBrow.wiggle("rotation", 0, 2, 5, 3, 5);
    rightBrow.wiggle("rotation", 0, 2, 5, 3, 5);
        
    // The Blobs needs to be updated if points have been changed with code
	// do not need to update for wiggling the whole blob (like the topLip, brows, etc.)
    Ticker.add(function () {
        wig.update();
        face.update();
        botLip.update();
    });
    
	
	// Pass the words along in a Scroller
    var words = new Label("Oooh, and look, it's another FLOWER, and there is a beautiful one.  What type is that?  Oh, heavens, its a cute little one!  What a gorgeous FLOWER.  What have you got planted there?  No, that can't be, how rare!  Oh my... what's the name of that FLOWER?  Are they perennials?  Do the deer eat them?  I know that FLOWER, what's it called again?  My favourite!  Wow!", 50, "garine", white)
        .loc(10, 550).alp(.5) 
    new Scroller(words, 1.8, null, null, -12);
    
	// Turn the text list of flowers into an array with 100 items (splice returns 100 removed items)
	// Thanks http://www.gardening.cornell.edu
    var flowers = shuffle(asset("flowerdata.txt").split("\r\n")).splice(0, 100);
    var flower = new Label({text:"", size:80, font:"garine", color:white, align:CENTER}).alp(.8).centerReg().mov(0,300);
    interval({min:3, max:5}, function (obj) {
        flower.text = flowers[obj.count%100];
    }, null, true);

  
    // DOCS FOR ITEMS USED
	// https://zimjs.com/docs.html?item=Frame
	// https://zimjs.com/docs.html?item=Container
	// https://zimjs.com/docs.html?item=Circle
	// https://zimjs.com/docs.html?item=Rectangle
	// https://zimjs.com/docs.html?item=Blob
	// https://zimjs.com/docs.html?item=Label
	// https://zimjs.com/docs.html?item=wiggle
	// https://zimjs.com/docs.html?item=pos
	// https://zimjs.com/docs.html?item=loc
	// https://zimjs.com/docs.html?item=mov
	// https://zimjs.com/docs.html?item=bot
	// https://zimjs.com/docs.html?item=alp
	// https://zimjs.com/docs.html?item=reg
	// https://zimjs.com/docs.html?item=sca
	// https://zimjs.com/docs.html?item=addTo
	// https://zimjs.com/docs.html?item=centerReg
	// https://zimjs.com/docs.html?item=center
	// https://zimjs.com/docs.html?item=Scroller
	// https://zimjs.com/docs.html?item=shuffle
	// https://zimjs.com/docs.html?item=timeout
	// https://zimjs.com/docs.html?item=interval
	// https://zimjs.com/docs.html?item=lighten
	// https://zimjs.com/docs.html?item=darken
	// https://zimjs.com/docs.html?item=toColor
	// https://zimjs.com/docs.html?item=zog
	// https://zimjs.com/docs.html?item=STYLE
	// https://zimjs.com/docs.html?item=Ticker
  
    // FOOTER
    // call remote script to make ZIM icon
    createIcon(); 

}); // end of ready
              
            
!
999px

Console