I have a series of jQuery functions to execute in a block. When they ALL are done, I need another function to be called. It seems a callback is the best way to do this. Here is my code.
function flipPage (x, callback) {
$("#view-1").animate({
width: x,
}, 500);
$("#view-2").animate({
width: browserWidth - x,
}, 500);
$("#iframe-2").animate({
left: -x,
}, 500);
$("#sweeper").animate({
left: x,
}, 500);
callback(function() {
alert("I'm Done.");
//do the next thing
}) ;
}
You could do something like this:
function flipPage (x, callback) {
var animationHelper = {
actionCounter: 0,
actionCount: 4,
callbackHandler: function() {
this.actionCounter++;
if(this.actionCounter == this.actionCount)
this.callbackAllFinished();
},
callbackAllFinished: null
};
$("#view-1").animate({
width: x }, 500, animationHelper.callbackHandler);
$("#view-2").animate({
width: browserWidth - x }, 500, animationHelper.callbackHandler);
$("#iframe-2").animate({
left: -x }, 500, animationHelper.callbackHandler);
$("#sweeper").animate({
left: x }, 500, animationHelper.callbackHandler);
animationHelper.callbackAllFinished = function() {
alert("I'm Done.");
//do the next thing
};
}
Essentially the same as sjkm's, but simplified.
function flipPage (x, callback) {
var counter = 0;
$("#view-1").animate({
width: x,
}, 500, finished);
$("#view-2").animate({
width: browserWidth - x,
}, 500, finished);
$("#iframe-2").animate({
left: -x,
}, 500, finished);
$("#sweeper").animate({
left: x,
}, 500, finished);
function finished() {
counter++;
if (counter >= 4) {
alert("I'm Done.");
//do the next thing if callback exists
callback && callback.call();
}
};
}
jsfiddle
Related
I'm trying to create a snake game in Phaser 3. The arrow.(key).isDown is acting strangely and I can't figure out why. If you press a key weather it is up, down, left or right it will not change directions if you press the opposite, it just keeps moving. like if I press down it keeps going down even after I press up. I have been trying to debug it for hours. All the examples pretty much have it set up the same way.
This is my code so far
class mainScene {
preload() {
this.load.image("fruit", "images/fruit.png");
this.load.image("snake", "images/snake.png");
}
create() {
this.score = 0;
this.snake = this.physics.add.sprite(20, 20, "snake");
this.fruit = this.physics.add.sprite(
Phaser.Math.Between(10, 590),
Phaser.Math.Between(10, 590),
"fruit"
);
this.scoreText = this.add.text(500, 5, `Score: ${this.score}`);
this.arrow = this.input.keyboard.createCursorKeys();
//debug
}
update() {
if (this.physics.overlap(this.snake, this.fruit)) {
this.hit();
}
this.snake.setVelocity(0);
if (this.arrow.right.isDown) {
this.snake.setVelocityX(50);
if (this.snake.x > 600) {
this.outOfBounds();
}
} else if (this.arrow.left.isDown) {
this.snake.setVelocityX(-50);
if (this.snake.x < 0) {
this.outOfBounds();
}
}
if (this.arrow.down.isDown) {
this.snake.setVelocityY(50);
if (this.snake.y > 600) {
this.outOfBounds();
}
} else if (this.arrow.up.isDown) {
this.snake.setVelocityY(-50);
if (this.snake.y < 0) {
this.outOfBounds();
}
}
}
hit() {
this.fruit.x = Phaser.Math.Between(10, 590);
this.fruit.y = Phaser.Math.Between(10, 590);
this.score += 1;
this.scoreText.setText(`Score: ${this.score}`);
this.tweens.add({
targets: this.snake,
duration: 200,
scaleX: 1.2,
scaleY: 1.2,
yoyo: true,
});
}
outOfBounds() {
this.score = 0;
this.scoreText.setText(`Score: ${this.score}`);
this.gameOverText = this.add.text(
100,
250,
"You went out of bounds.\nGame Over\nPress Space to continue.",
{ fontSize: "24px" }
);
if (this.arrow.space.isDown) {
this.gameOverText.destroy();
this.scene.restart();
}
}
}
const config = {
type: Phaser.CANVAS,
width: 600,
height: 600,
backgroundColor: 0x000040,
scene: mainScene,
physics: {
default: "arcade",
debug: true,
setBounds: { x: 0, y: 0, width: 600, height: 600 },
},
parent: "game",
};
new Phaser.Game(config);
I know nothing of jquery/js but i applied a News Slider/Ticker script that I found online to my website home page. The script itself works fine. The html and css parts were easy enough but I can't find the proper way to make it PAUSE ON HOVER. The .js file that came with it is lengthy and has much that I suspect isn't even being used, but as I said, I don't know js. Sorry for the long js file but I don't know what parts are even involved. Can somebody help this complete novice?
(function ($) {
$.simpleTicker = function (elem, options) {
var defaults = {
speed: 1000,
delay: 4000,
easing: 'swing',
effectType: 'slide'
};
var param = {
'ul': '',
'li': '',
'initList': '',
'ulWidth': '',
'liHeight': '',
'tickerHook': 'tickerHook',
'effect': {}
};
var plugin = this;
plugin.settings = {};
var $element = $(elem),
element = elem;
plugin.init = function () {
plugin.settings = $.extend({}, defaults, options);
param.ul = element.children('ul');
param.li = element.find('li');
param.initList = element.find('li:first');
param.ulWidth = param.ul.width();
param.liHeight = param.li.height();
element.css({
height: (param.liHeight)
});
param.li.css({
top: '0',
left: '0',
position: 'absolute'
});
//dispatch
switch (plugin.settings.effectType) {
case 'fade':
plugin.effect.fade();
break;
case 'roll':
plugin.effect.roll();
break;
case 'slide':
plugin.effect.slide();
break;
}
plugin.effect.exec();
};
plugin.effect = {};
plugin.effect.exec = function () {
param.initList.css(param.effect.init.css)
.animate(param.effect.init.animate, plugin.settings.speed, plugin.settings.easing)
.addClass(param.tickerHook);
if (element.find(param.li).length > 1) {
setInterval(function () {
element.find('.' + param.tickerHook)
.animate(param.effect.start.animate, plugin.settings.speed, plugin.settings.easing)
.next()
.css(param.effect.next.css)
.animate(param.effect.next.animate, plugin.settings.speed, plugin.settings.easing)
.addClass(param.tickerHook)
.end()
.appendTo(param.ul)
.css(param.effect.end.css)
.removeClass(param.tickerHook);
}, plugin.settings.delay);
}
};
plugin.effect.fade = function () {
param.effect = {
'init': {
'css': {
display: 'block',
opacity: '0'
},
'animate': {
opacity: '1',
zIndex: '98'
}
},
'start': {
'animate': {
opacity: '0'
}
},
'next': {
'css': {
display: 'block',
opacity: '0',
zIndex: '99'
},
'animate': {
opacity: '1'
}
},
'end': {
'css': {
display: 'none',
zIndex: '98'
}
}
};
};
plugin.effect.roll = function () {
param.effect = {
'init': {
'css': {
top: '3em',
display: 'block',
opacity: '0'
},
'animate': {
top: '0',
opacity: '1',
zIndex: '98'
}
},
'start': {
'animate': {
top: '-3em',
opacity: '0'
}
},
'next': {
'css': {
top: '3em',
display: 'block',
opacity: '0',
zIndex: '99'
},
'animate': {
top: '0',
opacity: '1'
}
},
'end': {
'css': {
zIndex: '98'
}
}
};
};
plugin.effect.slide = function () {
param.effect = {
'init': {
'css': {
left: (200),
display: 'block',
opacity: '0'
},
'animate': {
left: '0',
opacity: '1',
zIndex: '98'
}
},
'start': {
'animate': {
left: (-(200)),
opacity: '0'
}
},
'next': {
'css': {
left: (param.ulWidth),
display: 'block',
opacity: '0',
zIndex: '99'
},
'animate': {
left: '0',
opacity: '1'
}
},
'end': {
'css': {
zIndex: '98'
}
}
};
};
plugin.init();
};
$.fn.simpleTicker = function (options) {
return this.each(function () {
if (undefined == $(this).data('simpleTicker')) {
var plugin = new $.simpleTiecker(this, options);
$(this).data('simpleTicker', plugin);
}
});
};
})(jQuery);
In my opinion, that library is old and very very complicated to work with. I would personally recommend you move to something along the lines of Slick Slider.
Slick: https://kenwheeler.github.io/slick/
You can use the CDN version <script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
I was able to recreate your use case in about 5min (with hover pause) with Click. Because it's an actual slider, it's better to wrap things in <div> containers, so I've done so in the fiddle I've shown you. You can tweak the CSS opacity animations to taste, but it's basically what you're doing now.
The Fiddle: Slick Slider
I am using the following code to call a function when the screen is less than 200 but I can't disable the function when the scroll is more than 200.
function animateHeader() {
$(selector)
.animate({ opacity: 0.0, bottom: 70 }, { duration: 600 })
.animate({ opacity: 0.0, bottom: 50 }, { duration: 0 })
.animate({ opacity: 0.0, bottom: 70 }, { duration: 600, complete: animateHeader })
}
$window.on('scroll', function() {
if ($(window).scrollTop() < 200) {
animateHeader();
} else {
// Disable animateHeader()
}
}); // Finish scroll
I know there are alternatives to not call a function here in this case, but is it possible to disable a function when it's already active?
Try using stop() function:
else {
$(selector).stop();
}
I am using some JavaScript and jQuery (with the easing plugin) to create a virtual tour; really just a long image that can pan left and right. I have found this which is perfect for the cause: http://jsfiddle.net/MvRdD/1/. Is there a way to add easing to the animation?
http://jsfiddle.net/ARTsinn/MvRdD/890/
$(document).ready(function() {
$.getScript("https://raw.github.com/danro/easing-js/master/easing.min.js");
var animateTime = 10,
offsetStep = 5,
scrollWrapper = $('#wrap');
//event handling for buttons "left", "right"
var aktiv;
$('.bttL, .bttR').mousedown(function(e) {
if (e.target.className === 'bttR') {
aktiv = window.setInterval(function() {
scrollWrapper.animate({
scrollLeft: '+=' + 20
}, {
duration: 600,
queue: false,
easing: 'easeOutCirc'
});
}, 10);
} else if (e.target.className === 'bttL') {
aktiv = window.setInterval(function() {
scrollWrapper.animate({
scrollLeft: '-=' + 20
}, {
duration: 1200,
queue: false,
easing: 'easeOutCirc'
});
}, 10);
}
}).mouseup(function() {
window.clearInterval(aktiv);
});
scrollWrapper.mousedown(function(event) {
$(this).data('down', true).data('x', event.clientX).data('scrollLeft', this.scrollLeft);
return false;
}).mouseup(function(event) {
$(this).data('down', false);
}).mousemove(function(event) {
if ($(this).data('down')) {
$(this).stop(false, true).animate({
scrollLeft: $(this).data('scrollLeft') + ($(this).data('x') - event.clientX) * 2
}, {
duration: 600,
queue: false,
easing: 'easeOutCirc'
});
}
}).mousewheel(function(event, delta) {
$(this).stop(false, true).animate({
scrollLeft: '-=' + delta * 60
}, {
duration: 400,
queue: false,
easing: 'easeOutCirc'
});
event.preventDefault();
}).css({
'overflow': 'hidden',
'cursor': '-moz-grab'
});
});
What would be a better way of writing this:
setTimeout(function() {
$('#clock').animate({
'marginTop': '-20px'
}, 'slow', $.bez(bezierEasing));
}, 100);
setTimeout(function() {
$('#submit').animate({
'top': '-5px'
}, 500, $.bez(bezierEasing));
}, 200);
setTimeout(function() {
$('#details').animate({
'top': '-200px'
}, 500, $.bez(bezierEasing));
}, 300);
setTimeout(function() {
$('#details').animate({
'top': '19px'
}, 100, $.bez(bezierEasing));
}, 600);
Create a function:
// adjust your function accordingly...
function animateIt(selector, speed, top) {
setTimeout(function() {
$(selector).animate({
'top': top
}, speed, $.bez(bezierEasing));
}, 600);
}
Instead of using some weird timeOut chain why you don't use TimelineMax from greensock.com.
It's far more advanced and way easier to use.
Just throwing out my version...
function animateEl(selector, css, speed, timer) {
var tmp = parseInt(speed, 10);
if (!isNaN(tmp)) {
speed = tmp;
}
return setTimeout(function () {
$(selector).animate(css, speed, $.bez(bezierEasing)
}, timer);
}
animateEl('#clock', {'marginTop': '-20px' }, 'slow', 100);
animateEl('#submit', { 'top': '-5px' }, 500, , 200);
animateEl('#details', { 'top': '-200px' }, 500, 300);
animateEl('#details', { 'top': '19px' }, 100, 600);