I am using datatables with a custom plugin I got from here fnSetFilteringDelay but wanted to add an indicator or loader of some sort to tell the user when the search will happen on the typed text in the filter textbox. I have done this but it is a bit buggy, maybe someone can help me to get this fluent and beautiful.
But if you type more and more, the indicator bar starts to look like it is shattering.
I would like to get rid of the shattering part if possible.
Here is my code after initialising the datatables to variable oTable
oTable.fnSetFilteringDelay(550); //After the last character is entered, will take 550 milliseconds to search
$('#gvProjectList_filter input').parent().append($("<div id='lder' style='width: 0px; height: 30px; background-color: #999; float:right;'></div>"));
$('#gvProjectList_filter input').on('keyup', function (a) {
document.getElementById("lder").style.width = "50px"; //Start the indicator at 50px and end at 0px
var count = 550; //Same as the filtering delay set above
var counter = setInterval(timer, 25); //will run it every 25 millisecond
function timer() {
count -= 25; //Minus 25 milliseconds
if (count <= 0) {
clearInterval(counter);
document.getElementById("lder").style.width = "0px";
return;
}
var neww = parseInt((count / 550) * 50); //calculate the new width vs. time left of 550ms
document.getElementById("lder").style.width = neww + "px";
}
});
Basically it must start at 50px width, and go down, when the user types another character, the bar must start at 50px again.
Here is my jsFiddle demo, just type something to search, first one letter and then a whole name, you will see what I mean.
I have found my own solution. I have made use of the jquery animate function
oTable.fnSetFilteringDelay(550);
$('#mytable_filter input').parent().append($("<div id='lder' style='width: 0px; height: 20px; background-color: #999; float:right;'></div>"));
$('#mytable_filter input').on('keyup', function (a) {
$("#lder").width('50px');
$("#lder").stop().animate({width:'0px'},550);
});
works like a charm!
Here is the final Fiddle, check it out!
Related
I'm trying to create a border that slowly wraps around the screen. As part of this process, I'm playing around with only increasing the height of the border right now by using the setInterval method. However, I can't get the border height to increase slowly. Below is what I'm doing:
var i = 1;
setBorder = setInterval(borderAnimation(), 200);
function borderAnimation() {
var border = document.getElementById("border-animation");
border.style.height = i + "vh";
i = i + 1;
document.write(i);
if(i = 100){
clearInterval(setBorder);
}
}
document.write(2);
If I change the variable i inside the function to say 5, then the height changes to that number so I know the function is being called at least once.
Similarly, document.write(i) prints only once. So if i is 1, then in the screen I see only 1; it also does not print 2 at any time even though I have document.write(2). Why is this?
After this, I intend to make it so that another div is called that goes around the top (this one is left), then another on the right then another around bottom, thus completing a border that goes around the screen. If someone has a better idea or way of achieving this, please let me know as well.
There are a couple mistakes:
1: pass the function reference (don't call the function) to setInterval
2: if(i = 100) should be if(i == 100)
var i = 1;
setBorder = setInterval(borderAnimation, 200);
function borderAnimation() {
var border = document.getElementById("border-animation");
border.style.height = i + "vh";
i = i + 1;
console.log(i);
if(i == 20){
clearInterval(setBorder);
}
}
#border-animation{
position: absolute;
width: 200px;
border: 1px solid #333;
}
<div id="border-animation"><div>
I'm trying to highlight some text in a div, with the highlight being a fixed line in said text. So far I've got a very simple solution that uses two divs, one that houses the text, and the other acting as the highlight, and as you scroll the text, it will pass through the highlight div.
HTML is as follows:
<div id="test">
text...
</div>
<div id="highlight"></div>
CSS is:
#highlight {
position: fixed;
top: 50%;
width: 100%;
background-color: #ccff00;
height: 30px;
opacity: 0.6;
}
#test{
position: absolute;
font-size: 30px;
top: 50%;
}
A demo of it can be found here
I was wondering if anyone knows how to make it so that scrolling the text can be done in a way where as a user scrolls, the next line becomes highlighted. Currently it scrolls normally, so the highlight may miss a line, or not highlight a complete line. Additionally, I was wondering how it would be best to make the text scroll all the way to the bottom. Would adding a margin of the same size as the offset at the top work? Alternative solutions for any of this would be appreciated as well.
Try adding an event listener to the window on scroll. Then calculate the offset by taking the scrollY % line-height and set the highlight top margin to the negative of that value.
JavaScript below:
var highlight = document.querySelector("#highlight");
window.addEventListener('scroll', function(e){
var y = window.scrollY;
var offset = y % 30;
highlight.style.marginTop = - y % 30 + "px";
});
See Working Fiddle
Not sure if this
https://jsfiddle.net/ok0x3apo/6/ is what you're looking for
You can see that I'm remodifying the entered text, to get line by line highlight as page scrolls.
var el = document.getElementById("text"),
content = el.innerHTML.replace(/ |^\s+|\s+$/g,""),
lines = content.split(/\./);
var html = "";
for(var i in lines){
html+="<p class='clear_display' id='id_"+i+"'>"+lines[i]+".</p>";
};
document.getElementById("text").innerHTML=html;
You can make changes to the "clear_display" class on how you prefer to have the text block.
function calledEveryScroll() {
var scrollPosition = $(window).scrollTop();
for(var i in lines){
var currentSection = document.querySelector("#id_"+i+"");
var sectionTop = currentSection.offsetTop;
if (scrollPosition<=0){
$(".clear_display").removeClass('active');
document.querySelector("#id_0").className += " active";
}
if (scrollPosition >= sectionTop-50) {
$(".clear_display").removeClass('active');
if (!$(currentSection).hasClass('active')) {
$(currentSection).addClass('active');
if(previous){
if(currentSection.offsetTop==previous.offsetTop){
$(previous).addClass('active');
}
}
var previous = currentSection;
}
//return false;
}
}
}
function resizing(){
var offset =100;
var bottom = $(window).height()-offset;
$('#text').css('margin-bottom',bottom);
}
This function checks each line when page scrolls.For the scroll to reach the bottom I'm calculating the margin-bottom.Hope it helps.
I want to make a div slide (in,out,left,up,right or down) when I reach a specific scrollTop() value. However, I don't want it to trigger some animation... I want the div to move with the scroll, like the effect achieved here: http://www.tioluchin.com/
so far, the "closest" I got was this:
var vistaEstandar = document.getElementById('vista');
vistaEstandar.onscroll = function() {animacionesEstandarVista()};
function animacionesEstandarVista()
{
var ypos = vistaEstandar.scrollTop;
if (($(window).width() >= 1800 && vistaEstandar.scrollTop > 6053) || ($(window).width() > 1800 && document.documentElement.scrollTop > 6053)) {
var image= document.getElementById("seccion9textoSegundo");
var toppin = ypos/6053;
image.style.top = toppin*150 + 'px';
}
else
{};
However, this doesn't work because the value I manage to set is too low.
The web I am trying to put together is long so when I multiply the value it is either too high or too low.
In the website http://www.tioluchin.com/ I want the effect the knives and food have
I went into that source code because it made me curious. I have found how they do it.
First part is catching what happens on scroll
$(document).scroll(function(){
windowScroll()
});
They have there a condition which disables it on smaller screens but that is not important here.
Second part is this:
function windowScroll(){
var st = $(document).scrollTop();
$("#aff").css({"top": 32 - st * 0.15 + "px"});
$("#aff").css({"left": 48 - st * 0.15 + "px"});
}
They have it bigger, for more elements. And this is my playground. In principle you have start with current position as an offset. "st" indicates how deep you are. st*0.15 tells you how fast the element will run from the screen.
My HTML:
<div class="wrapper">
<div id="aff" class="moving-div">
</div>
And CSS:
.moving-div {
width: 3rem;
height: 3rem;
position: relative;
top: 2rem;
left: 3rem;
background: red;
}
.wrapper {
height: 1000px;
}
How would I go about adjusting the time manually based on the scroll position? What might that look like? To basically 'scroll' the tween? So that the tween reacts to the scrolling mouse's Y position rather than just trigger and execute based on a preset time?
IMHO, here is what you'll need to do:
You will need TimelineMax for sequencing your animations. Place
your animations in TimelineMax as you like them to be.
You'll need to figure out the maximum scroll position your window can scroll up to, beforehand. (This can also be re-calculated on browser resize as well but I haven't taken this into account in my example below). You can figure out with the
help of this answer. Also read the comments on that answer.
Upon scroll, you'll need to convert the current scroll position of
your window object into percentage that is: var currentScrollProgress=window.scrollY/maxScroll; such that your currentScrollProgress should always be between 0 and 1.
TimelineMax has a progress() method which takes values ranging
from 0 and 1 where 0 being the initial state of the animations
and 1 being the final state. Feed this currentScrollProgress
into it and you're done.
OR, you can tween the timeline itself that is: TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease});.
Code used in my example is as follows:
HTML:
<div> </div>
<div> </div>
...
CSS:
html, body { margin: 0; padding: 0; }
div { width: 100%; height: 60px; margin: 2px 0; }
div:nth-child(odd) { background: #cc0; }
div:nth-child(even) { background: #0cc; }
JavaScript:
/*global TweenMax, TimelineMax,Power2*/
var myDIVs=document.querySelectorAll('div'),numDIVs=myDIVs.length;
var timeline=new TimelineMax({paused:true}),duration=.4,ease=Power2.easeOut,staggerFactor=.1,scrollTweenDuration=.4;
var scrollTimeout=null,scrollTimeoutDelay=20,currentScrollProgress=0;
var maxScroll=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight)-window.innerHeight; //see [https://stackoverflow.com/a/17698713/3344111]
function init(){
initTimeline();
listenToScrollEvent();
onScroll();
}
function initTimeline(){
for(var i=0; i<numDIVs; i+=1){ timeline.fromTo(myDIVs[i],duration,{opacity:0},{opacity:1,ease:ease},i*staggerFactor); }
}
function listenToScrollEvent(){
(window.addEventListener)?window.addEventListener('scroll',debounceScroll,false):window.attachEvent('onscroll',debounceScroll);
}
function debounceScroll(){
clearTimeout(scrollTimeout);
scrollTimeout=setTimeout(onScroll,scrollTimeoutDelay);
}
function onScroll(){
currentScrollProgress=roundDecimal(window.scrollY/maxScroll,4);
//timeline.progress(currentScrollProgress); // either directly set the [progress] of the timeline which may produce a rather jumpy result
TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease}); // or tween the [timeline] itself to produce a transition from one state to another i.e. it looks smooth
}
function roundDecimal(value,place){ return Math.round(value*Math.pow(10,place))/Math.pow(10,place); }
//
init();
Here is the resulting jsFiddle. Hope it helps.
T
While Tahir's answer is correct and sufficient, there's a lot of unnecessary code to show the example.
A more concise snippet is:
var max_scroll = document.body.offsetHeight - window.innerHeight;
win.addEventListener('scroll', function(){
var scroll_perc = parseFloat(Math.min(window.pageYOffset / max_scroll, 1).toFixed(2));
TweenMax.to(tl, 0, {
progress: scroll_perc
});
});
var tl = new TimelineMax({paused: true});
// the rest of your timeline....
I'm trying to make some DOM element rotate smoothly around a fixed point. I'm writing this from scratch using jQuery and no matter what update speed I choose for the setInterval or how small I go with the amount of degrees the orbit advances on each loop, I get this janky staircase animation effect. I've tried using jquery's .animate instead of the .css hoping it would smooth things out but I cant seem to get it to work. Any help is appreciated.
In other words, it's not as smooth as rotating an image in HTML5 canvas. I want to make it smoother.
Here is a jsFiddle demonstrating the issue.
Notice how the animation is not quite smooth?
For reference, here is the code:
HTML
<div id="div"></div>
<div class="dot"></div>
<button class="stop">STOP</button>
<button class="start">START</button>
CSS
#div{
position:absolute;
height: 20px;
width: 20px;
background-color: #000;
}
.dot{
position:absolute;
width: 5px;
height: 5px;
background-color: #000;
}
button{
position:absolute;
}
.stop{
top:200px;
}
.start{
top:225px;
}
THE ALL IMPORTANT JAVASCRIPT
$(document).ready(function(){
$('#div').data('angle', 90);
var interval;
$('.stop').on('click', function(){
if(interval){
clearInterval(interval);
interval = undefined;
}
});
$('.start').on('click', function(){
if(!interval){
interval = setBoxInterval();
}
});
interval = setBoxInterval();
});
function drawOrbitingBox(degrees){
var centerX = 100,
centerY = 100,
div = $('#div'),
orbitRadius = 50;
//dot might not be perfectly centered
$('.dot').css({left:centerX, top:centerY});
//given degrees (in degrees, not radians), return the next x and y coords
function coords(degrees){
return {left:centerX + (orbitRadius * Math.cos((degrees*Math.PI)/180)),
top :centerY - (orbitRadius * Math.sin((degrees*Math.PI)/180))};
}
//increment the angle of the object and return new coords through coords()
function addDegrees(jqObj, degreeIncrement){
var newAngle = jqObj.data('angle') + degreeIncrement;
jqObj.data('angle', newAngle);
return coords(newAngle);
}
//change the left and top css property to simulate movement
// I've tried changing this to .animate() and using the difference
// between current and last position to no avail
div.css(addDegrees(div, degrees), 1);
}
function setBoxInterval(){
var interval = window.setInterval(function(){
drawOrbitingBox(-0.2); //This is the degree increment
}, 10); //This is the amount of time it takes to increment position by the degree increment
return interval;
}
I'd rather not resort to external libraries/plugins but I will if that's the accepted way of doing this kind of stuff. Thank you for your time.
That's because the value you set for top and left properties is rounded up. You should try using CSS Transforms.
Combining CSS Animations/Transitions and CSS Transforms you should also be able to get the animation without JavaScript.
Oh, I run into that myself!
There is actually nothing you can do, the stuttering you see is the pixel size. The pixel is the minimal step for css based animations, you can't do "half pixels" or "0.2 pixels". You will see that the same keeps happening with css3 animations.
The only solution is to speed up your animation, i'm afraid.
Also, cosndsider using rquestAnimationFrame instead of interval: https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame