create a soundbar with Angularjs - javascript

I looked into different solutions, such as this one that I improved with a button : http://jsfiddle.net/3mhJJ/.
$(".button").click(function(){
$(".bar").each(function(i) {fluctuate($(this));});
});
I would like to be able to pause the recording, and also to stop the animation when the sound is over ( I didn't include it, but just imagine the sound lasts 10 seconds)
I have never worked with jQuery, but I am familiar with AngularJS, do you think there is any way for me to do this only with JQuery or by mixing JQuery and AngularJS together?
Otherwise, I'd like to recreate something like Soundcloud but I am not sure how hard it is.
Thanks for advices.

Not entirely sure that I understood what you're after but here's how to start/stop the animation:
http://jsfiddle.net/kyysdo4n/2/ (updated to include an auto-stop feature)
var stopAnimation = false;
var closeTimeoutHandle = null;
function fluctuate(bar) {
if(stopAnimation){
return;
}
var amplitude = Math.random() * 10;
console.log(amplitude);
var height = amplitude * 4;
//Animate the equalizer bar repeatedly
bar.animate({
height: height
}, function() {
fluctuate($(this));
});
}
$("#btnStart").click(function(i) {
stopAnimation = false;
fluctuate($('.bar'));
closeTimeoutHandle = setTimeout(function(){
stopAnimation = true;
}, 10 * 1000); //10 seconds
});
$("#btnStop").click(function(i) {
stopAnimation = true;
fluctuate($('.bar'));
// clear the timeout so that if the user starts the animation again
// it doesn't get stopped when the initial timeout gets called
if(closeTimeoutHandle){
clearTimeout(closeTimeoutHandle);
}
});
I'm not sure if this helps .. if it doesn't then please add more details, maybe more code ?

Related

How to evenly time fading transitions?

so I'm trying to create a simple slide show from scratch, and so far I was able to get full screen images to fade out and fade in infinetly, but for some odd reason using setInterval(function(){fade(var)}, 3500);didn't work, maybe someone can explain why the first and last images took way longer than 3,5 seconds to fade. Meanwhile, I was trying to solve that problem by implementing a callback function in the fade(). My example has four images, and they start fading out until it reaches image one, then don't fade out image one and start fading back in image two until image 4, and do this forever, here is my recent attempt to implement a callback function:
var i = 4;
$(document).ready(function(){
fade(i, fade);
});
var fadeIN = false;
function fade(objectID, callbackfn){
var fadeTime = 3500;
if(!fadeIN){
$("#slide-"+objectID).fadeOut(fadeTime);
i--;
if(i === 1) {
fadeIN = true;
}
}
else{
i++;
$("#slide-"+objectID).fadeIn(fadeTime);
if(i === 4){
fadeIN = false;
}
}
if(arguments[1]){
callbackfn(i);
}
}
But that is not working, it fades out image 4, image 3 and stops on image 2. Maybe there is a way to evenly time the fading transitions using the setIntervel(), if so can someone tell me how? Appreciate any help.
Here is a JSFiddle to the code: http://jsfiddle.net/8kgc0chq/ it is not working tho.
Here is the doc for .fadeOut()
There is an optional argument complete:
A function to call once the animation is complete.
Put the next animation in there, they too take a complete (callback) function.
$("#id").fadeOut(fadeTime, function() {
// code to execute after animation complete
});
You need to do it properly with javascript. Easy way fails after last element.
So here is my solution. Can it be improved further, I think yes.. But it does work now. And is future proof to some extent.
I cleaned up css and changed html structure a little.
Demo: http://jsfiddle.net/8kgc0chq/3/
$(document).ready(function () {
$(window).resize(function () {
realTimeHeight();
});
realTimeHeight();
startSlides();
});
function startSlides() {
var fadeTime = 1000,
delay = 1300,
i = 0,
slides = $("#hero-slider > .slide"),
len = slides.length;
slides.hide();
var pF = $('<div class="slide">'), pB = pF.clone();
pF.attr('id', slides.eq(i).attr('id'));
$('#hero-slider').prepend(pF).prepend(pB);
setInterval(fadeThisIn, fadeTime + delay);
function fadeThisIn() {
pB.attr('id', pF.attr('id'));
i = ++i % len;
pF.hide().attr('id', slides.eq(i).attr('id')).fadeIn(fadeTime);
}
}
function realTimeHeight() {
var altura = $(window).height();
$("#hero-slider").css("height", altura);
}

Infinite scrolling div glitching with images

I'm currently using the following javascript as shown below.
It's working well when I place just text within the div .image_scroll_3 but as soon as I insert images the scroll glitches and won't move past the top of the image.
Any advice would be much appreciated
JS
<script>
(function($, undefined) {
$.fn.loopScroll = function(p_options) {
var options = $.extend({
direction: "upwards",
speed: 60
}, p_options);
return this.each(function() {
var obj = $(this).find(".image_scroll_2");
var text_height = obj.find(".image_scroll_3").height();
var start_y, end_y;
if (options.direction == "downwards") {
start_y = -text_height;
end_y = 0;
} else if (options.direction == "upwards") {
start_y = 0;
end_y = -text_height;
}
var animate = function() {
// setup animation of specified block "obj"
// calculate distance of animation
var distance = Math.abs(end_y - parseInt(obj.css("top")));
//alert("animate " + obj.css("top") + "-> " + end_y + " " + distance);
//duration will be distance / speed
obj.animate(
{ top: end_y }, //scroll upwards
1500 * distance / options.speed,
"linear",
function() {
// scroll to start position
obj.css("top", start_y);
animate();
}
);
};
obj.find(".image_scroll_3").clone().appendTo(obj);
$(this).on("mouseout", function() {
obj.stop();
}).on("mouseout", function() {
animate(); // resume animation
});
obj.css("top", start_y);
animate(); // start animation
});
};
}(jQuery));
$("#example4").loopScroll({ speed: 700 });
</script>
I think the problem is that your text_height is calculated before the images are actually loaded inside your .image_scroll_3 elements. So you'll need to wait for the images to load.
Put your loopScroll call inside a $(window).load like so:
$(window).load(function(){
$('#example4').loopScroll({speed:700});
});
That massive glitch should now be gone as the fix above should have helped mitigate it.
However, there is still some unwanted jank / stutter (don't want to use the word glitch again, lets keep it reserved for the initial problem) in movement of all images if you notice and I am guessing that is probably because we are animating the whole thing too fast. Passing in speed like 100 or 200 resolves that but this is not really a solution because, ideally, you should be able to put in any speed value and it should just produce smooth animations out of it.
I am working on exactly the same thing but before that, I want to know if the above fix for the glitch helps you and we are finally done with it? Let me know.
Update:
Here is my version that I spoke of earlier, for your perusal.
Because all you are trying to do is loop images in a very linear fashion, I, for one, do not see the need to rely on animate() function of jQuery. There is requestAnimationFrame API that I have leveraged instead. In fact, in my demonstration below I have completely abandoned jQuery in favour of vanilla JavaScript only because I kept finding alternatives to pretty much everything we needed to do in this demo. But of course, this is also a very subjective matter; a taste thing; so if you want to go with jQuery, then by all means.
Another fundamental change I brought is rather than updating top values, I have resorted to updating translateY values.
Take a look at this jsFiddle and let me know if it fits your needs.
JavaScript code of which is as belows:
// [http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/]
window.requestAnimFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60);};})();
var main=null;
var imageScroll2=null;
var imageScroll3=null;
var totalHeight=null;
var initY=null;
var destY=null;
var currY=null;
var increment=null;
var direction=null;
var UP=null;
var DOWN=null;
var isPlaying=null;
function init(){
main=document.getElementById('example4');
imageScroll2=main.getElementsByClassName('image_scroll_2')[0];
imageScroll3=main.getElementsByClassName('image_scroll_3')[0];
totalHeight=imageScroll3.clientHeight;
UP='upwards';
DOWN='downwards';
isPlaying=true;
direction=UP;
increment=10;
if(direction===DOWN){
initY= -totalHeight;
destY=0;
}else{
initY=0;
destY= -totalHeight;
}
currY=initY;
imageScroll2.appendChild(imageScroll3.cloneNode(true));
if(imageScroll2.addEventListener){
imageScroll2.addEventListener('mouseover',function(){isPlaying=false;},false);
imageScroll2.addEventListener('mouseout',function(){isPlaying=true;},false);
}else{
imageScroll2.attachEvent('onmouseover',function(){isPlaying=false;});
imageScroll2.attachEvent('onmouseout',function(){isPlaying=true;});
}
requestAnimFrame(render);
}
function render(){
if(isPlaying){
imageScroll2.style.transform='translate(0px,'+currY+'px)';
if(direction===DOWN){
currY+=increment;
if(currY>=destY){currY=initY;}
}else{
currY-=increment;
if(currY<=destY){currY=initY;}
}
}
requestAnimFrame(render);
}
//
init();

Simple loop for images

I'm trying to build a simple image slider (but using a fade effect). Every two seconds, the image should change to another image. At the end, it should call repeat_sponsor() again, to start over, so it becomes a loop.
I've written this (highly ineffective) code for 5 images. Turns out I'm going to need it for around 50 images. My editor just freezes when I add too much code.
I've tried using while-loops, but I just can't figure it out how to do this the right way.
Anyone who can help me with this?
function repeat_sponsor()
{
$("#sponsor2").hide();
$("#sponsor3").hide();
$("#sponsor4").hide();
$("#sponsor5").fadeOut("slow");
$("#sponsor1").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor2").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor3").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor4").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor5").fadeIn("slow", ...
(function (){
var cnt = 50; //set to the last one...
var max=50;
function show() {
$("#sponsor" + cnt).fadeOut("slow"); //if you want the fadeout to be done before showing next, put the following code in the complete callback
cnt++;
if(cnt>max) {
cnt=1;
}
$("#sponsor" + cnt).fadeIn("slow");
window.setTimeout(show, 2000);
}
show();
})();
But the real issue is the fact you are loading tons of images from the start. You will be better off changing it so you only have a small subset of images and change the source.
You should use some sort of for loop and a class for hiding the images. and add a max value that if checks out resets c & i
var i=0;
var c=1;
function repeat_sponsor()
{
$("#sponsor"+i).fadeOut("slow");
$(".sponsers").hide()
$("#sponsor"+c).fadeIn("slow", function() {
window.setTimeout(repeat_sponsor(), 3000);
}
i++;
c++;
}
Just run a function every two seconds with setInterval and appropriately target your different sponsor divs:
var i = 1;
var max = 50;
setInterval(function() {
// Could target all other sponsor images with a class "sponsor"
$('.sponsor').fadeOut();
// Execute code on the target
$("#sponsor" + i).fadeIn();
if (i === max) {
i = 0;
}
i++;
}, 2000);

Jquery Image pan, bad performances

I'm creating a jquery script to vertically pan an image inside its container according to the cursor position.
This is what I've done :
$(window).load(function(){
var lastcalc = 0;
$(".tn3a-image").mousemove(function(e){
//var y = e.pageY-$(".tn3a-image").offset().top;
//var Cnt_h = $(".tn3a-image").height();
//var Cy = ($(".pan-view").height()-Cnt_h)/Cnt_h;
var calc = -(($(".pan-view").height()/$(".tn3a-image").height())-1)*(e.pageY-$(".tn3a-image").offset().top)
if (Math.abs(lastcalc-calc)<=1) return;
lastcalc = calc;
$(".tn3a-full-image").stop(true,true)
.animate({ top : calc }, 500, 'linear');
});
});
It works as expected but the performances are really bad. It looks really sluggish, although I have a good GPU/CPU. I came up with two solutions - get the calculations made in a single variable (named 'calc'), and use '.stop(true,true)'. Yet I'm still not really satisfied with it. It looks really bad compared to Flash-based solutions.
Any ideas on how to optimize this ?
Thanks for your help.
Here is a simple way to throttle your handler:
var IsPanning = false;
$(window).load(function(){
var lastcalc = 0;
$(".tn3a-image").mousemove(function(e){
if(IsPanning == false){
IsPanning= true;
var calc = -(($(".pan-view").height()/$(".tn3a-image").height())-1)*(e.pageY-$(".tn3a-image").offset().top)
if (Math.abs(lastcalc-calc)<=1) return;
lastcalc = calc;
$(".tn3a-full-image").stop(true,true)
.animate({ top : calc }, 500, 'linear');
});
IsPanning = false;
}
});
Sorry, I can't check to see if there are any syntax errors at the moment, hopefully it gives you the idea.

Fixing the animation properties

I am doing some research at the moment into creating a new maths game for primary school children where divs from 0-9 appear at random inside a container.
A question is given at the beginning. Something like, multiples of 20. The user will then have to click on the correct ones, and they will then be counted at the end and a score will be given.
I have just changed the speed in which the divs appear so that they appear for longer and more than one at a time to make the game easier for younger children.
I used "fadeIn" like so..
$('#' + id).animate({
top: newY,
left: newX
}, 'slow', function() {}).fadeIn(2000);
}
My problem is that now when I shoot the correct or incorrect number the animation is very glitchy and I cannot figure out why.
Fiddle: http://jsfiddle.net/cFKHq/6/ (See version 5 to see what it was like before)
Inside startplay(), control the concurrency when calling scramble() , I do it with a global var named window.cont, so I replaced your following call:
play = setInterval(scramble, 1800);
for this one:
play = setInterval(function() {
if (window.cont){
window.cont = false;
scramble();
}
}, 1000);
The var window.cont needs to be set globally at the start of your code, like so:
var miss = 0;
var hit = 0;
var target = $("#target");
window.cont = true;
So with window.cont you now can control that animations are executed one after another, without overlapping, like so:
$('#'+id).css({
top: newY,
left: newX
}).fadeIn(2000, function() {
setTimeout(function() {
$('#' + id).slideUp('fast');
window.cont = true;
}, 1500);
});
See working demo

Categories

Resources