DAN ZEN EXPO - CODE EXHIBIT -
ZIM AVATAR
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Zim Avatar</title>
<link rel="shortcut icon" type="image/ico" href="favicon.ico" />
<!-- for Google -->
<meta name="description" content="ZIM Avatar - multiple avatars - multiuser with SocketIO and NodeJS - ZIM" />
<meta name="keywords" content="zimjs, socket, socketserver, socketio, nodejs, danzen, javascript, code, free, interactive media, modules, library, html5" />
<meta name="author" content="Dan Zen" />
<meta name="copyright" content="Dan Zen" />
<!-- for Facebook -->
<meta property="og:title" content="ZIM Avatar - multiple avatars - multiuser with SocketIO and NodeJS - ZIM" />
<meta property="og:type" content="website" />
<meta property="og:image" content="http://zimjs.com/images/zim_socket.jpg" />
<meta property="og:url" content="http://zimjs.com/avatar.html" />
<meta property="og:description" content="ZIM Avatar - multiple avatars - multiuser with SocketIO and NodeJS - ZIM" />
<!-- for Twitter -->
<meta name="twitter:card" content="summary" /> <!-- do not edit this line (must say "summary") -->
<meta name="twitter:title" content="ZIM Avatar - multiple avatars - multiuser with SocketIO and NodeJS - ZIM" />
<meta name="twitter:description" content="ZIM Avatar - multiple avatars - multiuser with SocketIO and NodeJS - ZIM" />
<meta name="twitter:image" content="http://zimjs.com/images/zim_socket.jpg" />
<!-- for Apple -->
<meta name="viewport" content="width=device-width, maximum-scale=1, minimal-ui" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="apple-touch-icon-precomposed" href="images/iconS_57.png" />
<!-- for CreateJS and ZIMjs http://zimjs.com - free to modify - Dan Zen 2015 -->
<!-- see http://zimjs.com/templates for more templates and meta tags -->
<script>var zon = true; // true for comments from zim code</script>
<script src="http://d309knd7es5f10.cloudfront.net/zim_1.4.2_min.js"></script><!-- take off _min to see code -->
<script src="http://code.createjs.com/createjs-2014.12.12.min.js"></script>
<script src="http://d309knd7es5f10.cloudfront.net/zimsocket_1.0.js"></script>
<!-- or can go to zimjs.com and createjs.com for individual modules -->
<script src="https://cdn.socket.io/socket.io-1.3.4.js"></script>
<style>
body {margin:0px; padding:0px; background-color:#FFF; background-image:url("images/avatarBacking3.jpg");}
#myCanvas {position:absolute; background-color:#000;}
</style>
<script>
// SCALING OPTIONS
// "none" sets canvas and stage to dimensions and does not scale if window changes
// "fit" sets canvas and stage to dimensions and scales to fit inside window size
// "outside" sets canvas and stage to dimensions and scales to fit outside window size
// "full" sets canvas and stage to window size (canvas is actually set to screen size)
var scaling = "fit"; // full automatically sets width and height to window size
var width = 1000;
var height = 1000;
var frame = new zim.Frame(scaling, width, height);
frame.on("ready", function() {
zog("ready from ZIM Frame");
var stage = frame.stage;
var stageW = frame.width;
var stageH = frame.height;
// ZIM Avatar - 2015 Dan Zen
// uses zimsocket.js and zimserver.js at http://zimjs.com/socket.html
// SUMMARY
// client makes an avatar with two colors and joins other avatars
// these all move around and the movement is shown on everyone's screen
// STRATEGY
// each client makes their own avatar object
// and sends the properties of the object to the server
// the server keeps track of all the data
// the client receives all the initial data from the server when it joins
// the client then creates avatars for everyone else based on this data
// and stores these avatars in an avatars object based on the other client ids
// when another avatar joins the client stores this in avatars too and makes the avatar
// when a client leaves, the client sends a disconnect to the server
// the server sends this out to the remaining clients
// the remaining clients remove the avatar and update their data
// ZIM handles all the server functions for you and gives you events
// join - when you join it passes all the other clients' data as an event object
// otherjoin - when another joins it passes that client's data as an event object
// otherleave - when another leaves it passes that client's data as an event object
// data - when any client moves, it passes that client's movement data as an event object
// here we show the Socket code first followed by the interface code
// the begin function is called once the user selects the colors and presses the OKAY button
var others = {};
var colors = {grey:"#666",brown:"#d1a170",blue:"#50c4b7",purple:"#e472c4",green:"#acd241",orange:"#f58e25"}
function begin() { // called from interface button at end of section below
// set parameters for the zim.Socket object
var server = "http://54.209.193.48:3000";
var app = "zimavatar";
var room = null; // just use the default room
var maxPeople = null; // just use the default of 0 which means unlimited
var fill = null; // just use the default of fill where clients leave
// we can send an optional initial object to the server
// this information will get sent to all the other clients in an otherjoin event
var initObj = {outer:colorOuter.currentValue, inner:colorInner.currentValue, x:avatar.x, y:avatar.y};
socket = new zim.Socket(server, app, room, maxPeople, fill, initObj);
// the ready event is triggered when a client first joins
// the event object holds all the data of the others in the room
// in this case, we have one big room as the default maxPeople is unlimited (the second null above)
socket.on("ready", function(avatars) {
zog("connected");
// populate the room using the data sent from the server - something like this:
// {id:{property:value, p2:v2}, id2:{property:value, p2:v2}, etc.}
// note, the data will also hold an id so data.id would give the id too
var data;
for (var id in avatars) {
data = avatars[id];
if (data) createAvatar(id, data.outer, data.inner, data.x, data.y);
}
});
socket.on("otherjoin", function(data) {
// create an avatar for the client who joined using the data sent from the server
if (data) createAvatar(data.id, data.outer, data.inner, data.x, data.y);
});
stage.on("stagemousedown", function() {
// make our avatar move
zim.animate(avatar, {x:stage.mouseX, y:stage.mouseY}, 1000, "backOut");
// send x and y to other clients
socket.setProperties({x:stage.mouseX, y:stage.mouseY});
});
socket.on("data", function(data) {
// receiving data from other clients
// note: data will always hold an id
// but not necessarily all the client data
// for instance, in this case, we only sent x and y when moving
// so we will not have a data property for the colors
// to get a property for the colors we could use:
// socket.getSenderProperty("inner");
// or to get some other client's inner color:
// socket.getOtherProperty(clientId, "inner");
zim.move(others[data.id], data.x, data.y, 700, "backOut");
});
socket.on("otherleave", function(data) {
zim.animate(others[data.id], {scaleX:0, scaleY:0}, 700, "backIn", gone);
function gone() {
delete others[data.id];
}
});
socket.on("error", function() {
error.label.text = "connection error";
error.show();
socket.disconnect();
});
}
function createAvatar(id, outerColor, innerColor, x, y) {
var other = others[id] = new createjs.Container();
stage.addChildAt(other, 0);
var outer = new zim.Circle(120, colors[outerColor]);
other.addChild(outer);
outer.shadow = new createjs.Shadow("rgba(0,0,0,.4)", 5, 5, 10);
var inner = new zim.Circle(60, colors[innerColor]);
other.addChild(inner);
inner.alpha = .9;
other.x = x;
other.y = y;
var b = other.getBounds();
other.cache(-b.width/2,-b.height/2,b.width,b.height);
zim.scale(other, 0);
zim.animate(other, {scaleX:.4, scaleY:.4}, 700, "backOut");
}
// INTERFACE
var pane = new zim.Pane(stage, 800, 900, null, "#ddd", null, null, false, 100);
pane.show();
pane.regY -= 10;
var errorLabel = new zim.Label("please choose colors", null, null, "white");
var error = new zim.Pane(stage, 400, 100, errorLabel, "red");
zim.scale(error, 1.5);
var avatar = new createjs.Container();
avatar.x = stageW/2;
avatar.y = stageH/2 - 240;
stage.addChild(avatar);
var outer = new zim.Circle(120, "#fff");
avatar.addChild(outer);
outer.shadow = new createjs.Shadow("rgba(0,0,0,.4)", 5, 5, 10);
var inner = new zim.Circle(60, "#eee");
avatar.addChild(inner);
inner.alpha = .9;
var colorOuter = new zim.Stepper(["outer", "orange","green","purple","blue","brown","grey"], 400);
colorOuter.loop = true;
pane.addChild(colorOuter);
zim.scaleTo(colorOuter, pane, 70);
zim.centerReg(colorOuter);
var outerSwipe = new zim.Swipe(colorOuter);
outerSwipe.on("swipe", function(e) {
if (e.target.direction == "left") colorOuter.next();
if (e.target.direction == "right") colorOuter.prev();
});
var colorInner = new zim.Stepper(["inner", "grey","brown","blue","purple","green","orange"], 400);
colorInner.loop = true;
pane.addChild(colorInner);
zim.scaleTo(colorInner, pane, 70);
zim.centerReg(colorInner);
colorInner.y += 140;
var innerSwipe = new zim.Swipe(colorInner);
innerSwipe.on("swipe", function(e) {
if (e.target.direction == "left") colorInner.next();
if (e.target.direction == "right") colorInner.prev();
});
colorOuter.on("change", function(e) {
if (e.target.currentValue == "outer") outer.setFill("white");
else outer.setFill(colors[e.target.currentValue]);
stage.update();
});
colorInner.on("change", function(e) {
if (e.target.currentValue == "inner") inner.setFill("#ccc");
else inner.setFill(colors[e.target.currentValue]);
stage.update();
});
var label = new zim.Label("OKAY",null,null,"white","black");
var button = new zim.Button(200,100,label,"black","white");
pane.addChild(button);
zim.centerReg(button);
button.y = 300;
button.on("click", function() {
if (colorInner.currentValue == "inner" || colorOuter.currentValue == "outer") {
// just in case a connection error changed it
error.label.text = "please choose colors";
error.show();
return;
}
pane.hide();
var b = avatar.getBounds();
avatar.cache(-b.width/2,-b.height/2,b.width,b.height);
zim.animate(avatar, {scaleX:.4, scaleY:.4}, 700, "backOut", begin);
});
stage.update();
}); // end of ready
</script>
</head>
<body>
<!-- canvas with id="myCanvas" is made by zim Frame -->
</body>
</html>