I am having this problem I want to animate the div from 100% to 0 using velocity js. I want it to animate every time the width not equal 0. The width of the div is updated automatically using setInterval process. This interval process is running forever and will update the width of the div every 3 seconds. The function of velocity js or other animation plugin is to just make it 0% in width.
My code is something like this.
// THIS IS A BIDDING PROCESS
var progressBar = $("#progressBar");
var scenario = 3
var width = 265;
var processDuration = 60000;
var processDelay = 3000;
var time_per_scenario = (processDuration / scenario);
var width_per_processDelay = (width / (processDuration / processDelay));
// Call the animateProgressBar for first time animation;
animateProgressBar();
setInterval(function(){
if(scenario != 0) {
if(time_per_scenario != 0) {
time_per_scenario -= 1000;
width -= width_per_processDelay;
} else {
scenario--;
width = 265;
time_per_scenario = 20000;
animateProgressBar();
}
} else {
scenario = 3;
}
}, processDelay);
function animateProgressBar() {
progressBar.attr("style", "width: " + width);
console.log("animateProgressBar Again with scenario: " + scenario);
if(scenario == 0 ) {
progressBar
.velocity({ width: width}, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario })
.velocity({ width: width }, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario, })
.velocity({ width: width}, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario, });
} else if(scenario == 1 ){
progressBar
.velocity({ width: width }, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario, })
.velocity({ width: width}, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario, });
} else {
progressBar
.velocity({ width: width }, { duration: 1 })
.velocity({ width: 0 }, { duration: time_per_scenario });
}
};
The problem with velocity js is that it just animate 1 time even if it is inside the setInterval process it wont do the animation. Why is it happening?
Finally found the solution.
// THIS IS A BIDDING PROCESS
var progressBar = document.getElementById("progressBar");
var scenario = 3
var width = 265;
var processDuration = 60000;
var processDelay = 3000;
var time_per_scenario = 20000;
var width_per_processDelay = (width / (processDuration / processDelay));
var process = null;
// Call the animateProgressBar for the first animation;
animateProgressBar();
setInterval(function(){
//console.log("time_per_scenario: " + time_per_scenario);
time_per_scenario -= 3000;
width -= width_per_processDelay;
},3000);
setInterval(function(){
if(scenario != 0) {
if(time_per_scenario <= 0) {
clearInterval(process);
scenario--;
width = 265;
time_per_scenario = 20000;
animateProgressBar();
}
} else {
scenario = 3;
}
}, processDelay);
function animateProgressBar() {
var widthAnimation = width;
var width_per_frame = (width / (time_per_scenario / 5));
//console.log("animateProgressBar Again with scenario: " + scenario);
process = setInterval(frame, 5);
var me = this;
function frame() {
if (widthAnimation <= 0) {
clearInterval(process);
} else {
widthAnimation = widthAnimation - width_per_frame;
progressBar.style.width = widthAnimation + 'px';
}
}
};
#progressBar {
height: 20px;
background-color: #ccc;
}
<div id="outerDiv">
<div id="progressBar"></div>
</div>
Thanks for the help #toddmo
Related
I have the vanilla JS code below to fade in each item of an array of HTML elements on scroll, but I would like to refactor my code to have the option to fade an element in only (specifically the '.navmenu' element), but not fade the element out again when the user scrolls back up:
const elementsArr = [
{
elementSelec: '.navmenu',
fadeInInit: 100,
fadeOutInit: document.documentElement.scrollHeight,
initOpacity: 0,
},
{
elementSelec: '#init-element',
fadeInInit: 100,
fadeOutInit: 400,
initOpacity: 0.2,
},
{
elementSelec: '#next-element',
fadeInInit: 500,
fadeOutInit: 900,
initOpacity: 0.2,
},
{
elementSelec: '#last-element',
fadeInInit: 1100,
fadeOutInit: 1700,
initOpacity: 0.2,
},
];
window.addEventListener('scroll', () =>
fadeOnScroll(elementsArr, { fadeLen: 200 })
);
function fadeOnScroll(elementsArr, { fadeLen }) {
const posY = window.scrollY;
for (const element of elementsArr) {
let opacity;
const { elementSelec, fadeInInit, fadeOutInit, initOpacity } = element;
const fadeInEnd = fadeInInit + fadeLen;
const fadeOutEnd = fadeOutInit + fadeLen;
if (fadeInInit < posY && posY < fadeInEnd) {
opacity = (1 - initOpacity) * ((posY - fadeInInit) / fadeLen) + initOpacity;
} else if (fadeInEnd <= posY && posY <= fadeOutInit) {
opacity = 1;
} else if (fadeOutInit < posY && posY < fadeOutEnd) {
opacity = 1 - (1 - initOpacity) * ((posY - fadeOutInit) / fadeLen);
} else {
opacity = initOpacity;
}
document.querySelector(elementSelec).style.opacity = opacity;
}
}
How do you recommend approaching this problem? Thanks.
Ok I'm trying to add every one second a 1% width with a background colour, but it appears in oneblock...
Can someone help me ?
Thank you all
Here is my code :
setTimeout(function() {
var percentage = 1;
for (var i = 0; i < 10; i++) {
var blabla = i + percentage
console.log(blabla)
document.getElementById("position").style.width = blabla + "%";
document.getElementById("position").style.backgroundColor = "blue";
document.getElementById("position").style.height = "20px";
}
}, 1000);
}
Rather than a loop, use setInterval
const increment = 1;
const tick = 1000;
let percent = 0;
const timer = setInterval(() => {
const div = document.querySelector('#position');
percent += increment;
div.style.width = `${percent}%`;
if ( percent >= 100 ) clearInterval(timer);
}, tick);
#position {
background-color: blue;
height: 20px;
width: 1%;
}
<div id="position"></div>
Maybe lets do this for several progress bars.
const timers = [];
const doTimer = (id, { tick = 1000, increment = 1 } = {}) => {
let percent = 0;
timers[id] = setInterval(() => {
const div = document.querySelector(`#${id}`);
percent += increment;
div.style.width = `${percent}%`;
div.innerHTML = `${percent}%`;
if ( percent >= 100 ) clearInterval(timers[id]);
}, tick);
};
doTimer('position');
doTimer('data', { tick: 500 });
doTimer('another', { increment: 5 });
#position, #data, #another {
background-color: blue;
height: 20px;
width: 1%;
}
#data {
background-color: red;
}
#another {
background-color: yellow;
}
<div id="position"></div>
<div id="data"></div>
<div id="another"></div>
document.getElementById("position").style.backgroundColor = "blue";
var i = 0;
function loop(){
i++;
document.getElementById("position").style.width = i+"%";
document.getElementById("position").innerHTML = i+"%";
if(i<10) {
setTimeout(function() {
loop();
}, 1000);
}
}
loop();
<div id="position"></div>
I want to animate a div (say height 50 px and width 50 px) from left to right in the browser.
I can share my html css part here:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.box{
width:100px;
height:100px;
position: absolute;
}
.blue{
background:#00f;
}
.position{
margin-top: 50px;
}
</style>
</head>
<body>
<div class="box blue position" id="move_box"> </div>
<script>
</script>
</body>
</html>
How can I animate the div from left to right according to the condition "moves 10 pixels right and 10 pixels down per second"?
Note: only in JavaScript.
My script:
<script>
var box = document.getElementById('move_box'),
boxPos = 0,
boxLastPos = 0,
boxVelocity = 0.01,
limit = 300,
lastFrameTimeMs = 0,
maxFPS = 60,
delta = 0,
timestep = 1000 / 60,
fps = 60,
framesThisSecond = 0,
lastFpsUpdate = 0,
running = false,
started = false,
frameID = 0;
function update(delta) {
boxLastPos = boxPos;
boxPos += boxVelocity * delta;
// Switch directions if we go too far
if (boxPos >= limit || boxPos <= 0) boxVelocity = -boxVelocity;
}
function draw(interp) {
box.style.left = (boxLastPos + (boxPos - boxLastPos) * interp) + 'px';
box.style.top = (boxLastPos + (boxPos - boxLastPos) * interp) + 'px';
console.log(box.style.top);
}
function panic() {
delta = 0;
}
function begin() {
}
function end(fps) {
/*box.style.backgroundColor = 'blue';*/
}
function stop() {
running = false;
started = false;
cancelAnimationFrame(frameID);
}
function start() {
if (!started) {
started = true;
frameID = requestAnimationFrame(function(timestamp) {
draw(1);
running = true;
lastFrameTimeMs = timestamp;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
frameID = requestAnimationFrame(mainLoop);
});
}
}
function mainLoop(timestamp) {
// Throttle the frame rate.
if (timestamp < lastFrameTimeMs + (1000 / maxFPS)) {
frameID = requestAnimationFrame(mainLoop);
return;
}
delta += timestamp - lastFrameTimeMs;
lastFrameTimeMs = timestamp;
begin(timestamp, delta);
if (timestamp > lastFpsUpdate + 1000) {
fps = 0.25 * framesThisSecond + 0.75 * fps;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
}
framesThisSecond++;
var numUpdateSteps = 0;
while (delta >= timestep) {
update(timestep);
delta -= timestep;
if (++numUpdateSteps >= 240) {
panic();
break;
}
}
draw(delta / timestep);
end(fps);
frameID = requestAnimationFrame(mainLoop);
}
start();
</script>
Check that:
var i = 1;
var div = document.getElementById('move_box');
function myLoop() {
setTimeout(function() {
div.style.top = i * 10 + 'px'
div.style.left = i * 10 + 'px'
i++;
if (i < 5) {
myLoop();
}
}, 1000)
}
myLoop(); // start the loop
.box {
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
}
.blue {
background: #00f;
}
.position {
margin-top: 50px;
}
<div class="box blue position" id="move_box"> </div>
JSFiddle
I tried to re create a Tinder like function.
I found this code :
var win = Titanium.UI.createWindow({
backgroundColor: "#ffffff",
title: "win"
});
// animations
var animateLeft = Ti.UI.createAnimation({
left: -520,
transform: Ti.UI.create2DMatrix({rotate: 60}),
opacity: 0,
duration: 300
});
var animateRight = Ti.UI.createAnimation({
left: 520,
transform: Ti.UI.create2DMatrix({rotate: -60}),
opacity: 0,
duration: 300
});
var curX = 0;
win.addEventListener('touchstart', function (e) {
curX = parseInt(e.x, 10);
});
win.addEventListener('touchmove', function (e) {
if (!e.source.id || e.source.id !== 'oferta') {
return;
}
// Subtracting current position to starting horizontal position
var coordinates = parseInt(e.x, 10) - curX;
// Defining coordinates as the final left position
var matrix = Ti.UI.create2DMatrix({rotate: -(coordinates / 10)});
var animate = Ti.UI.createAnimation({
left: coordinates,
transform: matrix,
duration: 20
});
e.source.animate(animate);
e.source.left = coordinates;
});
win.addEventListener('touchend', function (e) {
if (!e.source.id || e.source.id !== 'oferta') {
return;
}
// No longer moving the window
if (e.source.left >= 75) {
e.source.animate(animateRight);
} else if (e.source.left <= -75) {
e.source.animate(animateLeft);
} else {
// Repositioning the window to the left
e.source.animate({
left: 0,
transform: Ti.UI.create2DMatrix({rotate: 0}),
duration: 300
});
}
});
for (var i = 0; i < 10; i++) {
var wrap = Ti.UI.createView({
"id": 'oferta',
"width": 320,
"height": 400,
"backgroundColor": (i % 2 == 0 ? "red" : "blue")
});
var text = Ti.UI.createLabel({
text: "row: " + i,
color: "black"
});
wrap.add(text);
win.add(wrap);
}
win.open();
But there's a weird behaviour.
Indeed, When I took the wrap view from the top, everythnig is OK but if I put my finger on the bottom on the wrap view, the image becomes crazy..
Try the code and You will see strange behaviour.
I use Titanium SDK 5.2.2
and iOS 9.3.1 on an iPhone 6.
Here s a video showing the weird thing: http://tinypic.com/player.php?v=x37d5u%3E&s=9#.Vx_zDaOLQb0
(Sorry for the video size)
Thanks for your help
Use this code to convert pxToDp and vice versa:
Put following code in your lib folder and include it
with require("measurement")
instead of require("alloy/measurement")
var dpi = Ti.Platform.displayCaps.dpi, density = Ti.Platform.displayCaps.density;
exports.dpToPX = function(val) {
switch (density) {
case "xxxhigh":
return 5 * val;
case "xxhigh":
return 4 * val;
case "xhigh":
return 3 * val;
case "high":
return 2 * val;
default:
return val;
}
};
exports.pxToDP = function(val) {
switch (density) {
case "xxxhigh":
return 5 / val;
case "xxhigh":
return 4 / val;
case "xhigh":
return val / 3;
case "high":
return val / 2;
default:
return val;
}
};
exports.pointPXToDP = function(pt) {
return {
x: exports.pxToDP(pt.x),
y: exports.pxToDP(pt.y)
};
};
Many thanks to all !!! It works using this code ::
var win = Titanium.UI.createWindow({
backgroundColor: "#ffffff",
title: "win"
});
// animations
var animateLeft = Ti.UI.createAnimation({
left: -520,
transform: Ti.UI.create2DMatrix({rotate: 60}),
opacity: 0,
duration: 300
});
var animateRight = Ti.UI.createAnimation({
left: 520,
transform: Ti.UI.create2DMatrix({rotate: -60}),
opacity: 0,
duration: 300
});
Ti.include('measurement.js');
var curX = 0;
var wrap = [];
var topWrap = 100; //(Titanium.Platform.displayCaps.platformHeight - 400) / 2;
var leftWrap = 50; //(Titanium.Platform.displayCaps.platformWidth - 320) / 2;
for (var i = 0; i < 10; i++) {
wrap[i] = Ti.UI.createView({
"id": 'oferta',
"width": Titanium.Platform.displayCaps.platformWidth - 100,
"height": Titanium.Platform.displayCaps.platformHeight - 300,
image:(i % 2 == 0 ? 'principale.png' : 'principale1.png'),
"backgroundColor": (i % 2 == 0 ? "red" : "blue"),
top:topWrap,
left:leftWrap,
});
wrap[i].addEventListener('touchstart', function (e) {
// curX = parseInt(e.x, 10);
curX = pxToDP(parseInt(e.x, 10));
// curY = pxToDP(parseInt(e.Y, 10));
});
wrap[i].addEventListener('touchmove', function (e) {
// Subtracting current position to starting horizontal position
// var coordinates = parseInt(e.x, 10) - curX;
// Defining coordinates as the final left position
var coordinatesX = pxToDP(parseInt(e.x, 10)) - curX;
//var coordinatesY = pxToDP(parseInt(e.y, 10)) - curY;
var matrix = Ti.UI.create2DMatrix({rotate: -(coordinatesX / 10)});
var animate = Ti.UI.createAnimation({
left: coordinatesX,
// top: coordinatesY,
transform: matrix,
duration: 10
});
e.source.animate(animate);
e.source.left = coordinatesX;
// e.source.top = coordinatesY;
});
wrap[i].addEventListener('touchend', function (e) {
// No longer moving the window
if (e.source.left >= 75) {
e.source.animate(animateRight);
} else if (e.source.left <= -75) {
e.source.animate(animateLeft);
} else {
// Repositioning the window to the left
e.source.animate({
left: leftWrap,
transform: Ti.UI.create2DMatrix({rotate: 0}),
duration: 300
});
}
});
win.add(wrap);
}
win.open();
And the measurement.js file is :
var dpi = Ti.Platform.displayCaps.dpi, density = Ti.Platform.displayCaps.density;
function dpToPX(val) {
switch (density) {
case "xxxhigh":
return 5 * val;
case "xxhigh":
return 4 * val;
case "xhigh":
return 3 * val;
case "high":
return 2 * val;
default:
return val;
}
};
function pxToDP(val) {
switch (density) {
case "xxxhigh":
return 5 / val;
case "xxhigh":
return 4 / val;
case "xhigh":
return val / 3;
case "high":
return val / 2;
default:
return val;
}
};
function pointPXToD(pt) {
return {
x: pxToDP(pt.x),
y: pxToDP(pt.y)
};
};
You have to convert px to dp.
var measurement = require('alloy/measurement');
win.addEventListener('touchstart', function (e) {
curX = measurement.pxToDP(parseInt(e.x, 10));
Ti.API.info("touchstart curX: " + curX);
});
...
win.addEventListener('touchmove', function (e) {
if (!e.source.id || e.source.id !== 'oferta') {
return;
}
// Subtracting current position to starting horizontal position
var coordinates = measurement.pxToDP(parseInt(e.x, 10)) - curX;
...
I need my progress bar to last for exactly 20 seconds.
when it completes the bar, it still needs to be able to refresh, like it does now.
I need to be able to put the exact number of seconds in my code.
here's my code:
<div id="pbar_outerdiv">
<div id="pbar_innerdiv"></div>
<!--<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; width: 100%; height: 100%; color: black; font-weight: bold; text-align: center;"></div>-->
</div>
<script>
var timer = 0,
perc = 0,
timeTotal = 2500,
timeCount = 1,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
if(y === "100.000")
window.location.reload(1);
$('#pbar_innerdiv').css("width", x + "%");
//$('#pbar_innertext').text(y + "%");
}
function animateUpdate() {
if(perc < timeTotal) {
perc++;
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
perc = 0;
cFlag = true;
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
$( "#pbar_outerdiv" ).trigger( "click" );
});
</script>
You're using jQuery. Instead of reinventing the wheel, you can do everything you're attempting there with just:
var duration = 20 * 1000; // = 20 seconds
$(document).ready(function() {
$outer = $("#pbar_outerdiv");
$outer.click(function() {
$('#pbar_innerdiv')
.stop()
.css({ width: 0 })
.animate({ width: "100%" }, duration, "linear", function() { window.location.reload(1); });
})
$outer.trigger("click");
});
Working demo