Skip to content

Commit

Permalink
Update to Parallax class
Browse files Browse the repository at this point in the history
ZIM Build Parallax class has a new signature and now allows for using
scrollX and scrollY to control parallax (as well as any custom input).
ZIM Code received a scrollX function and a bug fix to ProportionDamp for
rounding.  ZIM Create has its centerReg() provide a center on container
second parameter to center the reg and center on stage for example.
Added a stand alone sub module for parallax.
  • Loading branch information
danzen committed Dec 9, 2015
1 parent c5c4aa6 commit 86b4fcf
Show file tree
Hide file tree
Showing 7 changed files with 707 additions and 221 deletions.
257 changes: 185 additions & 72 deletions zim.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ call the pd.immediate(baseValue) method with your desired baseValue (not targetV
METHODS
convert(input) - converts a base value to a target value
immediate(input) - immediately sets the target value (no damping)
dispose() - clears interval
PROPERTIES
damp - can adjust this dynamically (usually just pass it in as a parameter to start)
Expand Down Expand Up @@ -413,8 +414,7 @@ damp - can adjust this dynamically (usually just pass it in as a parameter to st

desiredAmount = targetAmount;
differenceAmount = desiredAmount - lastAmount;
lastAmount += differenceAmount*that.damp;
if (targetRound) {lastAmount = Math.round(lastAmount);}
lastAmount += differenceAmount*that.damp;
}

this.immediate = function(n) {
Expand All @@ -425,8 +425,12 @@ damp - can adjust this dynamically (usually just pass it in as a parameter to st
}

this.convert = function(n) {
baseAmount = n;
return lastAmount;
baseAmount = n;
if (targetRound) {
return Math.round(lastAmount);
} else {
return lastAmount;
}
}

this.dispose = function() {
Expand All @@ -436,23 +440,64 @@ damp - can adjust this dynamically (usually just pass it in as a parameter to st


// DOM CODE

/*--
zim.scrollX = function(num, time)
num and time are optional
if not provided, this gets how many pixels from the left the browser window has been scrolled
if only num is provided it scrolls the window to this x position
if num and time are provided it animates the window to the x position in time milliseconds
--*/
zim.scrollX = function(num, time) {
return zim.abstractScroll("X", "Left", num, time);
}


/*--
zim.scrollY = function()
how many pixels down from the top the browser window has been scrolled
zim.scrollY = function(num, time)
num and time are optional
if not provided, this gets how many pixels from the top the browser window has been scrolled
if only num is provided it scrolls the window to this y position
if num and time are provided it animates the window to the y position in time milliseconds
--*/
zim.scrollY = function() {
var safari = 0;
var browser=navigator.appName;
var navindex=navigator.userAgent.indexOf('Safari');
if (navindex != -1 || browser=='Safari') {
var safari = 1;
}
if (!safari && document.compatMode == 'CSS1Compat') {
return document.documentElement.scrollTop;
zim.scrollY = function(num, time) {
return zim.abstractScroll("Y", "Top", num, time);
}

zim.abstractScroll = function(dir, side, num, time) {
var perpend = (dir == "X") ? "Y" : "X"; // perpendicular direction
if (zot(num)) {
var safari = 0;
var browser=navigator.appName;
var navindex=navigator.userAgent.indexOf('Safari');
if (navindex != -1 || browser=='Safari') {
var safari = 1;
}
if (!safari && document.compatMode == 'CSS1Compat') {
return document.documentElement["scroll"+side];
} else {
return document.body["scroll"+side];
}
} else if (zot(time)) {
window.scrollTo(zim["scroll"+perpend](), num);
} else {
return document.body.scrollTop;
}
var interval = 50;
if (time < interval) time = interval;
var steps = time/interval;
var current = zim["scroll"+dir]();
var amount = num - current;
var diff = amount/steps;
var count = 0;
var scrollInterval = setInterval(function() {
count++;
current+=diff;
window.scrollTo(zim["scroll"+perpend](), current);
if (count >= steps) {
window.scrollTo(zim["scroll"+perpend](), num);
clearInterval(scrollInterval);
}
}, interval);
}
}

/*--
Expand Down Expand Up @@ -1086,12 +1131,22 @@ will not be resized - really just to use while building and then comment it out
}

/*--
zim.centerReg = function(obj)
zim.centerReg = function(obj, container)
centers the registration point on the bounds - obj must have bounds set
if container is specified then sets obj x and y to half the width and height of container
just a convenience function - returns obj for chaining
--*/
zim.centerReg = function(obj) {
if (zot(obj) || !obj.getBounds) {zog("zim create - centerReg(): please provide object with bounds set"); return;}
zim.centerReg = function(obj, container) {
if (zot(obj) || !obj.getBounds) {zog("zim create - centerReg(): please provide object with bounds set"); return;}
if (!zot(container)) {
if (!container.getBounds) {
zog("zim create - centerReg(): please provide context with bounds set");
return;
} else {
obj.x = container.getBounds().width/2;
obj.y = container.getBounds().height/2;
}
}
var oB = obj.getBounds();
obj.regX = oB.width/2;
obj.regY = oB.height/2;
Expand Down Expand Up @@ -1379,7 +1434,6 @@ if you nest things inside and want to drag them, will want to set to true
// find last angle
var angle3 = 180 - angle1 - angle2;


// the next line is b the angle will be relative to the length of c
// if c is the longest, then the angle is angle1
// if c is the second longest, then the angle is angle2, etc.
Expand Down Expand Up @@ -2619,76 +2673,123 @@ dispatches a "change" event when changed by pressing an arrow or a keyboard arro


/*--
zim.Parallax = function(stage, damp, layers)
zim.Parallax = function(stage, damp, layers, auto)
Parallax Class
takes objects and moves them with a parallax effect based on mouse movement
takes objects as layers and sets properties based on an input
for instance, each layer could move a different x based on position of mouseX
or each layer could scale a different amount based on scroll of y
The types of input are mouseX, mouseY, scrollX, scrollY
The types of properties to change could be x, y, scaleX, scaleY, rotation, alpha, frameNumber, etc.
Parallax allows scale to be a property which scales scaleX and scaleY together
Parallax allows frame to be a property and calls gotoAndStop() on a Sprite frame
Parallax really just manages multiple ProportionDamp objects
for proper parallax, the objects closer move more than the objects farther back
make a new object: p = new zim.Parallax(parameters)
PARAMETERS
pass in the stage from your code (uses stage.mouseX and stage.mouseY)
pass in a reference to the stage as the first parameter
pass in the damping value (.1 default)
pass in an array of layer objects in the following format
[[obj, distanceX, distanceY], [obj2, distanceX, distanceY], etc.]
or you can add these one at a time with the p.addLayer(obj, distanceX, distanceY); method
you must pass in a layer object - the distanceX and distanceY can be 0 for no motion on that axis
the distance is the total distance you want the layer object to travel
relative to the cursor position between 0 and stage width or height
the Parallax class will apply half the distance on either side of the object's start point
should work through nested clips...
pass in an array of layer objects in the following format:
[{obj:obj, prop:"x", propChange:100, input:"mouseX", inMin:100, inMax:300, factor:1, integer:false}, etc.]
the first three properties are required
object is the object whose property is being changed
prop is the property that is being changed
propChange is how much you want the property to change
input defaults to mouseX but can also be mouseY, scrollX, scrollY
the inMin defaults to 0, inMax to stageW (for x prop) stageH (for y prop)
the factor defaults to 1 which means change is in same direction
set factor to -1 to change in the opposite direction
integer rounds the value to an integer
note, if frame is the property, the gotoAndStop() accepts decimals
or you can add these one at a time with the p.addLayer({layer object properties});
the auto parameter defaults to true and uses the specified input
if auto is set to false, you must make your own Ticker and use the step(input) method
METHODS
addLayer(obj, distanceX, distanceY) - to alternately add layers after the object is made
addLayer({layer object properties}) - adds a layer
removeLayer(index) - removes a layer based on order added
step(input) - used when auto is false to send in custom input data
immediate([]) - immediately sets the target value for each layer object (no damping)
dispose() - removes listeners
PROPERTIES
damp - allows you to dynamically change the damping
--*/
zim.Parallax = function(stage, damp, layers) {
zim.Parallax = function(stage, damp, layers, auto) {

if (zon) zog("zim build - Parallax");

if (zot(stage) || !stage.getBounds) {zog("zim build - Parallax(): please pass in the stage with bounds as first parameter"); return;}
if (!stage.getBounds()) {zog("zim build - Pane(): Please give the stage bounds using setBounds()"); return;}

if (!stage.getBounds()) {zog("zim build - Parallax(): Please give the stage bounds using setBounds()"); return;}
if (zot(auto)) {auto = true;}

var stageW = stage.getBounds().width;
var stageH = stage.getBounds().height;

var that = this;

// public properties
this.damp = (zot(damp)) ? .1 : damp;
//this.x = (zot(damp)) ? stageW/2 : x;
//this.y = (zot(damp)) ? stageH/2 : y;

// public methods (do not get hoisted so define early)
// addLayer works as a public method
// and also is called from the object in case we add layers via the Parallax object parameters
// the function prepares ProportionDamp objects for both x and y
// the function prepares ProportionDamp objects for two values
// and stores them on the layer object
// and also stores the desired distances on the layer objects themselves
// and also stores the desired amounts on the layer objects themselves
// finally, the layer object is added to the myLayers private property
// the timer then loops through these layers and handles things from there
this.addLayer = function(obj, distanceX, distanceY) {
if (zot(obj)) return;
obj.zimX = zot(distanceX)?0:distanceX;
obj.zimY = zot(distanceY)?0:distanceY;
if (obj.zimX != 0) {
obj.zimpX = new zim.ProportionDamp(0, stageW, 0, obj.zimX, that.damp);
}
if (obj.zimY != 0) {
obj.zimpY = new zim.ProportionDamp(0, stageH, 0, obj.zimY, that.damp);
// obj, distanceX, distanceY, minX, minY, maxX, maxY, factor, targetRound
this.addLayer = function(layer) {
//{obj, prop, propChange, input, inMin, inMax, factor, integer}
if (zot(layer.obj) || zot(layer.prop) || zot(layer.propChange)) return;
var obj = {obj:layer.obj, prop:layer.prop};
obj[obj.prop] = layer.propChange;
if (zot(layer.input)) layer.input = "mouseX";
obj.input = layer.input;

var inMin = (zot(layer.inMin)) ? 0 : layer.inMin;
var inMax = (zot(layer.inMax)) ? stageW : layer.inMax;
var factor = (zot(layer.factor)) ? 1 : layer.factor;
var integer = (zot(layer.integer)) ? false : layer.integer;

// baseMin, baseMax, targetMin, targetMax, damp, factor, targetRound
obj["p_"+obj.prop] = new zim.ProportionDamp(inMin, inMax, 0, obj[obj.prop], that.damp, factor, integer);
if (obj.prop == "scale") {
obj["s_"+obj.prop] = obj.obj.scaleX; // helper to allow scale to be property
} else if (obj.prop == "frame") {
obj["s_"+obj.prop] = obj.obj.currentFrame;
} else {
obj["s_"+obj.prop] = obj.obj[obj.prop]; // obj.s_x = obj.obj.x for example
}
obj.zimsX = obj.x;
obj.zimsY = obj.y;
myLayers.push(obj);
myLayers.push(obj);
return myLayers.length-1;
}

this.removeLayer = function(index) {
if (zot(index)) return;
var layer = myLayers[index];
layer["p_"+layer.prop].dispose();
myLayers.splice(index,1);
}

this.immediate = function(array) {
var o;
for (var i=0; i<myLayers.length; i++) {
o = myLayers[i];
o["p_"+o.prop].immediate(array[i]);
}
}

this.dispose = function() {
myLayers = null;
createjs.Ticker.off("tick", ticker);
if (auto) createjs.Ticker.off("tick", ticker);
}

// private properties
Expand All @@ -2699,32 +2800,44 @@ damp - allows you to dynamically change the damping
// this will add the processed layers to the private property, myLayers
var myLayers = [];
for (var i=0; i<layers.length; i++) {
this.addLayer(layers[i][0], layers[i][1], layers[i][2]);
this.addLayer(layers[i]);
}

var ticker = createjs.Ticker.on("tick", animate);
createjs.Ticker.setFPS(60);

if (auto) {
var ticker = createjs.Ticker.on("tick", animate);
createjs.Ticker.setFPS(60);
}

// loop though our layers and apply the converted proportion damping
function animate(e) {
var o; var newX; var newY; var point;
that.step();
}

this.step = function(custom) {
var o; var input;
for (var i=0; i<myLayers.length; i++) {
o = myLayers[i];
point = o.parent.localToGlobal(o.zimsX, o.zimsY);
newX = point.x;
newY = point.y;
if (o.zimX != 0) {
newX = newX - o.zimX/2 + o.zimpX.convert(stage.mouseX);
o = myLayers[i];
if (zot(custom)) {
if (o.input == "mouseX") input = stage.mouseX;
else if (o.input == "mouseY") input = stage.mouseY;
else if (o.input == "scrollX") input = zim.scrollX();
else if (o.input == "scrollY") input = zim.scrollY();
} else {
input = custom;
}
if (o.zimY != 0) {
newY = newY - o.zimY/2 + o.zimpY.convert(stage.mouseY);
}
point = o.parent.globalToLocal(newX, newY);
o.x = point.x;
o.y = point.y;
}
// damp object at property to start value + converted goal based on input
if (o.prop == "scale") {
o.obj.scaleX = o.obj.scaleY = o["s_"+o.prop] + o["p_"+o.prop].convert(input);
} else if (o.prop == "frame") {
o.obj.gotoAndStop(o["s_"+o.prop] + o["p_"+o.prop].convert(input));
} else {
o.obj[o.prop] = o["s_"+o.prop] + o["p_"+o.prop].convert(input);
// for x on mouseX we split the destination range in two for a centered parallax
if (o.input == "mouseX") o.obj[o.prop] -= o[o.prop] / 2;
}
}
stage.update();
}
}
}


Expand Down
4 changes: 2 additions & 2 deletions zim.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 86b4fcf

Please sign in to comment.