Related
Trying to develop my website and got a problem with a jQuery plugin.
After searching through google 'till the page 9 of the the search, I've found an working JavaScript plugin that simply counts up ( I'll let a link as an exemple, it's as you scroll down a site and it displays a count up effect from 0 to a desired number in a desired amount of time).
It works amazing - and not gonna lie, it's the the only functional one I found in 8 pages of internet- but, if i try to copy+paste the plugin on the site( like, to double it) it blows the first plugin and they interfere with each other ( no matter what number i set the second one to count till, it will count as the first one). Basically, they blow each other up.
Link: https://jsfiddle.net/YWn9t/
My question:
Why is this thing happening? My hand-errors or?
As far as my experience with coding takes me, i know each plugin has some kind of name, like to indentify which is which. May this be the base of the error? Like, i have to change the name of the second? And if yes, which line/ lines should i modify?
Do you have this kind of plugin?
L.E.: Forgot to mention. I use a sitebuilder: WebWave so it must have a css code, html and jv code.
(function($) {
$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});
// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;
return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);
function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));
if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}
if (loopCount >= loops) {
clearInterval(interval);
value = options.to;
if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}
});
};
$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null, // callback method for when the element finishes updating
};
})(jQuery);
jQuery(function($) {
$('.timer').countTo({
from: 50,
to: 2500,
speed: 5000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
.timer {
width: 200px;
margin: 20px auto;
text-align: center;
display: block;
font-size: 20px
}
#help {
width: 500px;
margin: 20px auto;
text-align: center;
display: block;
font-size: 14px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="timer"></span>
<hr/>
<span id="help">From: 50 - To: 2500 / Over 5000 Milli-Seconds</span>
Works for me when I use unique IDs
Remove the display:block to align horizontally
For example
(function($) {
$.fn.countTo = function(options) {
options = $.extend({}, $.fn.countTo.defaults, options || {});
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;
return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);
function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));
if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}
if (loopCount >= loops) {
clearInterval(interval);
value = options.to;
if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}
});
};
$.fn.countTo.defaults = {
from: 0,
to: 100,
speed: 1000,
refreshInterval: 100,
decimals: 0,
onUpdate: null,
onComplete: null,
};
})(jQuery);
jQuery(function($) {
$('#timer1').countTo({
from: 50,
to: 2500,
speed: 5000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
$('#timer2').countTo({
from: 1550,
to: 4500,
speed: 5000,
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
.timer {
width: 200px;
margin: 20px auto;
text-align: center;
font-size: 20px;
padding: 50px;
}
#help {
width: 500px;
margin: 20px auto;
text-align: center;
display: block;
font-size: 14px
}
#container {
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<span class="timer" id="timer1"></span>
<span class="timer" id="timer2"></span>
</div>
<hr/>
<span id="help">From: 50 - To: 2500 / Over 5000 Milli-Seconds</span>
I'm trying to output the final numeric value but formatted in the form of currency to show the currency symbol and commas. I tried integrating a conversion function that I found on here but having some trouble including it in the entire code. I'm quite new to this so please let me know where I went wrong in your comments and what's the best direction to go in.
This is the code for the counter:
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
var a = 0;
$(window).scroll(function () {
var oTop = $('#counter').offset().top - window.innerHeight;
if (a == 0 && $(window).scrollTop() > oTop) {
$('.counter-value').each(function () {
var $this = $(this),
countTo = $this.attr('data-count');
$({
countNum: numberWithCommas.call($this.text())
}).animate({
countNum: countTo
}, {
duration: 2000,
easing: 'swing',
step: function () {
$this.text(Math.floor(this.countNum));
},
complete: function () {
$this.text(this.countNum);
}
});
});
a = 1;
}
});
.counter-value {
font-size: 60px;
line-height: 2em;
text-align: center;
padding: 17px 0;
}
.counter-value:after {
content: attr(data-desc);
display: block;
text-transform: uppercase;
font-size: 14px;
line-height: 1.2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="counter">
<div class="sqs-col sqs-col-4 counter-value" data-count="2500" data-desc="Happy Clients">0</div>
<div class="sqs-col sqs-col-4 counter-value" data-count="1000" data-desc="Projects Completed">0</div>
</div>
as Kawaljit Singh suggest, or simply use toLocaleString()
const nForm = new Intl.NumberFormat('en-EN')
, nFormUSD = new Intl.NumberFormat('en-EN',{style: "currency", currency: "USD"})
, nFormFix2 = v => nForm.format(v.toFixed(2))
;
let ValueX = 1234567.123456;
console.log('Intl.NumberFormat =>', nForm.format(ValueX))
console.log('Intl.NumberFormat USD =>', nFormUSD.format(ValueX))
console.log('Intl.NumberFormat in nFormFix2', nFormFix2(ValueX))
console.log( "x.toLocaleString('en-EN')", ValueX.toLocaleString('en-EN'))
.as-console-wrapper { max-height: 100% !important; top: 0; }
doc :
Country Currency Codes :
-> https://www.iban.com/currency-codes
Intl.NumberFormat.prototype.format() :
-> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/format
Number.prototype.toLocaleString() :
-> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
I've made a simple bar chart plugin which takes some settings and data and displays it as a percentage, it's working perfectly fine in all browsers except IE9-10.
The chart still displays fine yet there is a weird 'jump' once each of the bars have finished animating where the table seems to gain additional height. I've measured the height of the bars in the chart in browsers where it's working fine and there appears to be an additional ~50px height being added in browsers where the weird 'jump' effect occurs.
Here is the relevant CSS:
#barchart {
text-align: center;
}
.bar {
margin-right: 10px;
position: relative;
bottom: 0;
overflow: hidden;
padding-top: 50px;
height: 100%;
}
.bar .label {
text-align: center;
width: inherit;
margin: 0 auto 20px auto;
width: 116px;
}
.bar__value {
height: 0%;
background-repeat: repeat-y;
background-position: top center;
margin: 0 5px;
}
And here is the JS:
var Crafted = (function(c) {
return c;
})(Crafted || {});
(function($, c) {
c.BarChart = (function() {
var barChart = function(target, options, data) {
this.target = target;
this.ChartItem(options);
this.data = data;
this.create();
};
barChart.prototype.ChartItem = function(options) {
var settings = $.extend({
width: '100%',
height: '500px',
usePercentSymbol: false,
delay: 1000,
animSpeed: 1000,
chartImage: '',
chartBgColour: '#CCCCCC'
}, options);
this.width = settings.width;
this.height = settings.height;
this.usePercentSymbol = settings.usePercentSymbol;
this.delay = settings.delay;
this.animSpeed = settings.animSpeed;
this.chartImage = settings.chartImage;
this.chartBgColour = settings.chartBgColour;
return this;
};
barChart.prototype.create = function() {
var _self = this;
if (!_self.target) {
console.error('Error: BarChart \'target\' must be specified');
return;
}
if (!_self.data) {
console.error('Error: BarChart \'data\' must be provided');
return;
}
var $barChart = $('<table></table>').attr('id', 'barchart');
var $charts = $('<tr></tr>').addClass('data-row');
$charts.appendTo($barChart);
$barChart.appendTo(_self.target);
$barChart.attr('width', _self.width)
.attr('height', _self.height);
$.each(_self.data, function(index, value) {
var $chart = $('<td></td>')
.addClass('bar')
.attr('valign', 'bottom')
.attr('data-percent', value.percent);
$chart.appendTo($charts);
var $chartLabel = $('<div></div>').addClass('label');
$chartLabel.appendTo($chart);
var $chartValue = $('<div></div>').addClass('label__percent').text(_self.usePercentSymbol ? '0%' : 0);
$chartValue.appendTo($chartLabel);
var $chartTitle = $('<div></div>').addClass('label__title').text(value.label);
$chartTitle.appendTo($chartLabel);
var $barValue = $('<div></div>').addClass('bar__value');
var barStyle = _self.chartImage ?
'background-image:url(\'' + _self.chartImage + '\');' :
'background-color:' + _self.chartBgColour
$barValue.attr('style', barStyle);
$barValue.appendTo($chart);
});
setTimeout(function() {
$('.bar').each(function() {
var percentage = $(this).attr('data-percent');
var $percentLbl = $(this).find('.label__percent');
$(this).children('.bar__value').animate({
height: percentage + '%'
}, _self.animSpeed);
$({
countNum: 0
}).animate({
countNum: percentage
}, {
duration: _self.animSpeed,
easing: 'linear',
progress: function() {
var currentValue = Math.floor(this.countNum);
$percentLbl.text(_self.usePercentSymbol ? currentValue + '%' : currentValue);
}
});
});
}, _self.delay);
};
return barChart;
})();
})(jQuery, Crafted);
$(function() {
(function(c) {
var settings = {
width: '800px',
height: '400px',
usePercentSymbol: true,
delay: 200,
animSpeed: 1000,
chartImage: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/662693/chimney.svg'
};
var data = [{
label: 'MANCHESTER',
percent: 78
}, {
label: 'BIRMINGHAM',
percent: 69
}, {
label: 'LONDON',
percent: 94
}, {
label: 'CARDIFF',
percent: 39
}, {
label: 'GLASGOW',
percent: 54
}, {
label: 'BELFAST',
percent: 35
}]
var barChart = new c.BarChart('#barChart', settings, data);
})(Crafted);
});
I have a JsFiddle that demonstrates the problem. If you load this in IE9/10 (you can use the browser emulator in IE dev tools - F12) you will see the strange effect I'm talking about. This doesn't occur in IE11/Edge etc...
Could it be due to the padding top applied to the <td> elements? This is used to give enough spacing for each chart label to prevent them from being cut off.
try with this css modification to bar class
.bar {
margin-right: 10px;
position: relative;
bottom: 0;
overflow: hidden;
padding-top: 50px;
height: 75%;
}
seems it works either on ie9/10 and chrome
I'm doing this plugin that takes the words and makes them pulsate on the screen:
First they appear and grow, then they vanish, change place and again appear
Working plugin:
+ function($) {
var Pulsate = function(element) {
var self = this;
self.element = element;
self.max = 70;
self.min = 0;
self.speed = 500;
self.first = true;
self.currentPlace;
self.possiblePlaces = [
{
id: 0,
top: 150,
left: 150,
},
{
id: 1,
top: 250,
left: 250,
},
{
id: 2,
top: 350,
left: 350,
},
{
id: 3,
top: 250,
left: 750,
},
{
id: 4,
top: 450,
left: 950,
}
];
};
Pulsate.prototype.defineRandomPlace = function() {
var self = this;
self.currentPlace = self.possiblePlaces[Math.floor(Math.random() * self.possiblePlaces.length)];
if(!self.possiblePlaces) self.defineRandomPlace;
self.element.css('top', self.currentPlace.top + 'px');
self.element.css('left', self.currentPlace.left + 'px');
};
Pulsate.prototype.animateToZero = function() {
var self = this;
self.element.animate({
'fontSize': 0,
'queue': true
}, self.speed, function() {
self.defineRandomPlace();
});
};
Pulsate.prototype.animateToRandomNumber = function() {
var self = this;
self.element.animate({
'fontSize': Math.floor(Math.random() * (70 - 50 + 1) + 50),
'queue': true
}, self.speed, function() {
self.first = false;
self.start();
});
};
Pulsate.prototype.start = function() {
var self = this;
if (self.first) self.defineRandomPlace();
if (!self.first) self.animateToZero();
self.animateToRandomNumber();
};
$(window).on('load', function() {
$('[data-pulsate]').each(function() {
var element = $(this).data('pulsate') || false;
if (element) {
element = new Pulsate($(this));
element.start();
}
});
});
}(jQuery);
body {
background: black;
color: white;
}
.word {
position: absolute;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.9);
font-size: 0px;
}
.two {
position: absolute;
color: white;
left: 50px;
top: 50px;
}
div {
margin-left: 0px;
}
<span class="word" data-pulsate="true">Love</span>
<span class="word" data-pulsate="true">Enjoy</span>
<span class="word" data-pulsate="true">Huggs</span>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
If you notice i define the places that the word can grow in the self.possiblePlaces, and if you notice the animation, sometimes more then one word can grow in one place, my goal coming here is ask for help. How I can make two words never grow in the same place??
I was trying to do like this:
In the defineRandomPlace i pick a random object inside my possiblePlaces array:
Pulsate.prototype.defineRandomPlace = function() {
var self = this;
self.currentPlace = self.possiblePlaces[Math.floor(Math.random() * self.possiblePlaces.length)];
if(!self.possiblePlaces) self.defineRandomPlace;
delete self.possiblePlaces[self.currentPlace.id];
self.element.css('top', self.currentPlace.top + 'px');
self.element.css('left', self.currentPlace.left + 'px');
};
Notice the delete, first i clone the chosen object, after I delete it but keep his place in the array.
After the animation was over, I put the object in the array again, before starting all over again:
Pulsate.prototype.animateToZero = function() {
var self = this;
self.element.animate({
'fontSize': 0,
'queue': true
}, self.speed, function() {
self.possiblePlaces[self.currentPlace.id] = self.currentPlace;
self.defineRandomPlace();
});
But it made no difference.
Thanks!!
Pen: http://codepen.io/anon/pen/waooQB
In your example, you are randomly picking from a list that has five members, and you have three separate words that could be displayed, putting chance of overlap fairly high.
A simple approach to resolve is to pick the first item in the list, remove it from the list, and the append to the end of the list each time. Because you have more positions in the lists than items selecting from it, you're guaranteed to never collide.
Share the same list possiblePlaces between all instances.
Shift the first item off the queue, and push it onto the end when its done each time, instead of selecting randomly in defineRandomPlace.
Snippet highlighting #2:
// shift a position off the front
self.currentPlace = possiblePlaces.shift();
self.element.css('top', self.currentPlace.top + 'px');
self.element.css('left', self.currentPlace.left + 'px');
// push it back on the end
possiblePlaces.push(self.currentPlace);
If you want it truly random, you'll need to randomly select and remove an item from the array, and not put it back into the array until after it's been used. You'll also need to always ensure that you have more possiblePlaces than you have dom elements to place on the page.
Like so:
Pulsate.prototype.defineRandomPlace = function() {
var self = this;
var newPlace = possiblePlaces.splice(Math.floor(Math.random()*possiblePlaces.length), 1)[0];
if (self.currentPlace) {
possiblePlaces.push(self.currentPlace);
}
self.currentPlace = newPlace;
self.element.css('top', self.currentPlace.top + 'px');
self.element.css('left', self.currentPlace.left + 'px');
};
See http://codepen.io/anon/pen/bdBBPE
My decision is to divide the page to imaginary rows and to prohibit more than one word in the same row. Please check this out.
Note: as the code currently does not support recalculating of rows count on document resize, the full page view will not display correctly. Click "reload frame" or try JSFiddle or smth.
var pulsar = {
// Delay between words appearance
delay: 400,
// Word animation do not really depend on pulsar.delay,
// but if you set pulsar.delay small and wordAnimationDuration long
// some words will skip their turns. Try 1, 2, 3...
wordAnimationDuration: 400 * 3,
// Depending on maximum font size of words we calculate the number of rows
// to which the window can be divided
maxFontSize: 40,
start: function () {
this.computeRows();
this.fillWords();
this.animate();
},
// Calculate the height or row and store each row's properties in pulsar.rows
computeRows: function () {
var height = document.body.parentNode.clientHeight;
var rowsCount = Math.floor(height/this.maxFontSize);
this.rows = [];
for (var i = 0; i < rowsCount; i++) {
this.rows.push({
index: i,
isBusy: false
});
}
},
// Store Word instances in pulsar.words
fillWords: function () {
this.words = [];
var words = document.querySelectorAll('[data-pulsate="true"]');
for (var i = 0; i < words.length; i++) {
this.words.push(new Word(words[i], this.wordAnimationDuration, this.maxFontSize));
}
},
// When it comes time to animate another word we need to know which row to move it in
// this random row should be empty at the moment
getAnyEmptyRowIndex: function () {
var emptyRows = this.rows.filter(function(row) {
return !row.isBusy;
});
if (emptyRows.length == 0) {
return -1;
}
var index = emptyRows[Math.floor(Math.random() * emptyRows.length)].index;
this.rows[index].isBusy = true;
return index;
},
// Here we manipulate words in order of pulsar.words array
animate: function () {
var self = this;
this.interval = setInterval(function() {
var ri = self.getAnyEmptyRowIndex();
if (ri >= 0) {
self.words.push(self.words.shift());
self.words[0].animate(ri, function () {
self.rows[ri].isBusy = false;
});
}
}, this.delay);
}
}
function Word (span, duration, maxFontSize) {
this.span = span;
this.inAction = false;
this.duration = duration;
this.maxFontSize = maxFontSize;
}
/**
* #row {Numer} is a number of imaginary row to place the word into
* #callback {Function} to call on animation end
*/
Word.prototype.animate = function (row, callback) {
var self = this;
// Skip turn if the word is still busy in previous animation
if (self.inAction) {
return;
}
var start = null,
dur = self.duration,
mfs = self.maxFontSize,
top = row * mfs,
// Random left offset (in %)
left = Math.floor(Math.random() * 90),
// Vary then font size within half-max size and max size
fs = mfs - Math.floor(Math.random() * mfs / 2);
self.inAction = true;
self.span.style.top = top + 'px';
self.span.style.left = left + '%';
function step (timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
// Calculate the factor that will change from 0 to 1, then from 1 to 0 during the animation process
var factor = 1 - Math.sqrt(Math.pow(2 * Math.min(progress, dur) / dur - 1, 2));
self.span.style.fontSize = fs * factor + 'px';
if (progress < dur) {
window.requestAnimationFrame(step);
}
else {
self.inAction = false;
callback();
}
}
window.requestAnimationFrame(step);
}
pulsar.start();
body {
background: black;
color: white;
}
.word {
position: absolute;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.9);
font-size: 0px;
/* To make height of the .word to equal it's font size */
line-height: 1;
}
<span class="word" data-pulsate="true">Love</span>
<span class="word" data-pulsate="true">Enjoy</span>
<span class="word" data-pulsate="true">Huggs</span>
<span class="word" data-pulsate="true">Peace</span>
I updated your plugin constructor. Notice the variable Pulsate.possiblePlaces, I have changed the variable declaration this way to be able to share variable data for all Object instance of your plugin.
var Pulsate = function(element) {
var self = this;
self.element = element;
self.max = 70;
self.min = 0;
self.speed = 500;
self.first = true;
self.currentPlace;
Pulsate.possiblePlaces = [
{
id: 0,
top: 150,
left: 150,
},
{
id: 1,
top: 250,
left: 250,
},
{
id: 2,
top: 350,
left: 350,
},
{
id: 3,
top: 250,
left: 750,
},
{
id: 4,
top: 450,
left: 950,
}
];
};
I added occupied attribute to the possible places to identify those that are already occupied. If the randomed currentPlace is already occupied, search for random place again.
Pulsate.prototype.defineRandomPlace = function() {
var self = this;
self.currentPlace = Pulsate.possiblePlaces[Math.floor(Math.random() * Pulsate.possiblePlaces.length)];
if(!Pulsate.possiblePlaces) self.defineRandomPlace;
if (!self.currentPlace.occupied) {
self.currentPlace.occupied = true;
self.element.css('top', self.currentPlace.top + 'px');
self.element.css('left', self.currentPlace.left + 'px');
} else {
self.defineRandomPlace();
}
};
Every time the element is hidden, set the occupied attribute to false.
Pulsate.prototype.animateToZero = function() {
var self = this;
self.element.animate({
'fontSize': 0,
'queue': true
}, self.speed, function() {
self.currentPlace.occupied = false;
self.defineRandomPlace();
});
};
A small hint f = 0.5px x = 100px t = 0.5s
x / f = 200
200/2 * t * 0.5 = f(shrink->expand until 100px square) per 0.5 seconds
I'm trying to find a very simple and smooth, lightweight javascript or jquery marquee. I already tried silk marquee or something, but it wouldn't work with the application I was using. So the simpler and shorter, the better - and easier to debug. Does anybody know of a easy to implement javascript replacement for the marquee?
Pastebin
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
var tWidth='300px'; // width (in pixels)
var tHeight='25px'; // height (in pixels)
var tcolour='#ffffcc'; // background colour:
var moStop=true; // pause on mouseover (true or false)
var fontfamily = 'arial,sans-serif'; // font for content
var tSpeed=3; // scroll speed (1 = slow, 5 = fast)
// enter your ticker content here (use \/ and \' in place of / and ' respectively)
var content='Are you looking for loads of useful information <a href="http:\/\/javascript.about.com\/">About Javascript<\/a>? Well now you\'ve found it.';
var cps=-tSpeed; var aw, mq; var fsz = parseInt(tHeight) - 4; function startticker(){if (document.getElementById) {var tick = '<div style="position:relative;width:'+tWidth+';height:'+tHeight+';overflow:hidden;background-color:'+tcolour+'"'; if (moStop) tick += ' onmouseover="cps=0" onmouseout="cps=-tSpeed"'; tick +='><div id="mq" style="position:absolute;right:0px;top:0px;font-family:'+fontfamily+';font-size:'+fsz+'px;white-space:nowrap;"><\/div><\/div>'; document.getElementById('ticker').innerHTML = tick; mq = document.getElementById("mq"); mq.style.right=(10+parseInt(tWidth))+"px"; mq.innerHTML='<span id="tx">'+content+'<\/span>'; aw = document.getElementById("tx").offsetWidth; lefttime=setInterval("scrollticker()",50);}} function scrollticker(){mq.style.right = (parseInt(mq.style.right)>(-10 - aw)) ?
mq.style.right = parseInt(mq.style.right)+cps+"px": parseInt(tWidth)+10+"px";} window.onload=startticker;
</script>
</head>
<body>
<div id="ticker">
this is a simple scrolling text!
</div>
</body>
</html>
hiya simple demo from recommendations in above comments: http://jsfiddle.net/FWWEn/
with pause functionality on mouseover: http://jsfiddle.net/zrW5q/
hope this helps, have a nice one, cheers!
html
<h1>Hello World!</h1>
<h2>I'll marquee twice</h2>
<h3>I go fast!</h3>
<h4>Left to right</h4>
<h5>I'll defer that question</h5>
Jquery code
(function($) {
$.fn.textWidth = function(){
var calc = '<span style="display:none">' + $(this).text() + '</span>';
$('body').append(calc);
var width = $('body').find('span:last').width();
$('body').find('span:last').remove();
return width;
};
$.fn.marquee = function(args) {
var that = $(this);
var textWidth = that.textWidth(),
offset = that.width(),
width = offset,
css = {
'text-indent' : that.css('text-indent'),
'overflow' : that.css('overflow'),
'white-space' : that.css('white-space')
},
marqueeCss = {
'text-indent' : width,
'overflow' : 'hidden',
'white-space' : 'nowrap'
},
args = $.extend(true, { count: -1, speed: 1e1, leftToRight: false }, args),
i = 0,
stop = textWidth*-1,
dfd = $.Deferred();
function go() {
if(!that.length) return dfd.reject();
if(width == stop) {
i++;
if(i == args.count) {
that.css(css);
return dfd.resolve();
}
if(args.leftToRight) {
width = textWidth*-1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if(args.leftToRight) {
width++;
} else {
width--;
}
setTimeout(go, args.speed);
};
if(args.leftToRight) {
width = textWidth*-1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
go();
return dfd.promise();
};
})(jQuery);
$('h1').marquee();
$('h2').marquee({ count: 2 });
$('h3').marquee({ speed: 5 });
$('h4').marquee({ leftToRight: true });
$('h5').marquee({ count: 1, speed: 2 }).done(function() { $('h5').css('color', '#f00'); })
I've made very simple function for marquee. See: http://jsfiddle.net/vivekw/pHNpk/2/
It pauses on mouseover & resumes on mouseleave. Speed can be varied. Easy to understand.
function marquee(a, b) {
var width = b.width();
var start_pos = a.width();
var end_pos = -width;
function scroll() {
if (b.position().left <= -width) {
b.css('left', start_pos);
scroll();
}
else {
time = (parseInt(b.position().left, 10) - end_pos) *
(10000 / (start_pos - end_pos)); // Increase or decrease speed by changing value 10000
b.animate({
'left': -width
}, time, 'linear', function() {
scroll();
});
}
}
b.css({
'width': width,
'left': start_pos
});
scroll(a, b);
b.mouseenter(function() { // Remove these lines
b.stop(); //
b.clearQueue(); // if you don't want
}); //
b.mouseleave(function() { // marquee to pause
scroll(a, b); //
}); // on mouse over
}
$(document).ready(function() {
marquee($('#display'), $('#text')); //Enter name of container element & marquee element
});
I just created a simple jQuery plugin for that. Try it ;)
https://github.com/aamirafridi/jQuery.Marquee
The following works:
http://jsfiddle.net/xAGRJ/4/
The problem with your original code was you are calling scrollticker() by passing a string to setInterval, where you should just pass the function name and treat it as a variable:
lefttime = setInterval(scrollticker, 50);
instead of
lefttime = setInterval("scrollticker()", 50);
Why write custom jQuery code for Marquee... just use a plugin for jQuery - marquee() and use it like in the example below:
First include :
<script type='text/javascript' src='//cdn.jsdelivr.net/jquery.marquee/1.3.1/jquery.marquee.min.js'></script>
and then:
//proporcional speed counter (for responsive/fluid use)
var widths = $('.marquee').width()
var duration = widths * 7;
$('.marquee').marquee({
//speed in milliseconds of the marquee
duration: duration, // for responsive/fluid use
//duration: 8000, // for fixed container
//gap in pixels between the tickers
gap: $('.marquee').width(),
//time in milliseconds before the marquee will start animating
delayBeforeStart: 0,
//'left' or 'right'
direction: 'left',
//true or false - should the marquee be duplicated to show an effect of continues flow
duplicated: true
});
If you can make it simpler and better I dare you all people :). Don't make your life more difficult than it should be. More about this plugin and its functionalities at: http://aamirafridi.com/jquery/jquery-marquee-plugin
I made my own version, based in the code presented above by #Tats_innit .
The difference is the pause function. Works a little better in that aspect.
(function ($) {
var timeVar, width=0;
$.fn.textWidth = function () {
var calc = '<span style="display:none">' + $(this).text() + '</span>';
$('body').append(calc);
var width = $('body').find('span:last').width();
$('body').find('span:last').remove();
return width;
};
$.fn.marquee = function (args) {
var that = $(this);
if (width == 0) { width = that.width(); };
var textWidth = that.textWidth(), offset = that.width(), i = 0, stop = textWidth * -1, dfd = $.Deferred(),
css = {
'text-indent': that.css('text-indent'),
'overflow': that.css('overflow'),
'white-space': that.css('white-space')
},
marqueeCss = {
'text-indent': width,
'overflow': 'hidden',
'white-space': 'nowrap'
},
args = $.extend(true, { count: -1, speed: 1e1, leftToRight: false, pause: false }, args);
function go() {
if (!that.length) return dfd.reject();
if (width <= stop) {
i++;
if (i <= args.count) {
that.css(css);
return dfd.resolve();
}
if (args.leftToRight) {
width = textWidth * -1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if (args.leftToRight) {
width++;
} else {
width=width-2;
}
if (args.pause == false) { timeVar = setTimeout(function () { go() }, args.speed); };
if (args.pause == true) { clearTimeout(timeVar); };
};
if (args.leftToRight) {
width = textWidth * -1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
timeVar = setTimeout(function () { go() }, 100);
return dfd.promise();
};
})(jQuery);
usage:
for start: $('#Text1').marquee()
pause: $('#Text1').marquee({ pause: true })
resume: $('#Text1').marquee({ pause: false })
My text marquee for more text,
and position absolute enabled
http://jsfiddle.net/zrW5q/2075/
(function($) {
$.fn.textWidth = function() {
var calc = document.createElement('span');
$(calc).text($(this).text());
$(calc).css({
position: 'absolute',
visibility: 'hidden',
height: 'auto',
width: 'auto',
'white-space': 'nowrap'
});
$('body').append(calc);
var width = $(calc).width();
$(calc).remove();
return width;
};
$.fn.marquee = function(args) {
var that = $(this);
var textWidth = that.textWidth(),
offset = that.width(),
width = offset,
css = {
'text-indent': that.css('text-indent'),
'overflow': that.css('overflow'),
'white-space': that.css('white-space')
},
marqueeCss = {
'text-indent': width,
'overflow': 'hidden',
'white-space': 'nowrap'
},
args = $.extend(true, {
count: -1,
speed: 1e1,
leftToRight: false
}, args),
i = 0,
stop = textWidth * -1,
dfd = $.Deferred();
function go() {
if (that.css('overflow') != "hidden") {
that.css('text-indent', width + 'px');
return false;
}
if (!that.length) return dfd.reject();
if (width <= stop) {
i++;
if (i == args.count) {
that.css(css);
return dfd.resolve();
}
if (args.leftToRight) {
width = textWidth * -1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if (args.leftToRight) {
width++;
} else {
width--;
}
setTimeout(go, args.speed);
};
if (args.leftToRight) {
width = textWidth * -1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
go();
return dfd.promise();
};
// $('h1').marquee();
$("h1").marquee();
$("h1").mouseover(function () {
$(this).removeAttr("style");
}).mouseout(function () {
$(this).marquee();
});
})(jQuery);
Responsive resist jQuery marquee simple plugin. Tutorial:
// start plugin
(function($){
$.fn.marque = function(options, callback){
// check callback
if(typeof callback == 'function'){
callback.call(this);
} else{
console.log("second argument (callback) is not a function");
// throw "callback must be a function"; //only if callback for some reason is required
// return this; //only if callback for some reason is required
}
//set and overwrite default functions
var defOptions = $.extend({
speedPixelsInOneSecound: 150, //speed will behave same for different screen where duration will be different for each size of the screen
select: $('.message div'),
clickSelect: '', // selector that on click will redirect user ... (optional)
clickUrl: '' //... to this url. (optional)
}, options);
//Run marque plugin
var windowWidth = $(window).width();
var textWidth = defOptions.select.outerWidth();
var duration = (windowWidth + textWidth) * 1000 / defOptions.speedPixelsInOneSecound;
var startingPosition = (windowWidth + textWidth);
var curentPosition = (windowWidth + textWidth);
var speedProportionToLocation = curentPosition / startingPosition;
defOptions.select.css({'right': -(textWidth)});
defOptions.select.show();
var animation;
function marquee(animation){
curentPosition = (windowWidth + defOptions.select.outerWidth());
speedProportionToLocation = curentPosition / startingPosition;
animation = defOptions.select.animate({'right': windowWidth+'px'}, duration * speedProportionToLocation, "linear", function(){
defOptions.select.css({'right': -(textWidth)});
});
}
var play = setInterval(marquee, 200);
//add onclick behaviour
if(defOptions.clickSelect != '' && defOptions.clickUrl != ''){
defOptions.clickSelect.click(function(){
window.location.href = defOptions.clickUrl;
});
}
return this;
};
}(jQuery));
// end plugin
Use this custom jQuery plugin as bellow:
//use example
$(window).marque({
speedPixelsInOneSecound: 150, // spped pixels/secound
select: $('.message div'), // select an object on which you want to apply marquee effects.
clickSelect: $('.message'), // select clicable object (optional)
clickUrl: 'services.php' // define redirection url (optional)
});
Marquee using CSS animations.
`<style>
.items-holder {
animation: moveSlideshow 5s linear infinite;
}
.items-holder:hover {
animation-play-state: paused;
}
#keyframes moveSlideshow {
100% {
transform: translateX(100%);
}
}
</style>`
I try use only css for it this link.
<style>
.header {
background: #212121;
overflow: hidden;
height: 65px;
position: relative;
}
.header div {
display: flex;
flex-direction: row;
align-items: center;
overflow: hidden;
height: 65px;
transform: translate(100%, 0);
}
.header div * {
font-family: "Roboto", sans-serif;
color: #fff339;
text-transform: uppercase;
text-decoration: none;
}
.header div img {
height: 60px;
margin-right: 20px;
}
.header .ticker-wrapper__container{
display: flex;
flex-direction: row;
align-items: center;
position: absolute;
top: 0;
right: 0;
animation: ticker 30s infinite linear forwards;
}
.header:hover .ticker-wrapper__container{
animation-play-state: paused;
}
.ticker-wrapper__container a{
display: flex;
margin-right: 60px;
align-items: center;
}
#keyframes ticker {
0% {
transform: translate(100%, 0);
}
50% {
transform: translate(0, 0);
}
100% {
transform: translate(-100%, 0);
}
}
</style>