Log in

View Full Version : Marquee Scroll with Text and Images updated from Another Document



mkkulkarni
06-23-2019, 05:47 PM
I am looking for a Marquee Scroll which can pick up the content from another Text file on the server. The text should be reloaded after completing one scrolling cycle so that if the text file is updated the new content is automatically displayed in the next scrolling cycle. The format of Text file can be defined by the script. For example it can be like this with HTML tags to properly format the text.


<div><font face="Arial Narrow" size="7"><b><img src="image 1.gif">Message Text 1</b></font></div>
<div><font face="Arial Narrow" size="7"><b><img src="image 2.gif">Message Text 2</b></font></div>
<div><font face="Arial Narrow" size="7"><b><img src="image 3.gif">Message Text 3</b></font></div>
<div><font face="Arial Narrow" size="7"><b><img src="image 4.gif">Message Text 4</b></font></div>
<div><font face="Arial Narrow" size="7"><b><img src="image 5.gif">Message Text 5</b></font></div>
<div><font face="Arial Narrow" size="7"><b><img src="image 6.gif">Message Text 6</b></font></div>

There is a similar example here http://www.dynamicdrive.com/dynamicindex2/ajaxticker.htm which works fine but but it is not really a Marquee. t shows all the messages one by one with fade effect in a box. I need a Marquee which scrolls from right to left like a normal HTML Marquee. Can anybody help?

keyboard
06-24-2019, 02:25 PM
Ok so I hacked something together. Please note it is very rough and should not be used in production. I am writing this at 1AM and there are no comments.
I will clean it up later.
I'll post each piece of code separately, but I'll also attach a zip if you want to just download everything
This is coded in ES6 which should be widely compatible now. If you need backwards compatibility you'll need to change that.

index.html

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="marquee.js"></script>
<link rel="stylesheet" type="text/css" href="marquee.css">
</head>
<body>
<div id="marquee"></div>
</body>
<script type="text/javascript">
let marquee = new Marquee({
"src": "test.txt",
"el": "marquee",
"delay": 3,
"duration": 10
});
</script>
</html>

marquee.js

class Marquee {
constructor(options) {

/*
options:

src:
Path to the text file containing new line delimited text to scroll (path relative from current location)
Default is "text.txt"

duration:
The amount of time in seconds for the text to scroll across the parent div (#marquee by default)
Default is 3 seconds

delay:
The amount of time between each chunk of text starting to scroll
Default is 3 seconds

el:
The ID of the element to put the scrolling text into
If this isn't provided, an element with ID #marquee is added to the page

*/

this.src = options.src || "text.txt";
this.duration = options.duration || 3;
this.delay = (options.delay * 1000) || 3000;

this.index = 0;
this.lines = [];

if(options.el) {
this.el = document.getElementById(options.el);
} else {
this.el = document.createElement("div");
this.el.id = "marquee";
document.body.appendChild(this.el);
}

this.loadFile(this.src);

setInterval(() => {
this.animate();
}, this.delay);

}

loadFile(path) {
//Reset the index
this.index = 0;
let self = this;

//Load the file containing the text with an XMLHTTPRequest
let req = new XMLHttpRequest();
req.overrideMimeType("text/plain");
req.open("GET", `./${path}`, true);
req.onreadystatechange = function() {
//If the request worked
if(req.readyState == 4 && req.status == "200") {
self.lines = req.responseText.split("\n");
}
};
req.send();
}

animate() {
//Only animate if there's text available
if(this.lines.length == 0) {
return;
}

//Create a new div to contain the scrolling text
let textEl = document.createElement("div");
textEl.innerHTML = this.lines[this.index];
textEl.style.cssText = `animation-duration:${this.duration*2}s; -webkit-animation-duration:${this.duration*2}s`;

this.el.appendChild(textEl);

this.index += 1;

//If we've reached the last line in the text file, reload it
if(this.index === this.lines.length) {
this.loadFile(this.src);
}

//Remove the container div once the scrolling text is off-screen
setTimeout(this.removeElement.bind(this, textEl), this.duration * 1000 + 3000);
}

removeElement(textEl) {
this.el.removeChild(textEl);
}
}

marquee.css

@keyframes marquee {
from {
left:100%;
}
to {
left:-100%;
}
}

@-webkit-keyframes marquee {
from {
left:100%;
}
to {
left:-100%;
}
}

#marquee {
background:#AFEEEE;
width:50%;
overflow:hidden;
position:absolute;
height:20px;
}

#marquee div {
position:absolute;
white-space:nowrap;
animation-name:marquee;
animation-timing-function:linear;
animation-iteration-count:infinite;
-webkit-animation-name:marquee;
-webkit-animation-timing-function:linear;
-webkit-animation-iteration-count:infinite;
}

test.txt

<span style="color:blue">Example 1 - Blue</span>
<span style="font-weight:bold">Example 2 - Bold</span>
<span style="font-size:.5em">Example 3 - Small</span>
Example 4 - None

p.s. The font tag you used in your example is widely deprecated now and should not be used.


ZIP FILE
6349

keyboard
06-25-2019, 10:30 AM
Ok, I've cleaned up the code a bit, added comments and fixed a few problems.
I've edited my last post with the updated code (and zip file).
Check the top of marquee.js to see the options available.

Its still not perfect, but it works pretty well.
Let me know if there's any problems.

keyboard

--edit
p.s. It appears that chrome doesn't run animations while the web page is out of focus, so if you switch to a new tab all the text will bunch up.