Trying to load a random link out of array - javascript

I know this is a very noob question, looked up a couple of examples but me being a beginner I'm having trouble implementing it in my code.
I think the title is pretty clear cut, I would like that the loop starts with a random item, and continues picking random items out of the array.
var bgImageArray = [
"link1" , "link2" , "link3"
]
base = "https://lh3.googleusercontent.com/pw/";
bgImageArray.forEach(function(img){
new Image().src = base + img;
});
function backgroundSequence() {
window.clearTimeout();
var k = 0;
for (i = 0; i < bgImageArray.length; i++) {
setTimeout(function(){
document.getElementById('animated-bg').style.background = "url(" + base + bgImageArray[k] + ") no-repeat center center";
if ((k + 1) === bgImageArray.length) { setTimeout(function() { backgroundSequence() }, (60000 / tempo.value))} else { k++; }
}, (60000 / tempo.value) * i)
}
}
``

use this code for select random element from array
var bgImageArray = ["link1", "link2", "link3"];
const random = Math.floor(Math.random() * bgImageArray.length);
console.log(random, bgImageArray[random]);

Perhaps better like this
Update: Missed the random part
let bgImageArray = ["link1", "link2", "link3"];
const base = "https://lh3.googleusercontent.com/pw/";
bgImageArray = bgImageArray.map(img => new Image().src = base + img);
function backgroundSequence() {
const rndImageSrc = bgImageArray[Math.floor(Math.random()*bgImageArray.length)].src;
document.getElementById('animated-bg').style.background = "url(" + rndImageSrc + ") no-repeat center center";
}
let tId = setInteval(backgroundSequence,tempo*1000);

Related

Why I get Indefined when displaying Img’s on page?

I have been playing with this code for a while and I was wondering why when I try to add img’s to the array on the js code makes the images appear on DOM but also makes a bunch of Undefined elements appear, How can I just make the 15 images appear without the undefined? Thanks
enter link description here
var previous = document.getElementById('btnPrevious')
var next = document.getElementById('btnNext')
var gallery = document.getElementById('image-gallery')
var pageIndicator = document.getElementById('page')
var galleryDots = document.getElementById('gallery-dots');
var images = ["https://exoplanets.nasa.gov/internal_resources/1763/",
"https://cdn.britannica.com/56/234056-050-0AC049D7/first-image-from-James-Webb-Space-Telescope-deepest-and-sharpest-infrared-image-of-distant-universe-to-date-SMACS-0723.jpg",
"https://assets.newatlas.com/dims4/default/ac389ce/2147483647/strip/true/crop/1620x1080+150+0/resize/1200x800!/quality/90/?url=http%3A%2F%2Fnewatlas-brightspot.s3.amazonaws.com%2Farchive%2Funiverse-expanding-acceleration-1.jpg",
"https://media.newyorker.com/photos/590966ee1c7a8e33fb38d6cc/master/w_2560%2Cc_limit/Nissan-Universe-Shouts.jpg",
"https://www.thoughtco.com/thmb/NY5k_3slMRttvtS7mA0SXm2WW9Q=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/smallerAndromeda-56a8ccf15f9b58b7d0f544fa.jpg",
"https://static.scientificamerican.com/sciam/cache/file/05B8482C-0C04-4E41-859DCCED721883D2_source.jpg?w=590&h=800&7ADE2895-F6E3-4DF4-A11F51B652E9FA88",
"https://qph.cf2.quoracdn.net/main-thumb-66277237-200-huqebnzwetdsnnwvysbxemlskpcxnygf.jpeg",
"http://www.pioneertv.com/media/1090/hero_shot_1080x720.jpg?anchor=center&mode=crop&width=600&height=400&rnd=133159257140000000",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRSWFW1EpMNFM5-dbZEUUnzJkzT3KbUCeuhPHx_eseFCpPeX4Q_DIVPopjS0LeKVmKdQho&usqp=CAU",
"https://cdn.mos.cms.futurecdn.net/rwow8CCG3C3GrqHGiK8qcJ.jpg",
"https://static.wixstatic.com/media/917d103965314e2eacefed92edb6492c.jpg/v1/fill/w_640,h_356,al_c,q_80,usm_0.66_1.00_0.01,enc_auto/917d103965314e2eacefed92edb6492c.jpg",
"https://astronomy.com/~/media/A5B9B6CF36484AB9A6FFAE136C55B355.jpg",
"https://discovery.sndimg.com/content/dam/images/discovery/fullset/2022/9/alien%20planet%20GettyImages-913058614.jpg.rend.hgtvcom.616.411.suffix/1664497398007.jpeg",
"https://images.newscientist.com/wp-content/uploads/2017/06/21180000/planet-10-orange-blue-final-small.jpg?crop=16:9,smart&width=1200&height=675&upscale=true",
"https://images.hindustantimes.com/img/2022/07/20/1600x900/Viral_Instagram_Planet_Rainbow_Nasa_1658316556293_1658316573815_1658316573815.PNG"
]
for (var i = 0; i < 15; i++) {
images.push({
title: "Image " + (i + 1),
source: images[i]
});
}
var perPage = 8;
var page = 1;
var pages = Math.ceil(images.length / perPage)
// Gallery dots
for (var i = 0; i < pages; i++){
var dot = document.createElement('button')
var dotSpan = document.createElement('span')
var dotNumber = document.createTextNode(i + 1)
dot.classList.add('gallery-dot');
dot.setAttribute('data-index', i);
dotSpan.classList.add('sr-only');
dotSpan.appendChild(dotNumber);
dot.appendChild(dotSpan)
dot.addEventListener('click', function(e) {
var self = e.target
goToPage(self.getAttribute('data-index'))
})
galleryDots.appendChild(dot)
}
// Previous Button
previous.addEventListener('click', function() {
if (page === 1) {
page = 1;
} else {
page--;
showImages();
}
})
// Next Button
next.addEventListener('click', function() {
if (page < pages) {
page++;
showImages();
}
})
// Jump to page
function goToPage(index) {
index = parseInt(index);
page = index + 1;
showImages();
}
// Load images
function showImages() {
while(gallery.firstChild) gallery.removeChild(gallery.firstChild)
var offset = (page - 1) * perPage;
var dots = document.querySelectorAll('.gallery-dot');
for (var i = 0; i < dots.length; i++){
dots[i].classList.remove('active');
}
dots[page - 1].classList.add('active');
for (var i = offset; i < offset + perPage; i++) {
if ( images[i] ) {
var template = document.createElement('div');
var title = document.createElement('p');
var titleText = document.createTextNode(images[i].title);
var img = document.createElement('img');
template.classList.add('template')
img.setAttribute("src", images[i].source);
img.setAttribute('alt', images[i].title);
title.appendChild(titleText);
template.appendChild(img);
template.appendChild(title);
gallery.appendChild(template);
}
}
// Animate images
var galleryItems = document.querySelectorAll('.template')
for (var i = 0; i < galleryItems.length; i++) {
var onAnimateItemIn = animateItemIn(i);
setTimeout(onAnimateItemIn, i * 100);
}
function animateItemIn(i) {
var item = galleryItems[i];
return function() {
item.classList.add('animate');
}
}
// Update page indicator
pageIndicator.textContent = "Page " + page + " of " + pages;
}
showImages();
I checked your code and make it work with a small modification.
You are reusing the same array with the links of images and push inside the new object with the shape of { title, source }.
You just need to do this changes:
Change the name of your array of images. Something from images to arrayOfImages.
const arrayOfImages = ["https://exoplanets.nasa.gov/internal_resources/1763/", ...]
Declare an empty array before your first for loop. Make something like const images = []
On your for loop, instead of loop over the images variable, do it over the arrayOfImages variable.
const images = [];
for (var i = 0; i < 15; i++) {
images.push({
title: "Image " + (i + 1),
source: arrayOfImages[i]
});
}
With those changes, everything works for me.
Also, as a recommendation, try to avoid the var keyword. If you want more details about this, this answer is very helpful: https://stackoverflow.com/a/50335579/17101307
You can use Array#map to create a new array of objects from the array of URLS, then replace the original array.
images = images.map((x, i) => ({
title: "Image " + (i + 1),
source: x
}));

Can I update a jS variable's property dynamically from another variable?

I'm trying to update a property of a jS variable using the scroll velocity which I'm storing in another variable. This is my code thus far (scroll to the second code box as the first part works correctly):
jQuery( document ).ready(function() {
jQuery('main').attr('id', 'grained');
(function (window, doc) {
"use strict";
function grained(ele, opt) {
var element = null,
elementId = null,
selectorElement = null;
if (typeof ele === 'string') {
element = doc.getElementById(ele.split('#')[1]);
}
if (!element) {
console.error('Grained: cannot find the element with id ' + ele);
return;
} else {
elementId = element.id;
}
//set style for parent
if (element.style.position !== 'absolute') {
element.style.position = 'relative';
}
element.style.overflow = 'hidden';
var prefixes = ["", "-moz-", "-o-animation-", "-webkit-", "-ms-"];
//default option values
var options = {
animate: true,
patternWidth: 100,
patternHeight: 100,
grainOpacity: 0.1,
grainDensity: 1,
grainWidth: 1,
grainHeight: 1,
grainChaos: 0.5,
grainSpeed: 20
};
Object.keys(opt).forEach(function (key) {
options[key] = opt[key];
});
var generateNoise = function () {
var canvas = doc.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = options.patternWidth;
canvas.height = options.patternHeight;
for (var w = 0; w < options.patternWidth; w += options.grainDensity) {
for (var h = 0; h < options.patternHeight; h += options.grainDensity) {
var rgb = Math.random() * 256 | 0;
ctx.fillStyle = 'rgba(' + [rgb, rgb, rgb, options.grainOpacity].join() + ')';
ctx.fillRect(w, h, options.grainWidth, options.grainHeight);
}
}
return canvas.toDataURL('image/png');
};
function addCSSRule(sheet, selector, rules, index) {
var ins = '';
if (selector.length) {
ins = selector + "{" + rules + "}";
} else {
ins = rules;
}
if ("insertRule" in sheet) {
sheet.insertRule(ins, index);
} else if ("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
var noise = generateNoise();
var animation = '',
keyFrames = ['0%:-10%,10%', '10%:-25%,0%', '20%:-30%,10%', '30%:-30%,30%', '40%::-20%,20%', '50%:-15%,10%', '60%:-20%,20%', '70%:-5%,20%', '80%:-25%,5%', '90%:-30%,25%', '100%:-10%,10%'];
var pre = prefixes.length;
while (pre--) {
animation += '#' + prefixes[pre] + 'keyframes grained{';
for (var key = 0; key < keyFrames.length; key++) {
var keyVal = keyFrames[key].split(':');
animation += keyVal[0] + '{';
animation += prefixes[pre] + 'transform:translate(' + keyVal[1] + ');';
animation += '}';
}
animation += '}';
}
//add animation keyframe
var animationAdded = doc.getElementById('grained-animation');
if (animationAdded) {
animationAdded.parentElement.removeChild(animationAdded);
}
var style = doc.createElement("style");
style.type = "text/css";
style.id = 'grained-animation';
style.innerHTML = animation;
doc.body.appendChild(style);
//add custimozed style
var styleAdded = doc.getElementById('grained-animation-' + elementId);
if (styleAdded) {
styleAdded.parentElement.removeChild(styleAdded);
}
style = doc.createElement("style");
style.type = "text/css";
style.id = 'grained-animation-' + elementId;
doc.body.appendChild(style);
var rule = 'background-image: url(' + noise + ');';
rule += 'position: absolute;content: "";height: 300%;width: 300%;left: -100%;top: -100%;';
pre = prefixes.length;
if (options.animate) {
while (pre--) {
rule += prefixes[pre] + 'animation-name:grained;';
rule += prefixes[pre] + 'animation-iteration-count: infinite;';
rule += prefixes[pre] + 'animation-duration: ' + options.grainChaos + 's;';
rule += prefixes[pre] + 'animation-timing-function: steps(' +options.grainSpeed + ', end);';
}
}
//selecter element to add grains
selectorElement = '#' + elementId + '::before';
addCSSRule(style.sheet, selectorElement, rule);
}
window.grained = grained;
//END
})(window, document);
// Here down is the important part //
var grainOptions = {
animate: true,
patternWidth: 100,
patternHeight: 100,
grainOpacity: 0.04,
grainDensity: 1,
grainWidth: 1,
grainHeight: 1
};
grained('#grained', grainOptions);
document.querySelector("body").addEventListener("wheel", scrollGlitch);
function scrollGlitch(event) {
var y = event.deltaY;
var scaleY = y;
var divider = 100;
var sum = scaleY / divider;
console.log(sum);
}
});
From this I am getting 2 things which I need:
the property value of grainOpacity;
the scroll velocity as stored in the variable sum (which is divided by 100 to make the values the right scale i.e 0.01 - 0.1;
What I need to do now is update the grainOpacity property of the grainOptions variable with the value of the sum variable. Is this possible? How would I achieve this, I read about Bracket/Dot notations but can't tell if this is the right way.
You can take any object field reference using dot like
grainOptions.grainOpacity
Then you can redefine field value as using let variables.
Update your scrollGlitch function:
function scrollGlitch(event) {
var y = event.deltaY;
var scaleY = y;
var divider = 100;
var sum = scaleY / divider;
grainOptions.grainOpacity = sum;
}
Note. In JS you can take Object fields' value with 2 ways:
With saving reference on field to update it's own value. Ex:
grainOptions.grainOpacity.
Only for take value. Ex:
grainOptions['grainOpacity']

Problem with dynamic size array in javascript

I am trying to develop my own game engine running on JavaScript for text adventure games. It's more of a personal project than actually trying to go anywhere with it, but none the less, I am having fun.
The problem I am currently getting is Uncaught TypeError: optionGroups[(num + 1)] is undefined from my console, as well as a reference to line 97 in filereader.js. I believe that this is because of how I am defining the array, or trying to use it, but I am also unsure of the "correct" way to do so.
My filereader.js file
var raw;
function initFileReader(){
document.getElementById('fileInput').addEventListener('change', handleFileSelect, false);
}
function handleFileSelect(event){
const reader = new FileReader()
reader.onload = handleFileLoad;
reader.readAsText(event.target.files[0])
}
function handleFileLoad(event){
//console.log(event.target.result);
raw = event.target.result;
//All save files should be marked with MSF somewhere in the file.
if (!raw.includes("MSF")){
alert("Not a Save File");
}
else{
/*
* SYNTAX FOR SAVE FILE
* ===========================================================
* startupMessage = <T><T>
* optionText = <"0"><"0"> where 0 is the index of the entry.
* optionAddition = <'0'><'0'> where 0 is the index of the entry.
* optionGroups = <:0:>1,2<:0:> where 0 is the index of the group, and 1,2 is the list of the entries separated by commas
* ===========================================================
* Overrides are done by the last conflicting thing in the file being chosen.
* Important sections of the text are denoted by <!><!> and will show up as blue text.
*/
var buffer = raw;
//Pulling out the startup message.
buffer = buffer.substring(buffer.search("<T>") + 3);
startupMessage = buffer.substring(0, buffer.search("<T>"));
buffer = buffer.substring(buffer.search("<T>") + 3);
buffer = buffer.trim();
startupMessage = startupMessage.replace(/<!>/g, "<a class=\"important\">");
startupMessage = startupMessage.replace(/<\/!>/g, "</a>");
bodyText += startupMessage;
buffer = buffer.replace(/<!>/g, "<a class=\"important\">");
buffer = buffer.replace(/<\/!>/g, "</a>");
//Start segment parting
//console.log(buffer);
while(buffer != "" || buffer){
switch(buffer.charAt(1)){
case '\"':
//console.log("optionText");
var num = Number(buffer.substring(2).substring(0, buffer.substring(2).search("\"")));
//console.log(num);
buffer = buffer.substring(3).substring(buffer.substring(3).search(">") + 1);
//console.log(buffer);
var temp = buffer.substring(0, buffer.search("<\"" + num + "\">"));
//console.log(temp);
buffer = buffer.substring(temp.length + ("<\"" + num + "\">").length + 2);
//console.log(buffer);
//console.log(""+ num + " : " + temp);
optionText[num] = temp;
break;
case '\'':
//console.log("optionAddition");
var num = Number(buffer.substring(2).substring(0, buffer.substring(2).search("\'")));
//console.log(num);
buffer = buffer.substring(3).substring(buffer.substring(3).search(">") + 1);
//console.log(buffer);
var temp = buffer.substring(0, buffer.search("<\'" + num + "\'>"));
//console.log(temp);
buffer = buffer.substring(temp.length + ("<\'" + num + "\'>").length + 2);
//console.log(buffer);
//console.log(""+ num + " : " + temp);
optionAddition[num] = temp;
break;
case ':':
//console.log("optionGroups");
var num = Number(buffer.substring(2).substring(0, buffer.substring(2).search(":")));
//console.log(num);
buffer = buffer.substring(3).substring(buffer.substring(3).search(">") + 1);
//console.log(buffer);
var temp = buffer.substring(0, buffer.search("<:" + num + ":>"));
//console.log(temp);
buffer = buffer.substring(temp.length + ("<:" + num + ":>").length + 2);
//console.log(buffer);
//console.log(""+ num + " : " + temp);
let nums = temp.split(",");
console.log(Number(nums[0]));
console.log(optionGroups);
for(let i = 0; i < nums.length; ++i){
optionGroups[num+1][i] = Number(nums[i]);
++i;
}
console.log(optionGroups);
break;
}
}
var el = document.getElementById("gameSelectionWrapper");
var opacity = 1.0;
var fade = setInterval(() =>{
if(opacity <= 0){
el.parentNode.removeChild(el);
clearTimeout(fade);
}
else {
opacity = opacity - 0.02;
el.style.opacity = opacity;
}
}, 30/1000);
createSelections(0);
}
}
My index.js file
var bodyText = "";
var prevBodyText = bodyText;
var optionText = [];
var optionAddition = [];
var currentOptionGroup = 0;
var optionGroups = [];
var startupMessage = "";
function startup(){
initFileReader();
mainLoop();
}
function mainLoop(){
setInterval(()=>{
updateText();
prevBodyText = bodyText;
}, 30/1000);
}
function updateText(){
if(prevBodyText != bodyText){
let body = document.getElementById("bodyTextWrapper");
body.innerHTML = bodyText;
body.scrollTop = body.scrollHeight;
console.log(">> Updated Body Text");
}
}
function selectionHandler(flag){
for(let i = 0; i < optionGroups[currentOptionGroup].length; ++i){
removeOption(optionGroups[currentOptionGroup][i]);
}
createSelections(flag+1);
currentOptionGroup = flag + 1;
bodyText += "<br><br>" + optionAddition[flag];
}
function removeOption(optionNum){
var el = document.getElementById("option" + optionNum);
if(el != null){
var opacity = 1.0;
var fade = setInterval(() =>{
if(opacity <= 0){
el.parentNode.removeChild(el);
clearTimeout(fade);
}
else {
opacity = opacity - 0.05;
el.style.opacity = opacity;
}
}, 30/1000);
}
}
function createSelections(setNumber){
for(var e in optionGroups[setNumber]){
createOption(optionGroups[setNumber][e]);
}
}
function createOption(optionNum){
console.log("Making option");
var div = document.createElement("DIV");
div.className = "selection";
div.setAttribute("onclick", "selectionHandler("+optionNum+");");
div.id = "option" + optionNum;
div.innerHTML = ">> " + optionText[optionNum];
div.style.opacity = 0.0;
document.getElementById("selectionWrapper").appendChild(div);
var opacity = 0;
setTimeout(() => {
var fade = setInterval(() => {
if(opacity >= 1){
clearTimeout(fade);
}
else {
opacity = opacity + 0.05;
div.style.opacity = opacity;
}
}, 30/1000);
}, 400);
}
My sample save file
MSF
<T>Hello and welcome. <!>Please</!> press <!>Start</!> to begin.<T>
<"0">Start<"0">
<'0'>You have started the game.<'0'>
<:0:>1,2<:0:>
<"1">Go Left<"1">
<'1'>Heading left.<'1'>
<"2">Go Right<"2">
<'2'>Heading right.<'2'>
Please let me know if you need to see anything else, I would really appreciate any feedback on this one.

Object constructor - managing loop animation

I am doing a website wich has a lot of animations managed by JavaScript, when i started i just defined a function and some variables for the animation and repeat the process, like this. And a think is not the good way.
//BRIGHT ANIMATION
var frameWidth1 = 386;
var frameHeight1 = 100;
var spriteWidth1 = 20067;
var spriteHeight1 = 100;
var spriteElement1 = document.getElementById("bright");
var curPx1 = 0;
var ti1;
function animateSpriteB() {
spriteElement1.style.backgroundPosition = "-" + curPx1 + 'px 0px';
curPx1 = curPx1 + frameWidth1;
if (curPx1 >= spriteWidth1) {
curPx1 = 0;
}
ti1 = setTimeout(animateSpriteB, 70);
}
animateSpriteB();
// PAPIRO ANIMATION
var frameWidth = 56;
var frameHeight = 218;
var spriteWidth = 2016;
var spriteHeight = 218;
var spriteElement = document.getElementById("roll-off");
var curPx = 0;
var ti;
function animateSprite() {
spriteElement.style.backgroundPosition = "-" + curPx + 'px 0px';
curPx = curPx + frameWidth;
ti = setTimeout(animateSprite, 27.7);
if (curPx === spriteWidth) {
clearTimeout(ti);
}
}
function slideMask(){
var mask = $("#paper-mask");
var paper = $("#paper");
mask.animate({
width: 450
},{
duration: 1000,
complete: function(){
$("#paper-content").fadeIn();
}
});
}
var ti = setTimeout(function(){
animateSprite();
slideMask();
}, 3000);
So know, I decided to use a constructor to re use the same code and manage all the animations in the website. i came with Something like this:
// CONSTRUCTOR WHO MANAGE THE ANIMATIONS FOR THE WEBSITE
function SpriteAnimation(frameWidth, spriteWidth, spriteElement, isLoop){
this.frameWidth = frameWidth;
this.spriteWidth = spriteWidth;
this.spriteElement = spriteElement;
this.isLoop = isLoop;
this.curPx = 0;
this.ti;
}
SpriteAnimation.prototype.start = function(){
var selector = document.getElementById(this.spriteElement);
selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
this.curPx = this.curPx + this.frameWidth;
this.ti = setTimeout(this.start, 2000);
if (this.curPx === this.spriteWidth){
clearTimeout(this.ti);
}
this.start();
}
var letter = new SpriteAnimation(935.4, 17774, "letter", true);
letter.start();
I am having problems in performance, every time i run the code my browser just crash i also think im not doing good the loop. So here comes my question: how can i do to manage the animations with an object constructor in wich i can pass parameters like if it is loop animation and the sprite parameters?... I appreciate the help you guys can bring me :)
#Tibos Your code has been from great help for me i just spent almost 4 hours trying to achieve this, and then yo came out and make it really easy, this is how my code looks now, i added another parameter: frame rate. so every animation can have a different frame rate. Also modified a bit the if statement because the animation was running untill the sprite dissapear and i need them to stay in the last frame, let me know if this is the correct form.
// CONSTRUCTOR WHO MANAGE THE ANIMATIONS FOR THE WEBSITE
function SpriteAnimation(frameWidth, spriteWidth, spriteElement, shouldLoop, frameRate){
this.frameWidth = frameWidth;
this.spriteWidth = spriteWidth;
this.selector = document.getElementById(spriteElement);
this.shouldLoop = shouldLoop ;
this.curPx = 0;
this.frameRate = frameRate;
this.ti;
}
SpriteAnimation.prototype.start = function(){
this.selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
this.curPx += this.frameWidth;
if (this.curPx < (this.spriteWidth - this.frameWidth)){
setTimeout(this.start.bind(this), this.frameRate);
} else if (this.shouldLoop) {
this.curPx = 0;
this.start();
}
};
var letter = new SpriteAnimation(935.4, 17774, "letter", true, 60);
letter.start();
You have a few problems in your code, presented here in order of impact:
recursively calling start
losing the reference to this
clearing timeout as soon as it's set
unused variables
selecting the element at each iteration
Here is some better code (that works):
function SpriteAnimation(frameWidth, spriteWidth, spriteElement, shouldLoop){
this.frameWidth = frameWidth;
this.spriteWidth = spriteWidth;
this.selector = document.getElementById(spriteElement);
this.curPx = 0;
this.shouldLoop = shouldLoop;
}
SpriteAnimation.prototype.start = function(){
this.selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
this.curPx += this.frameWidth;
if (this.curPx <= this.spriteWidth){
setTimeout(this.start.bind(this), 2000);
} else if (this.shouldLoop) {
this.curPx = 0;
this.start();
}
};
var letter = new SpriteAnimation(935.4, 17774, "letter", true);
letter.start();
DEMO: http://jsbin.com/oJIYoRU/1/edit
This function calls itself recursively with no base case. As soon as you invoke it you will lock the UI and overflow the call-stack.
SpriteAnimation.prototype.start = function(){
... some code ...
this.start();
}

Trouble getting setInterval and setTimeout to work

This uses Raphaeljs to draw a single chord from an array:
function createChordStruct(key, string, shape) {
var string = string.toUpperCase();
var position = positions[string][key];
var struct = chord_shapes[shape];
return {
name: key + struct.name,
chord: struct.chord,
position: position,
position_text: struct.position_text,
bars: struct.bars
}
}
function createChordElement(chord_struct) {
var chordbox = $('<div>').addClass('chord');
var chordcanvas = $('<div>');
var chordname = $('<div>').addClass('chordname');
chordbox.append(chordcanvas);
chordbox.append(chordname);
chordname.append(chord_struct.name);
var paper = Raphael(chordcanvas[0], 150, 140);
var chord = new ChordBox(paper, 30, 30);
chord.setChord(
chord_struct.chord,
chord_struct.position,
chord_struct.bars,
chord_struct.position_text);
chord.draw();
return chordbox;
}
function createSectionElement(section_struct) {
var section = $('<div>').addClass('section');
var section_title = $('<div>').addClass('title');
var section_desc = $('<div>').addClass('description');
section.append(section_title);
section.append(section_desc);
section_title.append(section_struct.section);
section_desc.append(section_struct.description);
return section;
}
And this takes each chord created from the array and puts them in a new div called "chordscroller":
function c_i() {
var randomholder = 'id_' + (Math.floor(Math.random() * 100005) + 1);
var randomId = 'id_' + (Math.floor(Math.random() * 100005) + 1);
$(function () {
$('#sortable').append($('<li id ="' + randomholder + '" class="chordbox"><span id="i" class="scale">C - I</span><span id="' + randomId + '" class=" even scrollpane chordscroller"></span></li>').sortable( "refresh" ))
});
function c_one() {
var container = $("#" + randomId + "");
var column = null;
var column = _.shuffle(c_1);
for (var i = 0; i < column.length; ++i) {
var section_struct = column[i];
var section = createSectionElement(section_struct);
for (var j = 0; j < section_struct.chords.length; ++j) {
section.append(createChordElement(section_struct.chords[j]));
}
container.append(section);
}
}
$(function() { c_one() });
}
The problem is it draws all the chords at the same time and it takes forever. I've tried every combination of setTimeout and setInterval I could think of but I keep running into errors.
Can anybody tell from this code how to get the chords to be drawn one at a time instead of all at once?
Finally figured it out (using a plugin called doTimeout):
$.doTimeout( 1, function() {
chord.setChord(
chord_struct.chord,
chord_struct.position,
chord_struct.bars,
chord_struct.position_text);
chord.draw();
});

Categories