Skip to content

Instantly share code, notes, and snippets.

@wanghaooo
Created February 27, 2019 06:49
Show Gist options
  • Save wanghaooo/0f3ee85a21ae2b74a52cfcf840df5337 to your computer and use it in GitHub Desktop.
Save wanghaooo/0f3ee85a21ae2b74a52cfcf840df5337 to your computer and use it in GitHub Desktop.
ZIM Polygon Pen - hahaha - for CodePen Challenge
const frame = new Frame("fit", 1024, 768, darker, dark);
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
// This feature uses Box2D for physics
// and the ZIM physics.js helper file
// As of ZIM 10, physics is integrated into ZIM and the docs
// see examples here https://zimjs.com/physics
// This app is for the CodePen Challenge on Polygons
// There is a Box2D polygon shape
// but this would not let objects inside
// and ZIM only automatically maps Triangle, Rectangle, Circle
// You can custom map the polygon with setMap() if desired
// SO... the plan is to make a Polygon with a Blob
// setting the controlType to none
// which makes straight lines from point to point.
// Then add Rectangle objects along the lines
// with physics added and join them with a weld joint.
// This means we can put things inside! (or outside)
const width = 30; // width of polygon sides
// we will put all the parts in a Container
// so we can easily remove them to change polygons
let holder = new Container(stageW, stageH).addTo();
// The number of sides can be set from 3-8 with the tab controls
let startNum = 5;
let joints; // for storing joints to remove later
// Make a physics world
// requires Box2D and ZIM physics.js helper
const physics = new Physics(0); // no gravity
// create a function to make the polygon
// because we need to change the sides
// with the tab controls later
makePoly(startNum);
function makePoly(points) {
let poly = new Blob({
points:points,
borderWidth:width,
borderColor:blue,
controlType:"none",
interactive:false
}).transformPoints("scale", 2).center(holder);
// find the distance between points
let p0 = poly.pointControls[0];
let p1 = poly.pointControls[1];
let length = dist(p0, p1);
// above is ZIM dist() function - or use
// let length = Math.sqrt((p0.x-p1.x)**2 + (p0.y-p1.y)**2);
let angle = 360 / points; // for a regular polygon
// We will loop through the control points
// but we need to know the last point
// so we can make and position lines as we go
// Controls are inside Blob so get global points
let firstPoint = p0.localToGlobal(0, 0); // where is the 0,0 globally
let lastPoint = firstPoint;
let lastRect = null;
let firstRect = null;
joints = [];
// need two points each time to make a rectangle between
// so skip the first point...
// then need to do one more after the loop
loop(poly.pointControls, (point, i)=>{
if (i==0) return; // like a continue in a for loop
let thisPoint = point.localToGlobal(0, 0);
makeRect(lastPoint, thisPoint, i);
lastPoint = point.localToGlobal(0, 0);
});
makeRect(lastPoint, firstPoint, points); // the one more
function makeRect(lastPoint, thisPoint, num) {
// find half way between this point and last point
let midPoint = new Point(
thisPoint.x+(lastPoint.x-thisPoint.x)/2, // part way between points
thisPoint.y+(lastPoint.y-thisPoint.y)/2
);
// Adjust for Blob start angle
// let rectAngle = angle*(num-3);
// works hard coded for 5 sides
// but to make it work for any points use this - yum!
// this will be 2,2,3,3,4,4 for num points from 3-8
// and then Blob always start with point0 at top
// and we must subtract half the angle on even numbers - sigh.
let rectAngle = angle*(num-Math.ceil(points/2))-(points%2==0?angle/2:0);
let rect = new Rectangle(length, width, faint) // set to color to see
.centerReg(holder)
.loc(midPoint) // passing in an object with an x and y works for loc
.rot(rectAngle)
.addPhysics();
if (!lastRect) {
firstRect = rect;
} else {
joints.push(physics.join(rect, lastRect, thisPoint));
}
lastRect = rect;
}
joints.push(physics.join(firstRect, lastRect, firstPoint));
// need to make poly follow welded rectangles
// easiest way is to weld something at registration of poly
// we don't want the circles inside to interact with this
// so set the maskBits to another bit setting (2,4,8,16,etc.)
// default is 1 for all physics shapes - but can set categoryBits to adjust
let marker = new Circle(1, clear).loc(poly, null, holder).addPhysics({maskBits:2});
joints.push(physics.join(firstRect, marker, firstPoint));
// now make poly follow and rotate based on our marker
physics.Ticker.add(()=>{
// poly.loc(marker); works until we added controls to remake poly
// then introduced a bug where when we remove poly,
// this ticker adds it again to the stage!
// so make sure the loc does not add polly with the add:false
poly.loc({x:marker.x, y:marker.y, add:false}).rot(marker.rotation);
});
// Add a bunch of circles inside - or whatever...
let colors = series(pink,green,red,orange,brown,yellow);
interval(70, obj=>{
new Circle({min:20, max:30}, colors)
.center(holder)
.addPhysics()
.impulse( // push them in different directions
rand(3,5,null,true), // negative too
rand(3,5,null,true)
);
// normally, the end count == total
// but when you start right away, the count starts at 0
// so the end count == total-1
if (obj.count == obj.total-1) {
physics.drag();
holder.cur();
}
}, 12, true); // run 12 times and start right away
} // end make physics
const controls = new Tabs({
tabs:[3,4,5,6,7,8],
width:350,
selectedBackgroundColor:green,
selectedColor:darker
})
.centerReg()
.pos(null,30,null,true)
// make poly hit interface! false is not dynamic (static)
.addPhysics(false)
.change(()=>{
// stop the drag while we add circles
physics.noDrag();
holder.cur("default");
// remove old joints and physics mappings
loop(joints, joint=>{
physics.break(joint);
})
loop(holder, child=>{
if (child.physics) { // actual Blob does not get physics
child.removePhysics();
}
});
holder.removeAllChildren();
makePoly(Number(controls.text));
});
controls.selectedIndex = startNum-3; // starting tabs at 3 poly lines
new Label({text:"ZIM - Physics Polygon with Drag", color:white}).alp(.7).pos(30,30).bot();
// DOCS FOR ITEMS USED
// https://zimjs.com/docs.html?item=Frame
// https://zimjs.com/docs.html?item=Physics
// https://zimjs.com/docs.html?item=addPhysics
// 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=Tabs
// https://zimjs.com/docs.html?item=change
// https://zimjs.com/docs.html?item=drag
// https://zimjs.com/docs.html?item=noDrag
// https://zimjs.com/docs.html?item=loop
// https://zimjs.com/docs.html?item=cur
// https://zimjs.com/docs.html?item=pos
// https://zimjs.com/docs.html?item=bot
// https://zimjs.com/docs.html?item=alp
// https://zimjs.com/docs.html?item=rot
// 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=rand
// https://zimjs.com/docs.html?item=loop
// https://zimjs.com/docs.html?item=interval
// https://zimjs.com/docs.html?item=dist
// https://zimjs.com/docs.html?item=Point
// https://zimjs.com/docs.html?item=series
// https://zimjs.com/docs.html?item=zog
// https://zimjs.com/docs.html?item=Ticker
// FOOTER
// call remote script to make ZIM Foundation for Creative Coding icon
createIcon(frame);
}); // end of ready
<script src="https://d309knd7es5f10.cloudfront.net/createjs_1.1_min.js"></script>
<script src="https://d309knd7es5f10.cloudfront.net/zim_10.js"></script>
<script src="https://d309knd7es5f10.cloudfront.net/codepen/icon3.js"></script>
<script src="https://d309knd7es5f10.cloudfront.net/Box2dWeb-2.1.a.3.min.js"></script>
<script src="https://d309knd7es5f10.cloudfront.net/physics_2.0.js"></script>

ZIM Polygon Pen - hahaha - for CodePen Challenge

Here we make a physics Polygon that pens balls inside! ZIM 10 has integrated physics that makes Box2D very easy!!! Check out https://zimjs.com/physics/

ZIM provides JavaScript conveniences, components and controls for the Canvas and is powered by CreateJS with its solid Bitmap Object Model (BOM). Code Creativity with ZIM!

A Pen by Dan Zen on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment