How should multiple progress bars be handled in javascript - javascript

I have a number of progress bars each tied to a div which are updated using 'setTimeouts'.
An example of how it runs is like this :
myDiv._timer = setTimeout(function () {
func_name(data)
}, 1);
Edit: As requested a working example of my one progress bar: http://jsfiddle.net/H4SCr/
The question however is, I have multiple div's with progression bars with their own data to use to calculate progression. Which means with say 5 on the go i have 5 different timeouts running.
I'm no expert in javascript, but surely theres a way to structure this to tie to just one time out for all progress bars, or is my current approach the best method ?
Note: i don't use jQuery. I prefer to go with just vanilla javascript to learn!

Check this out:
http://jsfiddle.net/MZc8X/11/
I created an array of objects which contains the container id and its increment value.
// array to maintain progress bars
var pbArr = [{
pid: 'bar1', // parent container id
incr: 1 // increment value
}, {
pid: 'bar2',
incr: 2
}, {
pid: 'bar3',
incr: 3
}, {
pid: 'bar4',
incr: 4
}, {
pid: 'bar5',
incr: 5
}];
And, then call a function to create a progress bar...
var loopCnt = 1; // loop count to maintain width
var pb_timeout; // progress bar timeout function
// create progress bar function
var createPB = function () {
var is_all_pb_complete = true; // flag to check whether all progress bar are completed executed
for (var i = 0; i < pbArr.length; i++) {
var childDiv = document.querySelector('#' + pbArr[i].pid + ' div'); // child div
var newWidth = loopCnt * pbArr[i].incr; // new width
if (newWidth <= 100) {
is_all_pb_complete = false;
childDiv.style.width = newWidth + '%';
} else {
childDiv.style.width = '100%';
}
}
if (is_all_pb_complete) { // if true, then clear timeout
clearTimeout(pb_timeout);
return;
}
loopCnt++; // increment loop count
// recall function
pb_timeout = setTimeout(function () {
createPB();
}, 1000);
}
// call function to initiate progress bars
createPB();
Hope, it works for you.

Related

How do I have setinterval help me dynamically update multiple progress bars with a for loop?

I'm trying to update multiple progress bars at once on a Django template, but what I find is that it only updates that last one. I'm not sure why the for loop here isn't working. Can anyone provide any guidance. Thank you in advance.
I pull in the values that I need from the HTML into objects. From there I use a for loop to adjust the width of the progress bar dynamically, but it's only responding to the last div to go through the for loop.
var a = 0;
var counts = []
// Nestling relevant values in objects for for loop
var five = {
bar: document.getElementById("fivesBar"),
quantity: $("#fivesGiven").text()
}
var four = {
bar: document.getElementById("foursBar"),
quantity: $("#foursGiven").text()
}
var three = {
bar: document.getElementById("threesBar"),
quantity: $("#threesGiven").text()
}
var two = {
bar: document.getElementById("twosBar"),
quantity: $("#twosGiven").text()
}
var one = {
bar: document.getElementById("onesBar"),
quantity: $("#onesGiven").text()
}
counts.push(one, two, three, four, five);
console.log("Checking the list for counts:", counts);
// Grabbing percent complete to dynamically complete the progress bar
$(document).ready(function () {
for (b = 0; b < counts.length; b++) {
quantity = counts[b].quantity;
console.log(quantity);
quantity = parseInt(quantity)
bar = counts[b].bar;
if (a === 0) {
var width = 0;
var run = setInterval(fillratings, 5);
function fillratings() {
if (width === quantity) {
clearInterval(run);
a = 0;
} else {
width++;
bar.style.width = width + "%";
console.log(width);
}
}
}
}
});

JavaScript game switchable sprites

Any ideas how to make switchable characters I have a html game it's finished but I want to implement a way to switch my main character.
Simple coding using Phaser framework
upload function() {
this.game.load.sprite ("bird" assets/bird.png);
this.game.load.sprite ("bird2" assets/bird2.png);
this.game.load.sprite ("bird3" assets/bird3.png);
},
create function() {
this.game.add.sprite (0, 0 "bird" );
},
I want to be able to switch my playable character the "bird" with the "bird2" or "bird3" through a selection button if a player selects a switch character button for the playable character to switch to that. I'm pretty sure this is something simple but I'm still pretty new with coding.
I want a button where I press then I can switch the character
(Button 1) switches to bird2
"if button 1 is selected button two and current bird are disabled"-only bird2 is visible
(Button 2) switches to bird3
"if button 2 is selected button one and current bird are disabled"-only bird3 is visible
Edit This is My current code and states
var MainState = {
//load the game assets before the game starts
preload: function () {
this.load.image('background', 'assets/spring2.png');
this.load.spritesheet('bird', 'assets/bird.png',52 ,28, 7);
this.load.spritesheet('bird2', 'assets/bird2.png',52 ,28, 7);
this.load.spritesheet('bird3', 'assets/bird3.png',52 ,28, 7);
this.load.image('pipe', 'assets/pipe4.png');
},
//executed after everything is loaded
create: function () {
this.background = game.add.tileSprite(0, game.height-736,game.width, 736, 'background');
this.background.autoScroll(-20,0);
/////Bird///////////////////////////////////////////////////
this.bird = this.game.add.sprite(100, 200, 'bird');
this.bird.animations.add('fly');
this.bird.animations.play('fly', 50, true);
game.physics.startSystem(Phaser.Physics.ARCADE);
game.physics.arcade.enable(this.bird);
this.bird.body.gravity.y = 1000;
var spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
this.bird.body.collideWorldBounds=true;
this.bird.body.immovable= true;
game.input.onDown.add(this.jump, this); //////touch screen jump
spaceKey.onDown.add(this.jump, this);
///////////////////////////////////////////////////////Pipes
this.pipes = game.add.group();
//timer
this.timer = game.time.events.loop(1600, this.addRowOfPipes, this); /////////////timer for pipes
///Bird anchor
this.bird.anchor.setTo(-0.2, 0.5)
},
// this is execated multiple times per second
update: function () {
if (this.bird.y < 0 || this.bird.y > 480)
game.state.start("StateOver");
///Collision
game.physics.arcade.overlap(
this.bird, this.pipes, this.restartGame, null, this);
///Bird Angle
if (this.bird.angle < 30)
this.bird.angle += 1;
///////////////music stop w top+bottom collision
if (this.bird.y < 0 || this.bird.y > 479)
music.stop();
},
jump: function () {
//this is for so the bird wount fly once dead
if (this.bird.alive == false)
return;
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
// Jump Animation
var animation = game.add.tween(this.bird);
// Change the angle of the bird to -20° in 100 milliseconds
animation.to({angle: -20}, 100);
// And start the animation
animation.start();
game.add.tween(this.bird).to({angle: -20}, 100).start();
},
restartGame: function () {
// Start the 'main' state, which restarts the game
game.state.start(game.state.StateOver); /////////////////////changed from current #########
///Hit pipe Null
game.physics.arcade.overlap(
this.bird, this.pipes, this.hitPipe, null, this);
},
addRowOfPipes: function() {
var hole = Math.floor(Math.random() * 5) + 1; ///Math.floor(Math.random() * 5) + 1;
for (var i = 0; i < 10 ; i++) ///// (var i = 0; i < 8; i++)
if (i != hole && i != hole + 1) ///// if (i != hole && i != hole + 1)
this.addOnePipe(440, i * 50 ); ///// 640 starting point of pipe 240 point of down ////this.addOnePipe(480, i * 60 + 10);
},
addOnePipe: function(x, y) {
var pipe = game.add.sprite(x, y, 'pipe');
this.pipes.add(pipe);
game.physics.arcade.enable(pipe);
pipe.body.velocity.x = -200;
pipe.checkWorldBounds = true;
pipe.outOfBoundsKill = true;
},
hitPipe: function() {
// If the bird has already hit a pipe, do nothing
// It means the bird is already falling off the screen
if (this.bird.alive == false)
return;
else {
game.state.start("StateOver");
}
// Set the alive property of the bird to false
this.bird.alive = false;
// Prevent new pipes from appearing
game.time.events.remove(this.timer);
// Go through all the pipes, and stop their movement
this.pipes.forEach(function(p){
p.body.velocity.x = 0;
}, this);
},
};
character.js
var characters={
preload:function()
{
game.load.spritesheet('button', 'assets/button.png', 215, 53, 8);
game.load.image("background", "assets/characterbackground.png");
game.load.image("pajaro", "assets/storeicon.png");
game.load.image("logo", "assets/extra/storef.png");
this.load.spritesheet('bird', 'assets/bird.png',52 ,28, 7);
this.load.spritesheet('bird2', 'assets/bird2.png',52 ,28, 7);
this.load.spritesheet('bird3', 'assets/bird3.png',52 ,28, 7);
game.load.spritesheet("button2", 'assets/button2.png', 100, 10, 10);
},
create:function()
{
bird = game.add.image(140, 150, 'pajaro');
logo = game.add.image (20, 350, 'logo');
this.background = game.add.tileSprite(0, game.height-736,game.width, 736, 'background');
this.background.autoScroll(-100,0);
this.btnMainMenu=game.add.button(130,500,'button',this.mainMenu,this,4,5,4);
this.btnbird=game.add.button(180,600,"button2",this.changebird2,this,0,1,0);
},
mainMenu:function()
{
game.state.start("stateTitle");
},
update:function()
{
// bird.x +=1;
},
changebird2: function(){
},
};
Instead of creating three sprites that you either hide or show, I might recommend just changing what texture is loaded when the sprite is created/added.
To do this you'll need to store a reference to the playable character, which you probably already have.
// On the game itself, add a reference.
this.bird = null;
// In your preload, load the different images.
this.load.image('bird', 'assets/bird.png');
this.load.image('bird2', 'assets/bird2.png');
this.load.image('bird3', 'assets/bird3.png');
// When creating, default to one.
this.bird = this.game.add.sprite(0, 0, 'bird');
// In your function where they select a new skin, you can load in a different texture.
this.bird.loadTexture('bird3');
Alternatively, you could store the key that should be used on the game.
// On the game itself, track which key to use.
this.birdSkin = 'bird';
// You'll still have to load your possible textures.
this.load.image('bird', 'assets/bird.png');
this.load.image('bird2', 'assets/bird2.png');
this.load.image('bird3', 'assets/bird3.png');
// Now when creating just use the variable.
this.bird.loadTexture(this.birdSkin);
The Phaser init() will allow 0 or more parameters to be passed in (see the end of Phaser Tutorial: understanding Phaser states), which is where you could populate this.birdSkin.
I would look at what states you're using to determine what's best for you. If you have one state for the game and another for selecting which image/texture is used, than the second option might be better.
Update for Character State
Given your comments and what I saw in your code, I created a short example that you could tweak for your use.
There's a JSFiddle available, but the code is also included below.
var mainState = {
preload: function() {
// Load the three sprites that they can choose between.
this.load.crossOrigin = 'anonymous';
this.load.image('ball', 'https://raw.githubusercontent.com/photonstorm/phaser-examples/master/examples/assets/sprites/orb-blue.png');
this.load.image('ball2', 'https://raw.githubusercontent.com/photonstorm/phaser-examples/master/examples/assets/sprites/orb-green.png');
this.load.image('ball3', 'https://raw.githubusercontent.com/photonstorm/phaser-examples/master/examples/assets/sprites/orb-red.png');
},
create: function() {
this.ball = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, this.game.global.skin);
this.ball.anchor.setTo(0.5);
// Let the ball be acted upon. This will allow the player to change the sprite used.
this.ball.inputEnabled = true;
this.ball.events.onInputDown.add(this.changeCharacter, this);
},
update: function() {
},
changeCharacter: function() {
game.state.start('character');
}
};
var characterState = {
preload: function() {
},
create: function() {
// For this, add our three possible ball skins.
this.ball1 = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY / 2, 'ball');
this.ball1.anchor.setTo(0.5);
this.ball1.inputEnabled = true;
this.ball2 = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, 'ball2');
this.ball2.anchor.setTo(0.5);
this.ball2.inputEnabled = true;
this.ball3 = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY * 1.5, 'ball3');
this.ball3.anchor.setTo(0.5);
this.ball3.inputEnabled = true;
// Use the selected ball's sprite in our main game.
this.ball1.events.onInputDown.add(this.selectBall, this);
this.ball2.events.onInputDown.add(this.selectBall, this);
this.ball3.events.onInputDown.add(this.selectBall, this);
},
update: function() {
},
selectBall: function(sprite, pointer) {
// Grab the key of the sprite and save it to our global variable.
this.game.global.skin = sprite.key;
this.game.state.start('main');
}
};
var game = new Phaser.Game(200, 200);
// Create a global object that we can add custom variables to.
game.global = {
skin: 'ball'
};
game.state.add('main', mainState);
game.state.add('character', characterState);
game.state.start('main');
This actually simplifies things a bit, in that it just uses a global variable (I've been using TypeScript the last handful of months, so there's probably a better way to declare this).

How to create objects on runtime and move them?

I'm trying to create objects on my game update and move them. This is my banana object:
function Banana() {
this.height = 1.96;
this.width = 3.955;
this.pos_x = CENTER - this.width/2;
this.pos_y = -475;
this.banana_image = banana_image;
};
And this is the Move method:
Banana.prototype.move = function(){
if (this.pos_y > 500) {
//this.banana_image.parentElement.removeChild(this.banana_image);
}
this.height += ZOOM_RATE;
this.width += ZOOM_RATE;
this.pos_y += 3;
this.pos_x -= SIDES_RATE;
};
This is the Game Update part:
Game.update = function() {
this.player.move();
//creating bananas
if (objs.lenght <= 0) {
this.banana = new Banana();
} else {
for (i = 0; i < 10; i++) {
objs.push(new Banana());
}
}
//moving bananas
for (i = 0; i < objs.lenght; i++) {
this.objs[0].move();
}
};
Game Draw:
function Game.draw = function() {
this.context.drawImage(road, 0,0, rw, rh);
this.context.drawImage(
this.player.player_image,
this.player.pos_x, this.player.pos_y,
this.player.width, this.player.height);
this.context.drawImage(
this.banana.banana_image,
this.banana.pos_x, this.banana.pos_y,
this.banana.width, this.banana.height);
};
I tried to ask this to multiple people, but I can't find an answer for it.
Let's say you want to move the objects 10 times and then stop.
First you need to add a line to the start of Game.draw, so that it clears the canvas making you always start drawing from scratch:
this.context.clearRect(0,0,500,500); // clear canvas, adjust box size if needed
Then make a function to call both update and draw, and queue that function to be called again:
var count = 10;
function updateAndDraw() {
Game.update();
Game.draw();
count--;
if (count) requestAnimationFrame(updateAndDraw);
}
// start moving:
requestAnimationFrame(updateAndDraw);
The movement may go too fast to your liking, so then adjust the move method to make smaller changes, or use setTimeout instead of requestAnimationFrame (but that will make the animation less fluent).
Note that you have a few errors in your code, which you will need to fix first:
lenght should be length
function Game.draw = function() {: remove function before Game.draw.
... check the error messages you get in console.

Jquery looping and binding 10 records at a time

I have a scenario where I get thousands of records from the server as JSON and bind all records to the page. For each record, I am doing some calculations in jquery and binding data to UI. As record count is in 1000's the time take for calculation and binding data is more. Data on the page is bound at the end when all records calculations are done. Is there any option to bind data one by one or 10 by 10 and show binding on UI for that set. What I am trying to find is to execute $.each for 10 records at a time and append next set of 10 records to it and so on. any idea to make the page load faster? (Paging is not required for my requirement). Any clue can help.
<div id="keepFinalDataHere"></div>
$.each(data, function (i, record) {
content += "<div>" + record.id + "</div><div>" + record.fromId + "</div><div>" + record.subject + "</div>";
});
$(content).appendTo('#keepFinalDataHere');
In above code, content is built by getting several thousands of records and once the content is built, then it is being bound to the div. I am looking for an option to get first 10 items bind the data to make sure that users feel like the page is loaded, and then APPEND remaining items in sets of 100 or so to existing list.
In simple way you can do in chunks.
<div id="keepFinalDataHere"></div>
<script>
//.../
var chunkSize = 50;//what ever you want or could be dynamic based on data size
var $keepFinalDataHere = $('#keepFinalDataHere');
$.each(data, function (i, record) {
content += "<div>" + record.id + "</div><div>" + record.fromId + "</div><div>" + record.subject + "</div>";
if(i % chunkSize === 0){ // content chunk is ready
$keepFinalDataHere.append(content); // show records
content = '';//reset the content
}
});
if(!(content === '')){//any leftOver records
$keepFinalDataHere.append(content);
}
If you want to keep the UI responsive and want to be able to execute code in between rendering a large amount of DOM elements, you'll have to use a timeout mechanism. You can do so by passing your render method to setTimeout.
Instead of adding the method to the stack and executing it immediately, setTimeout pushes the method to a task queue and only executes it once the current js stack has cleared.
The main steps of the method I propose:
Copy your data set to a temporary array
Use splice to remove the first n items from the array
Render the first n items to the DOM
if there are still items left, go to (2)
Here's the main part of the code, with comments, assuming:
testData holds an array of data points
createRow holds the logic to transform a data point to a rendered DOM element
INITIAL_CHUNK_SIZE holds the number of rows you want to render without a timeout.
DEFAULT_CHUNK_SIZE holds the number of rows each following loop has to render
The time out renderer (toRenderer):
var toRenderer = function(s) {
// We need a copy because `splice` mutates an array
var dataBuffer = [].concat(testData);
var nextRender = function(s) {
// Default value that can be overridden
var chunkSize = s || DEFAULT_CHUNK_SIZE;
dataBuffer
.splice(0, chunkSize)
.forEach(createRow);
if (dataBuffer.length) {
setTimeout(nextRender);
}
};
// Triggers the initial (not timed out) render
nextRender(INITIAL_CHUNK_SIZE);
};
In the example below I've included a moving spinner to show how the render loop is able to hold a decent frame rate.
Note that the larger the DEFAULT_CHUNK_SIZE, the faster you'll have all your items rendered. The tradeoff: once one render chunk takes more than 1/60s, you'll loose your smooth frame rate.
// SETTINGS
var DATA_LENGTH = 10000;
var DEFAULT_CHUNK_SIZE = 100;
var INITIAL_CHUNK_SIZE = 10;
var list = document.querySelector("ul");
var createRow = function(data) {
var div = document.createElement("div");
div.innerHTML = data;
list.appendChild(div);
};
// Blocking until all rows are rendered
var bruteRenderer = function() {
console.time("Brute renderer total time:");
testData.forEach(createRow);
console.timeEnd("Brute renderer total time:");
}
// Pushes "render assignments" to the "task que"
var toRenderer = function(s) {
console.time("Timeout renderer total time:");
var dataBuffer = [].concat(testData);
var nextRender = function(s) {
var chunkSize = s || DEFAULT_CHUNK_SIZE;
dataBuffer
.splice(0, chunkSize)
.forEach(createRow);
if (dataBuffer.length) {
setTimeout(nextRender);
} else {
console.timeEnd("Timeout renderer total time:");
}
};
nextRender(INITIAL_CHUNK_SIZE);
};
// EXAMPLE DATA, EVENT LISTENERS:
// Generate test data
var testData = (function() {
var result = [];
for (var i = 0; i < DATA_LENGTH; i += 1) {
result.push("Item " + i);
}
return result;
}());
var clearList = function() {
list.innerHTML = "";
};
// Attach buttons
document.querySelector(".js-brute").addEventListener("click", bruteRenderer);
document.querySelector(".js-to").addEventListener("click", toRenderer);
document.querySelector(".js-clear").addEventListener("click", clearList);
button {
display: inline-block;
margin-right: .5rem;
}
.spinner {
background: red;
border-radius: 50%;
width: 20px;
height: 20px;
animation-duration: 1s;
animation-timing-function: linear;
animation-direction: alternate;
animation-name: move;
animation-iteration-count: infinite;
}
#keyframes move {
from {
transform: translate3d(800%, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
ul {
height: 200px;
overflow-y: scroll;
background: #efefef;
border: 1px solid #ccc;
}
<button class="js-brute">
Inject rows brute force
</button>
<button class="js-to">
Inject rows timeout
</button>
<button class="js-clear">
clear list
</button>
<pre></pre>
<div class="spinner"></div>
<ul>
</ul>
If you have problems with the amount of data you had fetched from the server, you should found a way to limit here the array.
So your client code could handle just the proper amount of elements, just those you could show to the user.
If this is not possible, and you want to do all on client side, you should have a more complicated approach.
You have to save the pointer to the processed elements, and a variable with the amount of element to process (page num?).
And then use a for loop.
// Globally but not global
var cursor = 0
...
for(var i = cursor; i < (cursor+pageNum); i++) {
var element = myDataAsJsonFromApi[i];
// ... do something here.
}
// check if pageNum elements is added..
cursor += pageNum
if (myDataAsJsonFromApi.length == cursor) {
// load from server...
}
One option is to split your data buffer into chunks, so you can operate on some of the data at a time.
var data = [1,2,3,4,5,6,7,7,8,9,9,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,89];
(function () {
var lastSliceStart = 0;
function writeNext() {
var length = 10;
var chunk = $(data).slice(lastSliceStart, lastSliceStart+length);
$(chunk).each((key, item) => {
console.log(item);
});
lastSliceStart += length;
if (lastSliceStart < data.length) {
setTimeout(writeNext, 500); // Wait .5 seconds between runs
}
}
writeNext();
})();
https://jsfiddle.net/bogfdmfb/1/
Build a queue, process queue for few items at a time, show progress, process next items in queue an so on.
//your app
App = {
data: [] //set your JSON dataSource here
}
//define Task
Task = function () {
this.buildQueue(10);
};
Task.prototype = {
buildQueue: function (size) {
var data_count = App.data.length; //length of your datasource
this.queue = [];
// fill the queue
var lastIndex = 0;
var current_index = size;
var c = true;
while (c) {
if (current_index >= data_count - 1) {
current_index = data_count;
c = false;
}
this.queue.push([lastIndex, current_index - 1]);
lastIndex = current_index;
current_index += size;
}
/* If size is 10, array would be [[0,9], [10,19], [20,29]....and so on], The smaller the size, better progress / percentage variation / loading on ui display */
},
doNext: function () {
if (this.queue.length == 0) {
this.end();
return;
}
var row = this.queue.shift(); //stack is LIFO, queue is FIFO, this.queue.pop()
try {
this.processQueue(App.data, row[0], row[1]); //pass dataSource, and indexes of array, loop in processQueue function for indexes passed
} catch (e) {
return;
}
this.incrementProgress(row[1] / App.data.length); //progress on ui
// do next
var _self = this;
setTimeout(function () {
_self.doNext();
}, 1);
},
incrementProgress: function (percent) {
var $progress = $('#percent');
percent = Math.ceil(percent * 100);
percent = percent + '%';
$progress.text(percent);
},
start: function () {
$('#percent').show();
this.doNext(); //initiate loop
},
end: function () {
$('#percent').hide();
},
processQueue: function (data, start, end) {
for (var i = start; i <= end; i++) {
var dataObj = data[i];
//use the data here, update UI so user sees something on screen
}
}
};
//initialize an instance of Task
var _task = new Task(task);
_task.start();

Javascript module pattern - what am I doing wrong?

A working version of this is here: http://est.pagodabox.com/client/svedka
I have the following function which I'm trying to convert into a module pattern, but when I try to use one of the function that I return at the bottom, for example:
est_project.closeContent($html);
I get an error that it's not a function. Is there something i'm doing wrong here?
Thanks!
var est_project = (function(){
// Setup functions
var flexDestroy,
cloneCurrent,
clonePosition,
switchSlide,
projectLayout,
contentHeight,
slidePos,
slideClick,
infoToggle,
closeContent;
// Destroy flexslider
flexDestroy = function($slider,$cleanSlider, $projBg) {
// Insert the clone of the un-initialized slide element, and remove the current flexslider
// Effectively "destroys" the current slider
var $curSlide = $slider.find('.flex-active-slide'),
// Get the zero based index of current slide
curSlideIndex = $curSlide.index() - 1,
curBg = $curSlide.find('img').attr('src'),
slideCount = $cleanSlider.data('count'),
i = 0,
$rearrange = $('');
// When you switch projects, the current slide should stay put
if(curSlideIndex !== 0 && slideCount > 1) {
// Cut from the current slide to the end, paste at the beginning
for(i = 0 ; i < slideCount; i += 1) {
if(curSlideIndex > i) {continue;}
$rearrange = $rearrange.add( $cleanSlider.find('li:eq(' + i + ')') );
}
$rearrange.remove();
$cleanSlider.find('li:first-child').before($rearrange)
$cleanSlider.css({'background-image' : 'url(' + curBg + ')'});
}
$slider.after($cleanSlider).remove();
clonePosition(slideheight);
};
return {
// Clone current
cloneCurrent: function($el) {
var $clean,
slideCount = $el.find('li').length;
$clean = $el.clone();
$clean.removeClass('project-current').find('div').removeClass('img-loading');
$clean.data('count',slideCount);
return $clean;
},
// Set the clone position, for when we add it to the DOM or resize the window
clonePosition: function(slideheight) {
var n = $cleanSlider.index(),
$myBg = $cleanSlider.find('div'),
myPosition = n * slideheight;
// Set the position of the inserted clone
$cleanSlider
.css({height: slideheight, top: myPosition, position : 'absolute'});
$myBg
.css({height: slideheight});
},
switchSlide: function($me, $slider) {
$('.project-current').removeClass('project-current');
$me.addClass('project-current');
// Get rid of current flexslider
flexDestroy($slider,$cleanSlider);
// Clone the unitialized slider so we can add it back in later when it gets destroyed
$cleanSlider = cloneCurrent($me);
$me.addClass('flexslider').flexslider({
animation: "slide",
animationSpeed: 500,
slideshow: false,
manualControls: '.dot-nav li a'
});
// After the flexslider initializes, slide the content
setTimeout(function(){
slidePos($me, $slidewrap, slideheight, $win);
},100);
},
// Custom "masonry" function, absolutely positions each project div according to the slide height
projectLayout: function(slideheight,$proj,$projBg) {
var n = 0;
$proj.each(function(){
var $me = $(this),
myPosition = n * slideheight;
// Set all the heights
$me
.css({top: myPosition, position : 'absolute'})
.add($projBg)
.css({height: slideheight});
n++;
});
},
// Set slide wrapper height to window height
contentHeight: function($win, $slidewrap) {
var winHeight = $win.height();
$slidewrap.css({height: winHeight});
},
// Set slide wrapper position to slide to the clicked slide, and set content position
slidePos: function($me, $slidewrap, slideheight, $win) {
var $contentText = $('.project-content .text'),
projNavHeight = Math.round( $win.height() * .1 ),
curIndex = $me.index(),
curTop = 0 - (curIndex * slideheight) + projNavHeight;
$slidewrap.css({transform: 'translate(0,' + curTop.toString() + 'px)'});
$('.corner-btn').add($contentText).css({'padding-top' : projNavHeight});
setTimeout(function(){
$slidewrap.removeClass('tr-none movin').addClass('tr-all');
$('.project').css({opacity: .4})
}, 100);
},
// Click a project, slide to it
slideClick: function($proj) {
$('.project').live('click',function(){
var $me = $(this),
myHref = $me.data('href'),
myTitle = $me.data('title'),
$slider = $('.flexslider'),
indexMy = $me.index(),
indexCur = $('.project-current').index(),
projDir;
$me.css({opacity: 1});
// Stop here if we click on the current project
if($me.hasClass('project-current')) {
return false;
}
History.pushState(null,myTitle,myHref);
});
},
// Hide and show content
infoToggle: function() {
// Open content
$('#corner-btn-info').on('click',function(){
$html.addClass('show-content');
if($('.project-content .text').height() <= $win.height()) {
$html.addClass('no-overflow');
}
$('.project-content-wrap').css({'z-index': 10});
});
// Close content
$('#corner-btn-close').live('click',function(){
closeContent($html);
});
},
closeContent: function($html) {
$html.removeClass('show-content');
setTimeout(function(){
$('.project-content-wrap').css({'z-index': -1});
$html.removeClass('no-overflow');
$('#classy').animate({scrollTop: 0})
},300);
}
};
});
The problem is that you're not executing the anonymous function, your code is the equivalent of:
var est_project = function() {};
You need to execute the function if you want it to return the functions defined in it.
Just replace the last line:
});
By:
}());
Or you can keep your code and call the closeContent function like this:
est_project().closeContent();
But I guess that's not what you want :-) You'd instantiate a new object everytime you call the est_project function.
At the start and end of your file just attach the object to window with the executed function and wrap whole function inside a self executing function. like this
(function(global) {
//your code goes here
global.est_project = est_project();
})(this)

Categories

Resources