I'm trying to make fade out effect for a div with pure JavaScript.
This is what I'm currently using:
//Imagine I want to fadeOut an element with id = "target"
function fadeOutEffect()
{
var fadeTarget = document.getElementById("target");
var fadeEffect = setInterval(function() {
if (fadeTarget.style.opacity < 0.1)
{
clearInterval(fadeEffect);
}
else
{
fadeTarget.style.opacity -= 0.1;
}
}, 200);
}
The div should fade out smoothly, but it immediately disappears.
What's wrong? How can I solve it?
jsbin
Initially when there's no opacity set, the value will be an empty string, which will cause your arithmetic to fail. That is, "" < 0.1 == true and your code goes into the clearInterval branch.
You can default it to 1 and it will work.
function fadeOutEffect() {
var fadeTarget = document.getElementById("target");
var fadeEffect = setInterval(function () {
if (!fadeTarget.style.opacity) {
fadeTarget.style.opacity = 1;
}
if (fadeTarget.style.opacity > 0) {
fadeTarget.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 200);
}
document.getElementById("target").addEventListener('click', fadeOutEffect);
#target {
height: 100px;
background-color: red;
}
<div id="target">Click to fade</div>
An empty string seems like it's treated as a 0 by JavaScript when doing arithmetic and comparisons (even though in CSS it treats that empty string as full opacity)
> '' < 0.1
> true
> '' > 0.1
> false
> '' - 0.1
> -0.1
Simpler Approach
We can now use CSS transitions to make the fade out happen with a lot less code
const target = document.getElementById("target");
target.addEventListener('click', () => target.style.opacity = '0');
// If you want to remove it from the page after the fadeout
target.addEventListener('transitionend', () => target.remove());
#target {
height: 100px;
background-color: red;
transition: opacity 1s;
}
<p>Some text before<p>
<div id="target">Click to fade</div>
<p>Some text after</p>
Just this morning I found this piece of code at http://vanilla-js.com, it's very simple, compact and fast:
var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();
You can change the speed of the fade changing the second parameter in the setTimeOut function.
var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();
#thing {
background: red;
line-height: 40px;
}
<div id="thing">I will fade...</div>
It looks like you can do it another way(I may be wrong).
event.target.style.transition = '0.8s';
event.target.style.opacity = 0;
you can use CSS transition property rather than doing vai timer in javascript. thats more performance oriented compared to what you are doing.
check
http://fvsch.com/code/transition-fade/test5.html#test3
In addition to the accepted answer, we now have WAAPI which basically adds animation API to JavaScript.
For example,
/**
* #returns {Object}
*/
function defaultFadeConfig() {
return {
easing: 'linear',
iterations: 1,
direction: 'normal',
fill: 'forwards',
delay: 0,
endDelay: 0
}
}
/**
* #param {HTMLElement} el
* #param {number} durationInMs
* #param {Object} config
* #returns {Promise}
*/
async function fadeOut(el, durationInMs, config = defaultFadeConfig()) {
return new Promise((resolve, reject) => {
const animation = el.animate([
{ opacity: '1' },
{ opacity: '0', offset: 0.5 },
{ opacity: '0', offset: 1 }
], {duration: durationInMs, ...config});
animation.onfinish = () => resolve();
})
}
/**
* #param {HTMLElement} el
* #param {number} durationInMs
* #param {Object} config
* #returns {Promise}
*/
async function fadeIn(el, durationInMs, config = defaultFadeConfig()) {
return new Promise((resolve) => {
const animation = el.animate([
{ opacity: '0' },
{ opacity: '0.5', offset: 0.5 },
{ opacity: '1', offset: 1 }
], {duration: durationInMs, ...config});
animation.onfinish = () => resolve();
});
}
window.addEventListener('load', async ()=> {
const el = document.getElementById('el1');
for(const ipsum of "Neque porro quisquam est qui dolorem ipsum quia dolor \uD83D\uDE00".split(' ')) {
await fadeOut(el, 1000);
el.innerText = ipsum;
await fadeIn(el, 2000);
}
});
.text-center {
text-align: center;
}
<h1 id="el1" class="text-center">...</h1>
function fadeOutEffect() {
var fadeTarget = document.getElementById("target");
var fadeEffect = setInterval(function () {
if (!fadeTarget.style.opacity) {
fadeTarget.style.opacity = 1;
}
if (fadeTarget.style.opacity > 0) {
fadeTarget.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 200);
}
document.getElementById("target").addEventListener('click', fadeOutEffect);
#target {
height: 100px;
background-color: red;
}
<div id="target">Click to fade</div>
my solution
function fadeOut(selector, timeInterval, callback = null) {
var fadeTarget = document.querySelector(selector);
let time = timeInterval / 1000;
fadeTarget.style.transition = time + 's';
fadeTarget.style.opacity = 0;
var fadeEffect = setInterval(function() {
if (fadeTarget.style.opacity <= 0)
{
clearInterval(fadeEffect);
if (typeof (callback) === 'function') {
callback();
}
}
}, timeInterval);
}
While most of the solutions in this and other SO threads work, here are my two cents. If you want to rely only on pure JS ONLY then this should do the trick:
function fadeOutEle(el) {
el.style.opacity = 1;
(function fade() {
if ((el.style.opacity -= .009) < 0) {
el.style.display = "none";
} else {
requestAnimationFrame(fade);
}
})();
};
The Key here is the el.style.opacity -= .009 which give a cool fade out effect. Keep it below 1/2 a second (0.009 in this case) so that the effect is visible before the element hides.
Related
So when animating the element, I'm using calc to apply a multiplier (which is a custom property) to the animation duration, and then I change the multiplier in Javscript. The problem is that when the CSS property gets updated the animation is reset and the motion is not smooth. I doubt that there's a fix for this (if I keep using css animation) but hopefully someone will come through.
Here's the code:
function setMultiplier() {
document.documentElement.style.setProperty(
"--animation-multiplier",
Math.random() * 2
);
setTimeout(setMultiplier, 2000);
}
setMultiplier();
:root {
--animation-multiplier: 1;
}
div {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
#keyframes spin {
50% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}
span {
background: #049;
display: inline-block;
width: 20vh;
height: 20vh;
animation: spin calc(10s / var(--animation-multiplier)) linear infinite;
}
<div>
<span></span>
</div>
EDIT:
Well, this was already supposed to be a 2 day project, so gave up on it and just wrote this shirty code. All these lines to replace 6 lines of css (or JS's animate function. Tried that one too and got the same result):
function animate() {
let sign = 1
const cores = []
for (let i = 1; i <= 11; i++) {
const layer = document.getElementById(`core-layer-${i}`)
const duration = parseInt(layer.getAttribute('data-animation-duration'))
const dpf = 360.0 / (duration / 1000.0) / fps
const opf = (duration / 1000.0) / fps
let animation
if (i === 8) {
animation = null
} else if (i === 9) {
animation = 'opacity'
} else {
animation = 'rotation'
}
sign *= -1
cores.push({
layer: layer,
dpf: dpf * sign,
opf: opf,
animationValue: 0.0,
animation: animation,
alternate: [1, 7].includes(i),
})
}
function tick() {
cores.forEach(core => {
if (core.animation === null) {
return
} else if (core.animation === 'opacity') {
core.animationValue += core.opf * activeAnimationMultiplier
core.layer.style.opacity = Math.sin(core.animationValue / 2)
} else if (core.animation === 'rotation') {
core.animationValue = core.animationValue + core.dpf * activeAnimationMultiplier
core.layer.style.transform = `rotate(${core.animationValue}deg)`
if (core.animationValue > 360.0) {
core.dpf = Math.abs(core.dpf) * -1
} else if (core.animationValue < 0.0) {
core.dpf = Math.abs(core.dpf)
}
}
})
if (Math.abs(activeAnimationMultiplier - animationMultiplier) > 0.05) {
const diff = animationMultiplier - activeAnimationMultiplier
activeAnimationMultiplier += Math.roundf(0.05 * (diff / Math.abs(diff)))
}
setTimeout(tick, 1000.0 / fps)
}
tick()
}
EDIT 2:
Got rid of the JS too. Used Synfig to create the animation (mp4) and played that in a video tag. Results: CPU usage down to ~0.5% from ~2.5% and GPU usage down to ~4% from ~10%.
How can I create the CSS animation below in JavaScript? I've looked all over Google, and tried multiple times to create this but I couldn't figure out how to do this.
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 100;
}
}
To run this, I know I can use what is shown below, but I don't know how to create this animation. Can anyone help?
element.style.animation = "fadeIn 5s linear";
You can use javascript with transition to achieve it
// start frame
const start = {
opacity: 0
};
// end frame
const end = {
opacity: 1
};
const element = document.querySelector('span');
Object.assign(element.style, start);
element.style.transition = 'all 5s linear';
requestAnimationFrame(() => {
Object.assign(element.style, end);
});
<span>Lorem Ipsum</span>
What do you mean exactly with "Create in Javascript"? Without using CSS?
If so, you can use a simple interval to update the opacity of the element until it reached 0 or 100. Simple example:
let opacity = 0;
const fadeEl = document.getElementById("fadeInElementIdWithOpacity0");
const fadeInInterval = setInterval(() => {
if (opacity < 1) {
opacity = opacity + 0.1
fadeEl.style.opacity = opacity;
} else {
clearInterval(fadeInInterval);
}
}, 200);
You can first define this function with whatever amount of intervals that you want and then call it with any querySelector
function fadeIn(x) {
var fade = document.querySelector(x);
var opacity = 0;
var intervalID = setInterval(function() {
if (opacity < 1) {
opacity = opacity + 0.1
fade.style.opacity = opacity;
} else {
clearInterval(intervalID);
}
}, 200);
}
havnig this function in console and running fadeIn(".-logo") will fade in the stackoverflow's logo
I have a sentence where I fade in one word and replace it with another from an array. However, since the words all vary in length, the sentence width abruptly changes and it results in a choppy transition.
How can I animate the width change? I tried adding a transition to the container of the sentence in css but that didn't work. I applied the transition as 1.5s all linear, so it should be animating the width as well as everything else whenever there is change. Any ideas?
$(function() {
var hello = ['dynamic', 'a', 'aklsjdlfajklsdlkf', 'asdf'];
var used = ['dynamic'];
var greeting = $('#what');
var item;
function hey() {
item = hello[Math.floor(Math.random() * hello.length)];
if (hello.length != used.length) {
while (jQuery.inArray(item, used) != -1) {
item = hello[Math.floor(Math.random() * hello.length)];
}
used.push(item);
} else {
used.length = 0;
item = hello[Math.floor(Math.random() * hello.length)];
used.push(item);
}
greeting.html(item);
greeting.animate({
"opacity": "1"
}, 1500);
}
window.setInterval(function() {
greeting.animate({
"opacity": "0"
}, 1500);
setTimeout(hey, 1500)
}, 5000);
});
#sentence {
transition: 1.5s all linear;
}
#what {
font-style: italic;
text-decoration: underline;
color: red;
}
<p id="sentence">
This is a sentence that has <span id="what">dynamic</span> text that alters width.
</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
EDIT: Sorry if I was unclear, I only want to fade out the word, not the entire sentence. I'm trying to animate the width to fit the new word. I don't want to change/add any elements, just solve with the current tags in place.
function dataWord () {
$("[data-words]").attr("data-words", function(i, d){
var $self = $(this),
$words = d.split("|"),
tot = $words.length,
c = 0;
// CREATE SPANS INSIDE SPAN
for(var i=0; i<tot; i++) $self.append($('<span/>',{text:$words[i]}));
// COLLECT WORDS AND HIDE
$words = $self.find("span").hide();
// ANIMATE AND LOOP
(function loop(){
$self.animate({ width: $words.eq( c ).width() });
$words.stop().fadeOut().eq(c).fadeIn().delay(1000).show(0, loop);
c = ++c % tot;
}());
});
}
// dataWord(); // If you don't use external fonts use this on DOM ready; otherwise use:
$(window).on("load", dataWord);
p{text-align: center;font-family: 'Open Sans Condensed', sans-serif;font-size: 2em;}
/* WORDS SWAP */
[data-words]{
vertical-align: top;
position: static;
}
[data-words] > span{
position: absolute;
color: chocolate;
}
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
We provide
<span data-words="code|solutions|design"></span>
for your business.
</p>
<p>
You ordered
<span data-words="1|3|28"></span>
<b>big</b>
<span data-words="salad|macs|chips"></span>
</p>
When you set new word for your sentence, you can save #what width and then make an animation with this width too. Like this:
// declare as global variable and update when you set new word
var width = greeting.css('width');
// animation
greeting.animate({
"opacity": "0", "width": width
}, 1500, function(){
});
I have had the same problem and went with a different approach, not fading but typing: jsfiddle demo
function type($el, text, position) {
if (text.length >= position) {
var rchars = 'qbvol'; // typo chars
if (position % 3 == 0 && Math.random() > .85) { // insert typo!
var typo;
var chr = text.substr(position, 1);
if (chr == chr.toUpperCase()) { typo = chr.toLowerCase(); }
else { typo = rchars.substr(Math.floor(Math.random() * rchars.length), 1); }
$el.text(text.substring(0, position - 1) + typo + '_');
setTimeout(function() { type($el, text, position - 1); }, 200)
}
else {
$el.text(text.substring(0, position) + '_');
setTimeout(function() { type($el, text, position + 1); }, 150)
}
}
else {
setTimeout(function() { $el.text(text); }, 400)
}
}
It basically inserts your new text on the page, with a nice caret and typo to make it look like someone is typing it.
Try this out:- http://jsfiddle.net/adiioo7/c8fFU/13/
You can update the sentence effect depending upon your requirement. Currently it is using fadein/fadeout.
JS:-
$(function () {
var hello = ['jupiter', 'a', 'aklsjdlfajklsdlkf', 'asdf'];
var used = ['jupiter'];
var greeting = $('#what');
var item;
var sentence = $('#sentence');
function hey() {
item = hello[Math.floor(Math.random() * hello.length)];
if (hello.length != used.length) {
while (jQuery.inArray(item, used) != -1) {
item = hello[Math.floor(Math.random() * hello.length)];
}
used.push(item);
} else {
used.length = 0;
item = hello[Math.floor(Math.random() * hello.length)];
used.push(item);
}
greeting.html(item);
greeting.animate({
"opacity": "1"
}, 1500);
sentence.fadeIn(1500);
}
window.setInterval(function () {
sentence.fadeOut(1500);
greeting.animate({
"opacity": "0"
}, 1500);
setTimeout(hey, 1500);
}, 5000);
});
I have a box with text within that scrolling up like the old known marquee tag.
I am using the jquery scrollbox that I found on this website:
http://wmh.github.io/jquery-scrollbox/
now, in my css file I want to replace the ul & il tags with classes, say: .list_wrapper would be instead of ul, and .list would be instead of li, so far so good...
after modifying the css, the scroller stopped to work, i found that i need to modify the "jquery.scrollbox.js" file too, but my knowledge in js is basic.
my page:
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="/js/jquery.scrollbox.js" type="text/javascript"></script>
<style type="text/css">
#marquee {
height: 180px;
overflow: hidden;
margin: 0;
}
#marquee .list_wrapper {
width: 165px;
line-height: 25px;
list-style-type: none;
padding: 5;
margin: 0;
overflow: hidden;
}
#marquee .list {
overflow: hidden;
}
</style>
<script type="text/javascript">
$(function () {
$('#marquee').scrollbox({
linear: true,
step: 1,
delay: 0,
speed: 65
});
});
</script>
</head>
<body>
<div id="marquee">
<div class="list_wrapper">
<div class="list">• text 1</div>
<div class="list">• text 2</div>
<div class="list">• text 3</div>
<div class="list">• text 4</div>
<div class="list">• text 5</div>
<div class="list">• text 6</div>
</div>
</body>
</html>
heres ths js file (I think there's something to do with the "('ul:first-child') and ('li:first-child'):
/*!
* jQuery Scrollbox
* (c) 2009-2013 Hunter Wu <hunter.wu#gmail.com>
* MIT Licensed.
*
* http://github.com/wmh/jquery-scrollbox
*/
(function($) {
$.fn.scrollbox = function(config) {
//default config
var defConfig = {
linear: false, // Scroll method
startDelay: 2, // Start delay (in seconds)
delay: 3, // Delay after each scroll event (in seconds)
step: 5, // Distance of each single step (in pixels)
speed: 32, // Delay after each single step (in milliseconds)
switchItems: 1, // Items to switch after each scroll event
direction: 'vertical',
distance: 'auto',
autoPlay: true,
onMouseOverPause: true,
paused: false,
queue: null
};
config = $.extend(defConfig, config);
config.scrollOffset = config.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
if (config.queue) {
config.queue = $('#' + config.queue);
}
return this.each(function() {
var container = $(this),
containerUL,
scrollingId = null,
nextScrollId = null,
paused = false,
backward,
forward,
resetClock,
scrollForward,
scrollBackward;
if (config.onMouseOverPause) {
container.bind('mouseover', function() { paused = true; });
container.bind('mouseout', function() { paused = false; });
}
containerUL = container.children('ul:first-child');
scrollForward = function() {
if (paused) {
return;
}
var curLi,
i,
newScrollOffset,
scrollDistance,
theStep;
curLi = containerUL.children('li:first-child');
scrollDistance = config.distance !== 'auto' ? config.distance :
config.direction === 'vertical' ? curLi.height() : curLi.width();
// offset
if (!config.linear) {
theStep = Math.max(3, parseInt((scrollDistance - container[0][config.scrollOffset]) * 0.3, 10));
newScrollOffset = Math.min(container[0][config.scrollOffset] + theStep, scrollDistance);
} else {
newScrollOffset = Math.min(container[0][config.scrollOffset] + config.step, scrollDistance);
}
container[0][config.scrollOffset] = newScrollOffset;
if (newScrollOffset >= scrollDistance) {
for (i = 0; i < config.switchItems; i++) {
if (config.queue && config.queue.hasChildNodes() && config.queue.getElementsByTagName('li').length > 0) {
containerUL.append(config.queue.getElementsByTagName('li')[0]);
containerUL.remove(containerUL.children('li:first-child'));
} else {
containerUL.append(containerUL.children('li:first-child'));
}
}
container[0][config.scrollOffset] = 0;
clearInterval(scrollingId);
if (config.autoPlay) {
nextScrollId = setTimeout(forward, config.delay * 1000);
}
}
};
// Backward
// 1. If forwarding, then reverse
// 2. If stoping, then backward once
scrollBackward = function() {
if (paused) {
return;
}
var curLi,
i,
liLen,
newScrollOffset,
scrollDistance,
theStep;
// init
if (container[0][config.scrollOffset] === 0) {
liLen = containerUL.children('li').length;
for (i = 0; i < config.switchItems; i++) {
containerUL.children('li:last-child').insertBefore(containerUL.children('li:first-child'));
}
curLi = container.children('li:first-child');
scrollDistance = config.distance !== 'auto' ?
config.distance :
config.direction === 'vertical' ? curLi.height() : curLi.width();
container[0][config.scrollOffset] = scrollDistance;
}
// new offset
if (!config.linear) {
theStep = Math.max(3, parseInt(container[0][config.scrollOffset] * 0.3, 10));
newScrollOffset = Math.max(container[0][config.scrollOffset] - theStep, 0);
} else {
newScrollOffset = Math.max(container[0][config.scrollOffset] - config.step, 0);
}
container[0][config.scrollOffset] = newScrollOffset;
if (newScrollOffset === 0) {
clearInterval(scrollingId);
if (config.autoPlay) {
nextScrollId = setTimeout(forward, config.delay * 1000);
}
}
};
forward = function() {
clearInterval(scrollingId);
scrollingId = setInterval(scrollForward, config.speed);
};
backward = function() {
clearInterval(scrollingId);
scrollingId = setInterval(scrollBackward, config.speed);
};
resetClock = function(delay) {
config.delay = delay || config.delay;
clearTimeout(nextScrollId);
if (config.autoPlay) {
nextScrollId = setTimeout(forward, config.delay * 1000);
}
};
if (config.autoPlay) {
nextScrollId = setTimeout(forward, config.startDelay * 1000);
}
// bind events for container
container.bind('resetClock', function(delay) { resetClock(delay); });
container.bind('forward', function() { clearTimeout(nextScrollId); forward(); });
container.bind('backward', function() { clearTimeout(nextScrollId); backward(); });
container.bind('speedUp', function(speed) {
if (typeof speed === 'undefined') {
speed = Math.max(1, parseInt(config.speed / 2, 10));
}
config.speed = speed;
});
container.bind('speedDown', function(speed) {
if (typeof speed === 'undefined') {
speed = config.speed * 2;
}
config.speed = speed;
});
});
};
}(jQuery));
thank you!
open jquery-scrollbox.js and try to change by the hand (not automatically) all ul&li tag on div tag
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>