Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Optimizing horizontally scrolling divs

    Hi,

    I've been tasked with writing a webpage in which multiple lines of gibberish move horizontally across the screen. It works on Chrome right now, but it takes up a hefty chunk of memory. On a 2GHz Mac Mini with 3GG RAM boot camping Windows XP, it takes up anywhere between a third to a half of the CPU. On a Lenovo Thinkpad T420 with a 2.6GHz i5 and 8GB of RAM running Windows 7, it goes between 25% and 30%. On IE9 it runs much slower when the number of lines goes above fifty or so, while Chrome and Safari freeze up after around a hundred. Safari's framerate drops a bit after around 30 or 40. Opera runs like crap and can't handle more than a dozen.

    Are there any ways I'd be able to optimize this to use as little memory/CPU as possible, and/or run as smoothly as possible on as many browsers as possible? I understand constantly moving 100+ divs is pretty intensive, so any little tips or tweaks would be greatly appreciated.

    A few extra questions:
    - How come this doesn't display at all on Firefox? I added the !DOCTYPE so IE would recognize it.
    - Once divs reach the right edge of the screen, text acts as if the div's width is being shortened by the end of the screen, so it drops down to a new line. Is there a tag to stop the text from being cropped off?

    Thank you very much!

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
    
    <html>
    	<head>
    		<script type="text/javascript">
    			// Line content
    			var numlines = 117, minlength = 14, maxlength = 49;
    			var fontsize = 21; fontsizevariance = 20;
    			var lines;
    			
    			// Line positioning
    			var mintop = 140, maxtop = 490;
    			var linemoves, maxspeed = 14, minspeed = 7;
    			var marginleft = 70, marginright = screen.width - 70;
    			// linemoves: 0 is leftmargin, 1 is speed
    			
    			function initial() {
    				lines = new Array(numlines);
    				linemoves = new Array(numlines);
    				for(var l=0; l<numlines; ++l) {
    					setLine(l);
    				}
    			}
    			
    			function setLine(l) {
    				// Line
    				lines[l] = document.createElement("div");
    				lines[l].setAttribute("class","line");
    				var thisfont = fontsize + ((Math.random()-.5) * fontsizevariance);
    				thisfont*=.84; thisfont=Math.round(thisfont);
    				lines[l].style.fontSize = thisfont + "px";
    				lines[l].style.zIndex = fontsize - thisfont;
    				lines[l].innerText = generateLineContent();
    				
    				// Linemoves
    				linemoves[l] = new Array(2);
    				linemoves[l][0] = 0;
    				linemoves[l][1] = randomBetween(minspeed, maxspeed);
    			}
    			
    			function generateLineContent() {
    				var extralength = randomBetween(minlength, maxlength);
    				var length = minlength + extralength, total="";
    				for(var c=0; c<length; ++c) {
    					total+=String.fromCharCode(randomBetween(33,210));
    				}
    				return total;
    			}
    			
    			function placeLines() {
    				for(var l=0; l<numlines; ++l) {
    					placeLine(l, 1);
    				}
    			}
    			
    			// First is a bool for the first time: if yes, place it randomly along the page. Otherwise spawn on the left.
    			function placeLine(l, first) {
    				var thistop = randomBetween(mintop, maxtop);
    				lines[l].style.top = thistop + "px";
    				if(first) {
    					linemoves[l][0] = randomBetween(-350, marginright);
    					lines[l].style.left = linemoves[l][0] + "px";
    				}
    				else {
    					linemoves[l][0] = -350;
    					lines[l].style.left = -350 + "px";
    				}
    				document.body.appendChild(lines[l]);
    			}
    			
    			function animateLines() {
    				for(var l=0; l<numlines; ++l) {
    					linemoves[l][0] += linemoves[l][1];
    					lines[l].style.left = linemoves[l][0] + "px";
    					
    					if(linemoves[l][0] > screen.width) {
    						document.body.removeChild(lines[l]);
    						setLine(l);
    						placeLine(l,0);
    					}
    				}
    				setTimeout(function() {animateLines()}, 28);
    			}
    			
    			function randomBetween(low, high) {
    				return Math.round(Math.random() * (high - low) ) + low;
    			}
    		</script>
    		<style type="text/css">
    			html, body {
    				margin: 0;
    				padding: 0;
    				font-family: Arial, sans-serif;
    				overflow: hidden;
    			}
    			
    			.line {
    				position: absolute;
    				font-weight: bold;
    				text-overflow: ellipses;
    			}
    		</style>
    	</head>
    	
    	<body onload="initial(); placeLines(); animateLines()">
    		
    	</body>
    </html>

  • #2
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,092
    Thanks
    38
    Thanked 498 Times in 492 Posts
    Your request is unclear to me.

    Is it something like a marquee or banner that moves text across the screen from right to left?
    Are there multiple lines of text (how many) moving or is it just one line moving somewhere across the screen?
    How fast is the movement? How big is the display?
    What is this for?

  • #3
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Sure, let me elaborate. It is like a marquee that moves from left to right, but there are lots of them (in the code above, the number of lines is 117). Each line is a different size and moves at a different speed. The code above should work if you copy+paste it into a blank .html file.

    It's intended to an animated part of a website's landing page, so theoretically all non-mobile displays should be able to run it. On running it should look something like the attached file, and moving to the right.
    Attached Thumbnails Attached Thumbnails Optimizing horizontally scrolling divs-untitled.jpg  
    Last edited by Diogenes; 06-11-2012 at 07:05 PM.

  • #4
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Fun fact: black text on a white background is easier to do than white text on a black background. Here's an updated version of the code; although it's a lot heftier, this is much closer to what the final version is supposed to look like. Just in case anybody wants. Anybody?

    Code:
    <html>
    	<head>
    		<script src="library.js"></script>
    		<script type="text/javascript">
    			// Gibberish content
    			var numgibberish = 96, mingiblength = 14, maxgiblength = 49;
    			var mingibsize = 14, maxgibsize = 35;
    			var giblines, gibcontainer;
    			
    			// Word content
    			var numwords = 7, minwordsize = 21, maxwordsize = 28;
    			var words, wordcontainer;
    			
    			// Gibberish positioning
    			var gibmoves, maxgibspeed = 35, mingibspeed = 21; // technically swapped
    			
    			// Word positioning
    			var wordmoves, maxwordspeed = 49, minwordspeed = 28;
    			
    			function initialGibberish() {
    				giblines = new Array(numgibberish);
    				gibmoves = new Array(numgibberish);
    				for(var g=0; g<numgibberish; ++g) {
    					createGibberish(g);
    					setGibberish(g);
    				}
    				gibcontainer = document.getElementById("gibberishcontainer");
    			}
    			
    			function initialWords() {
    				wordscontainer = document.getElementById("wordscontainer");
    				setLibrary();
    				words = new Array(numwords);
    				wordmoves = new Array(numwords);
    				for(var w=0; w<numwords; ++w) {
    					createWord(w);
    					setWord(w);
    				}
    			}
    			
    			function createGibberish(g) {
    				// Div element
    				giblines[g] = document.createElement("div");
    				giblines[g].setAttribute("class","gibberish");
    				var thisfont = randomBetween(mingibsize, maxgibsize);
    				giblines[g].style.fontSize = thisfont + "px";
    				
    				// Animation
    				gibmoves[g] = new Array(2);
    				
    				// Color
    				colorGibberish(g);
    			}
    			
    			function createWord(w) {
    				// Div element
    				words[w] = document.createElement("div");
    				words[w].setAttribute("class","word");
    				words[w].style.fontSize = randomBetween(minwordsize, maxwordsize);
    				
    				// Animation
    				wordmoves[w] = new Array(2);
    			}
    			
    			function setGibberish(g) {
    				giblines[g].innerText = generateGibberish();
    				
    				gibmoves[g][0] = 0;
    				gibmoves[g][1] = randomBetween(mingibspeed, maxgibspeed);
    			}
    			
    			function setWord(w) {
    				words[w].innerText = getWord(randomBetween(0, librarysize));
    				
    				wordmoves[w][0] = 0;
    				wordmoves[w][1] = randomBetween(minwordspeed, maxwordspeed);
    			}
    			
    			function placeAllGibberish() {
    				for(var g=0; g<numgibberish; ++g)
    					placeGibberish(g,1);
    			}
    			
    			function placeAllWords() {
    				for(var w=0; w<numwords; ++w)
    					placeWord(w, 1);
    			}
    			
    			function placeGibberish(g, first) {
    				giblines[g].style.top = randomBetween(0, 100) + "%";
    				if(first) gibmoves[g][0] = randomBetween(-35, 77);
    				else gibmoves[g][0] = -35;
    				giblines[g].style.left = gibmoves[g][0] + "%";
    				gibcontainer.appendChild(giblines[g]);
    			}
    			
    			function placeWord(w, first) {
    				words[w].style.top = randomBetween(0,96) + "%";
    				if(first) wordmoves[w][0] = randomBetween(-35, 100);
    				else wordmoves[w][0] = -35;
    				words[w].style.left = wordmoves[w][0] + "%";
    				wordscontainer.appendChild(words[w]);
    			}
    			
    			function animateAllGibberish() {
    				for(var g=0; g<numgibberish; ++g)
    					animateGibberish(g);
    			}
    			
    			function animateAllWords() {
    				for(var w=0; w<numwords; ++w)
    					animateWord(w);
    			}
    			
    			function animateGibberish(g) {
    				gibmoves[g][0] += 1;
    				giblines[g].style.left = gibmoves[g][0] + "%";
    				
    				if(gibmoves[g][0] > 100) {
    					setGibberish(g);
    					placeGibberish(g,0);
    				}
    				
    				setTimeout(function() {animateGibberish(g)}, gibmoves[g][1]);
    			}
    			
    			function animateWord(w) {
    				wordmoves[w][0] += 1;
    				words[w].style.left = wordmoves[w][0] + "%";
    				
    				if(wordmoves[w][0] > 100) {
    					setWord(w);
    					placeWord(w,0);
    				}
    				
    				setTimeout(function() {animateWord(w)}, wordmoves[w][1]);
    			}
    			
    			function generateGibberish() {
    				var total="", length = randomBetween(mingiblength, maxgiblength);
    				for(var t=0; t<length; ++t)
    					total+=String.fromCharCode(randomBetween(33,210));
    				return total;
    			}
    			
    			function colorGibberish(g) {
    				var colors = new Array(3);
    				for(var c=0; c<3; ++c)
    					colors[c] = randomBetween(35,70);
    				giblines[g].style.color = "rgb("
    					+ colors[0] + ","
    					+ colors[1] + ","
    					+ colors[2] + ")";
    			}
    			
    			function randomBetween(low, high) {
    				return Math.round(Math.random() * (high - low) ) + low;
    			}
    		</script>
    		<style type="text/css">
    			html, body {
    				margin: 0;
    				padding: 0;
    				font-family: Garamond, "Times New Roman", serif;
    				color: #99cc99;
    				overflow: hidden;
    				background: black;
    			}
    			
    			#header {
    				width: 100%;
    				height: 84px;
    				min-width: 819px;
    				text-align: center;
    				margin: auto;
    				font-size: 70px;
    				font-weight: bold;
    			}
    			
    			#menuout {
    				width: 819px;
    				height: 21px;
    				margin: auto;
    			}
    			
    			#menuin {
    				position: relative;
    				width: 100%;
    				height: 100%;
    				text-align: center;
    				vertical-align: top;
    				background-color: darkgreen;
    				z-index: 70;
    			}
    			
    			.cataround {
    				vertical-align: top;
    				display: inline-block;
    			}
    			
    			.cataround:hover {
    				color: gold;
    			}
    			
    			.category {
    				width: 70px;
    				height: 21px;
    				overflow: hidden;
    			}
    			
    			.category:hover {
    				height: 70px;
    			}
    			
    			.catup {
    				height: 21px;
    			}
    			
    			#mainbody {
    				width: 700px;
    				height: 490px;
    				color: #cccccc;
    				margin: auto;
    				position: relative;
    				z-index: 35;
    			}
    			
    			#maintext {
    				position: absolute;
    				width: 700px;
    				height: 100%;
    			}
    			
    			#wordscontainerout {
    				position: absolute;
    				width: 700px;
    				height: 100%;
    			}
    			
    			#leftdecor {
    				background-color: blue;
    				position: absolute;
    				left: 0;
    				top: 105px;
    				width: 140px;
    				height: 595px;
    			}
    			
    			#rightdecor {
    				background-color: red;
    				position: absolute;
    				right: 0;
    				top: 105px;
    				width: 140px;
    				height: 595px;
    			}
    			
    			#bottomdecor {
    				position: absolute;
    				background-color: gold;
    				top: 700px;
    				width: 100%;
    				height: 70px;
    				bottom: 0;
    			}
    			
    			#gibberishcontainer {
    				position: absolute;
    				top: 105px;
    				height: 490px;
    				right: 140px;
    				left: 140px;
    				overflow: hidden;
    			}
    			
    			#wordscontainer {
    				position: absolute;
    				z-index: -70;
    				width: 100%;
    				height: 100%;
    				overflow: hidden;
    				background-color: rgba(0,0,0,.84);
    			}
    			
    			.word {
    				position: absolute;
    				text-overflow: ellipses;
    				font-weight: bold;
    				color: white;
    			}
    			
    			.gibberish {
    				position: absolute;
    				font-weight: bold;
    				text-overflow: ellipses;
    			}
    		</style>
    	</head>
    	
    	<body onload="setLibrary(); initialGibberish(); initialWords(); placeAllGibberish(); placeAllWords(); animateAllGibberish(); animateAllWords();">
    	
    		<div id="header">Insert Name</div>
    		
    		<div id="menuout">
    			<div id="menuin">
    				
    				<div class="cataround"><div class="category">
    					<div class="catup">Home</div>
    					<div class="catdown">down</div>
    				</div></div>
    				<div class="cataround"><div class="category">
    					<div class="catup">About us</div>
    					<div class="catdown">down</div>
    				</div></div>
    				<div class="cataround"><div class="category">
    					<div class="catup">Features</div>
    					<div class="catdown">down</div>
    				</div></div>
    				<div class="cataround"><div class="category">
    					<div class="catup">Download</div>
    					<div class="catdown">down</div>
    				</div></div>
    				<div class="cataround"><div class="category">
    					<div class="catup">Media</div>
    					<div class="catdown">down</div>
    				</div></div>
    				<div class="cataround"><div class="category">
    					<div class="catup">News</div>
    					<div class="catdown">down</div>
    				</div></div>
    				
    				
    			</div>
    		</div>
    		
    		<div id="mainbody">
    			<div id="maintext"> Main text goes here. </div>
    			<div id="wordscontainerout">
    				<div id="wordscontainer">
    				</div>
    			</div>
    		</div>
    		
    		<div id="leftdecor"></div>
    		<div id="rightdecor"></div>
    		<div id="bottomdecor"></div>
    		
    		<div id="gibberishcontainer"></div>
    		
    	</body>
    </html>
    (Library.js is just a library of different words that can be used for the middle words)

    Code:
    var library, librarysize = 52;
    
    // Instead of using a typical switch statement, be efficient! meh
    function getWord(num) {
    	if(library[num]!=undefined) return library[num];
    	return num;
    }
    
    function setLibrary() {
    	library = new Array(
    	"accept",
    	"allow",
    	"ask",
    	"be",
    	"believe",
    	"borrow",
    	"bring",
    	"buy",
    	"can",
    	"change",
    	"count",
    	"dance",
    	"draw",
    	"drink",
    	"drive",
    	"eat",
    	"explain",
    	"fill",
    	"find",
    	"finish",
    	"fix",
    	"fly",
    	"give",
    	"go",
    	"hear",
    	"learn",
    	"listen",
    	"live",
    	"love",
    	"make",
    	"open",
    	"play",
    	"put",
    	"read",
    	"reply",
    	"say",
    	"see",
    	"sell",
    	"send",
    	"sign",
    	"sing",
    	"speak",
    	"spell",
    	"stand",
    	"start",
    	"succeed",
    	"take",
    	"talk",
    	"teach",
    	"tell",
    	"think",
    	"try",
    	"understand"
    	);
    }

  • #5
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Looks like you have at least ten times as much code there as you really need in order to do what you are after.

    The problem divides into two parts - generating the content for each marquee and then making the marquees operate as marquees.

    The second part of this involves the larger amount of code but that's still only a small fraction of what you have to do it - see http://www.felgall.com/jstip109.htm for an example of the amount of code necessary to create multiple marquees.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #6
    New to the CF scene
    Join Date
    May 2012
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Cool, thank you. I'll try to implement some of the stuff there.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •