I'm using my limited javascript skills to try an piece togheter a script that can play a small animation and a sound clip in a loop. This is what i've got so far:
<script>
function PulseArea() {
$('.area-pulse').stop();
$('.area-pulse').css({ width: 38, height: 38, top: 217, left: 77, opacity: 1 });
$('.area-pulse').animate({ width: 700, height: 700, top: -114, left: -254, opacity:0 }, 4000, null, function () { setTimeout("PulseArea()", 400); });
}
$(function() {
var sample = new Audio("audio/water-droplet-1.wav");
function playSample() {
sample.pause();
sample.currentTime = 0;
sample.play();
}
})
$(document).ready(function() {
for (i=0;i<=5;i++)
{
PulseArea();
playSample();
}
})
</script>
Related css:
.area-pulse
{
display:block;
width:38px;
height:38px;
position:absolute;
top:217px;
left:77px;
background-color:transparent;
zoom: 1;
}
.area-pulse img
{
opacity:1;
width:100%;
height:100%;
display:inline-block;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/area_pulse.png', sizingMethod='scale');
background-color:transparent;
}
Related HTML:
<div style=" width:954px; height:600px; position:absolute;" class="area-pulse"><img src="img/area_pulse.png" /></div>
It's the sound that is the problem. The animation plays fine. Any suggestions? I've searched StackOverflow, but can't find anything like this.
Thanks for taking an interest!
Your function playSample is defined inside of anonymous function scope, so it can't be called from the document.ready scope. If you move all of it into the same scope, it will work fine:
$(document.ready(function () {
function PulseArea() {
$('.area-pulse').stop();
$('.area-pulse').css({ width: 38, height: 38, top: 217, left: 77, opacity: 1 });
$('.area-pulse').animate({ width: 700, height: 700, top: -114, left: -254, opacity:0 }, 4000, null, function () { setTimeout("PulseArea()", 400); });
}
var sample = new Audio("audio/water-droplet-1.wav");
function playSample() {
sample.pause();
sample.currentTime = 0;
sample.play();
}
for (i=0;i<=5;i++) {
PulseArea();
playSample();
}
});
I don't know what was wrong with the script in my question, but i solved it by rewriting it. I hope someone else can be helped by this. :)
<script>
function PulseArea() {
var audioElement = document.createElement('audio');
audioElement.setAttribute('src', 'audio/waterdrop.mp3');
audioElement.play();
$('.area-pulse').stop();
$('.area-pulse').css({ width: 16, height: 16, top: 227, left: 89, opacity: 1 });
$('.area-pulse').animate({ width: 700, height: 700, top: -114, left: -254, opacity:0 }, 4000, null, function () { setTimeout("PulseArea()", 400); });
}
$(document).ready(function() {
for (i=0;i<=5;i++)
{
PulseArea();
}
})
</script>
Related
I am trying to animate an object for a game in which the ball is supposed to move up, right, left and down on pressing user button. I am trying to achieve this by using .animate() function on the ball. But after every animation event, the ball resets to its initial position and does not continue moving from its "new" position. Is there any way to accomplish this?
Following is my condensed code snippet for simplicity:
/* Animation */
var item = document.getElementById('item');
var anim;
function myMoveLeft(){
anim=item.animate([
// keyframes
{ transform: 'translateX(0px)' },
{ transform: 'translateX(-60px)' }
], {
duration: 1000,
iterations: 1
});
}
function myMoveDown(){
anim=item.animate([
// keyframes
{ transform: 'translateY(0px)' },
{ transform: 'translateY(60px)' }
], {
duration: 1000,
iterations: 1
});
// anim.onfinish(()=>{console.log("onfinish ran")})
}
item.addEventListener('animationend', () => {
console.log('Animation ended');
});
button{
display:inline-block;
height:40px;
width:80px;
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: lightgray ;
}
#item {
background: orange;
position: absolute;
right:30px;
top:30px;
height: 30px;
width: 30px;
border-radius:50%;
}
<p>
<button onclick="myMoveLeft()">Left</button>
<button onclick="myMoveDown()">Down</button>
</p>
<div id ="myContainer">
<div id="item"></div>
</div>
As seen, I have already tried using .onfinish() and Event Listener 'animationend' hoping I could update the new 'right' and 'top' position but it does not work. Not sure if that would be the right approach.
Could someone please suggest on how to save the element to a new position and animate it further from that new position?
PS: I am also open to suggestions/techniques if you feel there are other better ways to do this.
Thanks a lot in Advance!!
You can make the ball get the final transform value using the fill option, which is the same as animation-fill-mode in css animation.
For not override the transform when you do the next animation, you can save the x and y value as variables, and do any animation according to the current x and y state. (from x to x-60, instead from 0 to -60, etc.)
Example:
/* Animation */
var item = document.getElementById('item');
var anim;
var x=0, y=0;
function myMoveLeft(){
anim=item.animate([
// keyframes
{ transform: `translate(${x}px, ${y}px)` },
{ transform: `translate(${x-60}px, ${y}px)` }
], {
duration: 1000,
iterations: 1,
fill: 'forwards'
});
x -= 60;
}
function myMoveDown(){
anim=item.animate([
// keyframes
{ transform: `translate(${x}px, ${y}px)` },
{ transform: `translate(${x}px, ${y+60}px)` }
], {
duration: 1000,
iterations: 1,
fill: 'forwards'
});
y += 60;
// anim.onfinish(()=>{console.log("onfinish ran")})
}
item.addEventListener('animationend', () => {
console.log('Animation ended');
});
button{
display:inline-block;
height:40px;
width:80px;
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: lightgray ;
}
#item {
background: orange;
position: absolute;
right:30px;
top:30px;
height: 30px;
width: 30px;
border-radius:50%;
}
<p>
<button onclick="myMoveLeft()">Left</button>
<button onclick="myMoveDown()">Down</button>
</p>
<div id ="myContainer">
<div id="item"></div>
</div>
I am trying to make a small jQuery plugin that is able to create an overlay to create a tinting effect. To create this overlay is simple enough using plain js & jQuery, but when I try to wrap it all up into a jQuery plugin I get the error message that append (and appendTo) are not functions. The plugin works if I use extend instead of append, but the it is simply changing the existing css code, while I want to create an actual overlay over any div or object.
(function ($) {
$.fn.tint = function( options )
{
var overlay = $.append(
{
backgroundColor: "black",
opacity: 0.5,
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
//"z-index": 1000,
}, options
);
return this.css(
{
backgroundColor: overlay.backgroundColor,
opacity: overlay.opacity,
width: overlay.width,
height: overlay.height,
position: overlay.position,
top: overlay.top,
left: overlay.left,
right: overlay.right,
bottom: overlay.bottom,
//z-index: overlay.z-index,
}
);
}
} ( jQuery ));
I guess you are trying to do $.extend (not $.append):
(function ($) {
$.fn.tint = function( options )
{
if($(this).find(".overlay").length > 0) return $(this);
var overlay = $.extend({
backgroundColor: "black",
opacity: 0.5,
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
//"z-index": 1000,
}, options);
$("<div class='overlay'>").css(
{
backgroundColor: overlay.backgroundColor,
opacity: overlay.opacity,
width: overlay.width,
height: overlay.height,
position: overlay.position,
top: overlay.top,
left: overlay.left,
right: overlay.right,
bottom: overlay.bottom,
//z-index: overlay.z-index,
}
).appendTo(this);
return $(this);
}
} ( jQuery ));
$(".overlay-target").on("click", function(){
$(this).tint({backgroundColor: "green"});
});
.overlay-target {
border: 1px solid red;
margin: 20px;
padding: 50px;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='overlay-target'>I want an overlay</div>
I have to apply animation on each "div". But it is applying just in first one not in all.
According to me "$("#viewport").each(appendTo(c));" this line is not working in javascript code.
HTML code:
<div id="viewport"></div>
<div id="viewport"></div>
<div id="viewport"></div>
Javascript code:
$(window).load(function(){
$(function () {
var a = 0;
for (; a < 15; a += 1) {
setTimeout(function b() {
var a = Math.random() * 1e3 + 5e3,
c = $("<div />", {
"class": "smoke",
css: {
opacity: 0,
left: Math.random() * 200 + 80
}
});
**$("#viewport").each(appendTo(c));**
$.when($(c).animate({
opacity: 1
}, {
duration: a / 4,
easing: "linear",
queue: false,
complete: function () {
$(c).animate({
opacity: 0
}, {
duration: a / 3,
easing: "linear",
queue: false
})
}
}), $(c).animate({
bottom: $("#viewport").height()
}, {
duration: a,
easing: "linear",
queue: false
})).then(function () {
$(c).remove();
b()
});
}, Math.random() * 3e3)
}
}());
});
Use more than one element with the same id is absolutely bad practice! Put "vieport" as class and use
$( ".viewport" )
The .each() function take a function as first argument and in that function context, the "this" variable will contain the element
$( ".viewport" ).each( function() {
$( this ).appendTo( c );
});
If I am not wrong. You want something like this:
HTML:
<div id="viewport">
<div class="smoke smoke1"></div>
<div class="smoke smoke2"></div>
<div class="smoke smoke3"></div>
</div>
JS:
(function () {
"use strict";
$('#viewport .smoke').each(function ns () {
var initialTop = $(this).position().top;
$(this).animate({
top: - $(this).height()
}, Math.random() * 2000 + 2000, function () {
$(this).css({
top: initialTop,
opacity: 0
});
}).animate({
opacity: 1
}, ns)
});
}());
CSS:
#viewport {
position: relative;
width: 400px;
height: 300px;
margin: 100px auto;
border: 1px solid #333333;
overflow: hidden;
}
#viewport .smoke {
position: absolute;
width: 20px;
height: 40px;
background: rgba(0, 0, 0, 0.5);
}
#viewport .smoke1 {
left: 140px;
top: 260px;
}
#viewport .smoke2 {
left: 180px;
top: 260px;
}
#viewport .smoke3 {
left: 220px;
top: 260px;
}
Please see demo here: http://jsfiddle.net/1rf31eyL/
You may check another example demo here: http://gettycreations.com/
first of all
add function in $.each
like
"$("#viewport").each(
function(){
$(this).appendTo(c);
}
);
and then try this,
$("[id=viewport]")
When you use
$("#viewport")
it selects only the first element with the given ID.
However, when you select by attribute (e.g. id in your case), it returns all matching elements, like so:
$("[id=viewport]")
I want to modify this code for click event. But I am not able to do so. My requirement is to slide the panel on click (not hover) and again rollback on click (and not mouse out).
HTML
<div id="sidePanel">
<div id="panelContent">
<iframe src="//www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2FWebsTutorial&width=200&height=258&colorscheme=light&show_faces=true&border_color&stream=false&header=false&appId=253401284678598" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:200px; height:258px;" allowTransparency="true"></iframe>
</div>
<div id="panelHandle"><p>Facebook</p></div>
</div>
CSS
/* ===== Primary Styles ========================================================
Author: NTechi | WebsTutorial
========================================================================== */
body{
font-family:Arial;
}
#sidePanel{
width:245px;
position:fixed;
left:-202px;
top:15%;
}
#panelHandle{
background-image: -webkit-linear-gradient(top,#333,#222);
background-image: -moz-linear-gradient(center top , #333333, #222222);
background-image: -o-linear-gradient(center top , #333333, #222222);
background-image: -ms-linear-gradient(center top , #333333, #222222);
background-image:linear-gradient(center top , #333333, #222222);
height:150px;
width:40px;
border-radius:0 5px 5px 0;
float:left;
cursor:pointer;
}
#panelContent{
float:left;
border:1px solid #333333;
width:200px;
height:300px;
background-color:#EEEEEE;
}
#panelHandle p {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
color: #FFFFFF;
font-size: 24px;
font-weight: bold;
left: -4px;
margin: 0;
padding: 0;
position: relative;
top: 26px;
}
JavaScript
jQuery(function($) {
$(document).ready(function() {
$('#panelHandle').hover(function() {
$('#sidePanel').stop(true, false).animate({
'left': '0px'
}, 900);
}, function() {
jQuery.noConflict();
});
jQuery('#sidePanel').hover(function() {
// Do nothing
}, function() {
jQuery.noConflict();
jQuery('#sidePanel').animate({
left: '-201px'
}, 800);
});
});
});
Any help would be really helpful.
Thanks in advance!
Use Toggle API Instead http://api.jquery.com/toggle-event/
$('#panelHandle').toggle(function() {
$('#sidePanel').stop(true, false).animate({
'left': '0px'
}, 900);
}, function() {
jQuery('#sidePanel').animate({
left: '-201px'
}, 800);
});
Fiddle: http://jsfiddle.net/GPdFk/4812/
Simple way to do this. Change the hover event to toggle event.
Using your jsfiddle it would be something like this:
$(document).ready(function() {
$('#panelHandle').toggle(function() {
$('#sidePanel').stop(true, false).animate({
'left': '0px'
}, 900);
}, function() {
jQuery.noConflict();
jQuery('#sidePanel').animate({
left: '-201px'
}, 800);
});
});
It can easily be done using .toggle()
Here is the updated code:
jQuery(function($) {
$('#panelHandle').toggle(function() {
$('#sidePanel').animate({
'left': '0px'
}, 900);
}, function() {
$('#sidePanel').animate({
'left': '-202px'
}, 900);
});
});
I'm making a gallery of pics that expand to full size when you click them and shrink back to normal when you click them a second time... my issue is that if I click multiple pictures, they will all enlarge and stack without the first ones returning to their original size. I'm wondering if there is an easy way to either force all of the other pics back to the smaller size when one is clicked for enlargement, or if there is a way to make it so you have to click somewhere away from the enlarged pic to get it to return to the smaller size.
Here's my code, fiddle link at the bottom
(click the second pic and then the first to see what I'm talking about)
<div id="Gpic1">
<img class='galleryPics' id='pic1' src='http://i.imgur.com/urxD24P.jpg?1'>
</div>
<div id="Gpic2">
<img class='galleryPics' id='pic2' src='http://i.imgur.com/JbJXjsf.jpg?1'>
</div>
#Gpic1 {
float: left;
width: 187px;
height: 280px;
margin-left: 5%;
display: inline-block;
background: black;
padding: 0;
}
#pic1 {
width: 187px;
height: 280px;
}
#Gpic2 {
float: left;
width: 187px;
height: 280px;
margin-left: 5%;
display: inline-block;
background: black;
padding: 0;
}
#pic2 {
width: 187px;
height: 280px;
}
.enlarged {
border: 10px solid #e5dbcc;
position: absolute;
-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
-moz-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
}
$('#Gpic1').hover(function () {
if (!$(this).find('img').hasClass('enlarged')) {
$(this).find('img').fadeTo(500, 0.5);
}
}, function () {
$(this).find('img').fadeTo(500, 1);
});
$('#pic1').click(function () {
$(this).fadeTo(0, 1);
if ($(this).hasClass('enlarged')) {
$(this).removeClass('enlarged');
$(this).stop().animate({
width: 187,
height: 280
}, 0,
function () {
$(this).parent().removeClass('ontop');
$('#Gpic1').css('background', 'black');
});
} else {
$(this).addClass('enlarged')
$(this).parent().addClass('ontop');
$(this).stop().animate({
width: 533,
height: 800,
left: +100,
bottom: +50
}, 200);
$('#Gpic1').css('background', 'none');
}
});
$('#Gpic2').hover(function () {
if (!$(this).find('img').hasClass('enlarged')) {
$(this).find('img').fadeTo(500, 0.5);
}
}, function () {
$(this).find('img').fadeTo(500, 1);
});
$('#pic2').click(function () {
$(this).fadeTo(0, 1);
if ($(this).hasClass('enlarged')) {
$(this).removeClass('enlarged');
$(this).stop().animate({
width: 187,
height: 280
}, 0,
function () {
$(this).parent().removeClass('ontop');
$('#Gpic2').css('background', 'black');
});
} else {
$(this).addClass('enlarged')
$(this).parent().addClass('ontop');
$(this).stop().animate({
width: 533,
height: 800,
left: +100,
bottom: +50
}, 200);
$('#Gpic2').css('background', 'none');
}
});
EDIT ---- fiddle: http://jsfiddle.net/Td6tT/4/
Simply use a jQuery function to select all picture elements of the given class "enlarged" and shrink them before enlarging the next one:
$("img.enlarged").removeClass("enlarged");
So in your code, for example:
$('#pic1').click(function () {
$(this).fadeTo(0, 1);
if ($(this).hasClass('enlarged')) {
$(this).removeClass('enlarged');
$(this).stop().animate({
width: 187,
height: 280
}, 0,
function () {
$(this).parent().removeClass('ontop');
$('#Gpic1').css('background', 'black');
});
} else {
//Add the following line
$("img.enlarged").removeClass("enlarged");
$(this).addClass('enlarged')
$(this).parent().addClass('ontop');
$(this).stop().animate({
width: 533,
height: 800,
left: +100,
bottom: +50
}, 200);
$('#Gpic1').css('background', 'none');
}
});
Voila!
There are really a couple ways to do this, and it depends on how you feel about different approaches. Perhaps the easiest thing to do, since you're already basing it on classes would be to add something like $('.enlarged').removeClass('enlarged') to the start of the clickhandler section that deals with enlarging a new image. That way, when you click to enlarge another image, all other images that are enlarged will shrink.
If you prefer, you could create a variable to store whichever one is currently open and shrink it in the same way, as well, though I think the above suggestion is nicer as it keeps everything within the function scope.
For a general 'clickaway' function, you may also consider using .blur, but you'd need to give the image focus when it is clicked using .focus.