I have a game made in phaser and we're trying to add fullscreen functionality to it. When I call just
this.game.scale.startFullScreen(false);
it keeps the games maxHeight and maxWidth, since they're set in the preload, so it shows a black full screen with the game centered, so I created a wrapper for it, which works, but not when a user hits escape as opposed to the "Exit fullscreen button". The start wrapper sets the maxWidth and maxHeight to null, which then allows total full screen, and the stop wrapper sets them back to their default values, and when you press the "exit fullscreen" button it works fine, but when I hit escape it calls my function, but doesn't reset the screen, so it exits browser full screen mode, but is still taller than the browser window.
Here's my full code:
var startFullscreen = function() {
// remove maxwith and maxheight
game.scale.maxWidth = null;
game.scale.maxHeight = null;
// set to fullscreen
game.scale.startFullScreen(false);
}
var stopFullscreen = function() {
// reset maxWidth and maxHeight
game.scale.maxWidth = 1000;
game.scale.maxHeight = 600;
// turn off fullscreen
if (game.scale.isFullScreen) { // if the user hit escape, fullscreen is already exited and we only need to reset the scale
game.scale.stopFullScreen();
} else {
// what goes here?
}
}
$(document).keyup(function (e) {
if (e.keyCode == 27) { // escape key maps to keycode `27`
stopFullscreen();
}
});
Any help is appreciated. Thanks in advance!
I moved the resetting to after we go to full screen, that way they're already set when exit full screen gets called, so it renders correct, but I'm still open to better solutions.
var startFullscreen = function() {
// remove maxwith and maxheight
game.scale.maxWidth = null;
game.scale.maxHeight = null;
// set to fullscreen
game.scale.startFullScreen(false);
setTimeout(function () {
// resets height and width so the game will render correctly when fullscreen exits
game.scale.maxWidth = 1000;
game.scale.maxHeight = 600;
}, 500);
}
Related
I am running a script to show a notification within a menu with scroll, but I do not know how to detect if the device has orientation landscape to validate the script.
The call onClick="VerHayMas();" works perfectly, but if the user open the menu once, clicking on #boton-menu and with your device in portrait, after changing the orientation to landscape the script no longer meet the objective.
The script has its logic ONLY if the device is in landscape, which is
when the menu needs to show the notification.
So, is it possible that my script is only valid with (max-width:999px) and (orientation:landscape), ignoring the portrait...?
I am a beginner in JS, and I do not know how to do it, really.
Any idea?
Thanks in advance!
HTML & CSS
#mas-menu {display:none}
<div id="boton-menu" onClick="VerHayMas();">+</div>
Script:
var clicksVerHayMas = 0;
function VerHayMas() {
clicksVerHayMas = clicksVerHayMas + 1;
if (clicksVerHayMas == 1) {
document.getElementById('mas-menu').style.display = 'block';
window.setTimeout(function() {
$('#mas-menu').fadeOut('slow');
}, 4000);
}
};
EDIT:
I have tried with the following script, but it does not work. If the user makes a call to onClick="VerHayMas();" in portrait mode, the script is no longer running in landscape mode.
What am I doing wrong here?
const matchesMediaQuery = window.matchMedia('(max-width:999px) and (orientation:landscape)').matches;
if (matchesMediaQuery) {
var clicksVerHayMas = 0;
function VerHayMas() {
clicksVerHayMas = clicksVerHayMas +1;
if(clicksVerHayMas == 1){
document.getElementById('mas-menu').style.display = 'block';
window.setTimeout(function(){
$('#mas-menu').fadeOut('slow');
},4000);
}};
}
I'd keep it simple, if screen height is less than width, then the user is in landscape mode. You can grab the height and width from the global window object.
if (window.innerWidth > window.innerHeight) {
// The user is in landscape mode!
userInLanscapeFunc();
}
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight
You can solve this using matchMedia:
const matchesMediaQuery = window.matchMedia('(max-width:999px) and (orientation:landscape)').matches;
if (matchesMediaQuery) {
// do something
}
Make sure to note the browser support in the MDN link.
EDIT TO PROVIDE CONTEXT:
Because the user may be moving around their screen, you will want to make this evaluation inside VerHayMas, each time it is run, to determine if the main body of the script should be executed:
var clicksVerHayMas = 0;
function VerHayMas() {
var isLandscapeAndMeetsSizeRequirements = window.matchMedia('(max-width:999px) and (orientation:landscape)').matches;
if (isLandscapeAndMeetsSizeRequirements) {
clicksVerHayMas = clicksVerHayMas + 1;
if (clicksVerHayMas == 1) {
document.getElementById('mas-menu').style.display = 'block';
window.setTimeout(function() {
$('#mas-menu').fadeOut('slow');
}, 4000);
}
}
};
So VerHayMas will be run on every click, but only if the screen meets the requirements as determined by the media query string will it execute the code inside the if block.
You can see from my codepen that I have a logo on my website that fades out as you scroll down the page, which is triggered after a certain trigger has been fired. This is working the way I want it, except I only want this to fire on mobile browsers and mobile screen sizes.
I'm using scrollmagic.js with this also.
Does anyone know how to set this up so the effect will only work on mobile and screen sizes < 768px.
I'm fairly new to JS and so would appreciate baby steps.
thanks
// When the DOM is ready
$(window).on('load', function() {
// Init ScrollMagic Controller
var scrollMagicController = new ScrollMagic();
// Create Animation for 0.5s
var tween = TweenMax.to('#animation', 0.5, {
opacity: 0
});
// Create the Scene and trigger when visible
var scene = new ScrollScene({
triggerElement: '.scene',
offset: 150 /* offset the trigger 150px below #scene's top */
})
.setTween(tween)
.addTo(scrollMagicController);
// Add debug indicators fixed on right side
scene.addIndicators();
});
Codepen of what I currently have
I would wrap the scrollMagic block on an if statement that checks if it is a touch device or if it has a minimum with, depending on which behaviour you are interested in.
With Modernzr:
var agent = navigator.userAgent.toLowerCase();
var onlyTaps = Modernizr.touch ||
(agent.match(/(iphone|ipod|ipad)/) ||
agent.match(/(android)/) ||
agent.match(/(iemobile)/) ||
agent.match(/iphone/i) ||
agent.match(/ipad/i) ||
agent.match(/ipod/i) ||
agent.match(/blackberry/i) ||
agent.match(/bada/i));
if (onlyTaps) {
//magicScroll block here
} else {
//something else here
}
Now, if you are only interested on the device width then you can use screen.width:
if (screen.width < 480) {
//magicScroll block here
} else {
//something else here
}
The only caveat is that screen.width might return real pixels or not on some high density devices. It works as expected on iPhones and Macbook Pro w/retina displays.
I have created an animated menu that opens when the users cursor is placed within 20px of the right hand side of their screen. I want to prevent the menu opening if the users cursor moves out of this region within 2 seconds but I'm struggling with the Javascript timeouts. My code looks like this so far:
HTML
Javascript
// Timer variable
var timer;
function openToolbar()
{
// Only execute for desktop
$('.no-touch').on('mousemove',function(event) {
// Toolbar and Window width
var tableToolbar = $('.ac-table-toolbar'),
winWidth = $(window).width();
// If cursor enters right hand side of the screen start the timer
// and execute after 2 seconds
if(event.pageX > (winWidth - 20)) {
// Timeout
timer = setTimeout(function()
{
// Add active class to toobar and css transition will animate it
// to open position
tableToolbar.addClass('active').removeClass('notActive');
}, 2000);
}
// If mouse pointer leaves right hand side of the screen and
// still has notActive class cancel the timeout to prevent
// the toolbar from opening
if(event.pageX < (winWidth - 20) && tableToolbar.hasClass('notActive'))
{
clearTimeout(timer);
}
// Toolbar has active class so we know its visible
if(tableToolbar.hasClass('active') && event.pageX < (winWidth - 220))
{
// Clear timeout (if needed?)
clearTimeout(timer);
// Remove active class and css transition will return it to docked position
tableToolbar.removeClass('active').addClass('notActive');
}
});
}
The animation is handled with CSS transitions that are triggered by the active notActive classes.
Please can anyone point me in the right direction. Many thanks in advance.
Too complex for this task. Big amount of mousemove events will slow down your page. Try to use another approach:
HTML:
<div id='rightActivateZone'></div>
CSS:
#rightActivateZone {
background-color: red; // change to transparent for your purpose
height: 100%;
width: 20px;
position: fixed;
top: 0;
right: 0;
}
JS:
var timer;
$('#rightActivateZone').on('mouseenter', function() {
timer = setTimeout(function() {
alert('fire!'); // your code to show menu is here
}, 2000);
});
$('#rightActivateZone').on('mouseleave', function() {
clearTimeout(timer);
});
JSFiddle demo
I agree with finelords answer. That is the best approach but to answer your question
Demo: http://jsfiddle.net/robschmuecker/EZJv6/
We had to do a check on the timer being in existence aswell, see comments below.
JS:
var timer = null;
function openToolbar() {
// Moved these out of event to prevent re-processing.
// Toolbar and Window width
var tableToolbar = $('.ac-table-toolbar'),
winWidth = $(window).width();
// Only execute for desktop
$('.no-touch').on('mousemove', function (event) {
// If cursor enters right hand side of the screen start the timer
// and execute after 2 seconds
// here you are setting a timer on every mousemove, even the ones when the cursor is over the active bar so we need to fix by checking if
if (event.pageX > (winWidth - 20) && tableToolbar.hasClass('notActive') && timer == null) {
// Timeout
console.log('setting timeout');
timer = setTimeout(function () {
// Add active class to toobar and css transition will animate it to open position
tableToolbar.addClass('active').removeClass('notActive');
}, 500);
}
// If mouse pointer leaves right hand side of the screen and
// still has notActive class cancel the timeout to prevent
// the toolbar from opening
if (event.pageX < (winWidth - 20) && tableToolbar.hasClass('notActive') && timer != null) {
clearTimeout(timer);
timer = null;
console.log('cancelling timeout 1');
}
// Toolbar has active class so we know its visible
if (tableToolbar.hasClass('active') && event.pageX < (winWidth - 20)) {
// Clear timeout (if needed?)
clearTimeout(timer);
timer = null;
console.log('cancelling timeout 2');
// Remove active class and css transition will return it to docked position
tableToolbar.removeClass('active').addClass('notActive');
}
});
}
openToolbar();
Rather than clearing the time out, perhaps let it run, but keep track of the latest mouse position
var currentX;
function openToolbar()
{
// Only execute for desktop
$('.no-touch').on('mousemove',function(event) {
currentX = event.pageX;
// Toolbar and Window width
var tableToolbar = $('.ac-table-toolbar'),
winWidth = $(window).width();
// If cursor enters right hand side of the screen start the timer
// and execute after 2 seconds
if(currentX > (winWidth - 20)) {
// Timeout
timer = setTimeout(function()
{
// check the mouse position after the timeout
if(currentX > (winWidth - 20)) {
// Add active class to toobar and css transition will animate it
// to open position
tableToolbar.addClass('active').removeClass('notActive');
}
}, 2000);
}
// Toolbar has active class so we know its visible
if(tableToolbar.hasClass('active') && currentX < (winWidth - 220))
{
// Remove active class and css transition will return it to docked position
tableToolbar.removeClass('active').addClass('notActive');
}
});
}
I am writing a basic code for an animation on click with Snap.svg. It looks like this:
var s = Snap(500, 500);
var circle = s.rect(100,100,100,100);
circle.click(function(){
var width = circle.attr('width');
var height = circle.attr('height');
circle.animate({
width: width/2,
height :height/2
}, 2000);
});
I make a rectangle in the top left corner of the container and animate it's width on a click. THEN, however, I want to do something different on the second click, return it to its original state for example.
I'd also be glad to learn how do you handle this second click in Javascript in general.
For example: press this button once and the slide navigation opens. Tap it second time and the navigation dissappears.
Thanks in advance!
You can do that by using the event.detail property. In your case, that would be:
circle.click(function(e) {
var width = circle.attr('width');
var height = circle.attr('height');
if (e.detail == 1) {
circle.animate({
width: width/2,
height :height/2
}, 2000);
} else if (e.detail == 2) {
circle.animate({ //example
width:width,
height:height
}, 2000);
}
});
There, the animation to change back to the original sizes plays when the user performs a double click (so 2x fast). If you basically want to toggle the element, instead of reverting it on doubleclick, you can simply check if the element has a width or height style other than its initial width or height:
circle.click(function(e) {
var width = circle.attr('width');
var height = circle.attr('height');
if (parseInt(this.style.width) == parseInt(width) || !this.style.width) {
circle.animate({
width: width/2,
height :height/2
}, 2000);
} else {
circle.animate({ //example
width:width,
height:height
}, 2000);
}
});
Then the if() will return true when either the width attribute is equal to the width style, or when the width style is empty/not defined.
You'd want to store what state of the click.
There are many different ways to go about this, but I'll choose two:
Create a counter variable (say, counter) and increment it each time the click handler runs. Then, each time, to decide what to do, see if the number is even or odd:
var counter = 0;
circle.click(function(){
if(counter % 2 == 0){
//action1
}else{
//action2
}
counter++;
});
Alternatively, you can use a Boolean that changes each time to keep track of which action to perform.
var flag = true;
circle.click(function(){
if(flag){
//action1
flag = false;
}else{
//action2
flag = true;
}
});
I have a responsive layout and I've created a fading panels animated element with jQuery. I set the jQuery function to only activate if the user is above a certain screen size. However, if I scale the window down, the function still runs.
Here's what I'd like to achieve:
When the user scrolls bellow a browser width of 1440px, stop that fading panels animation.
Once the animation is stopped, I want to reset the area to display the 1st panel.
If the user scrolls back up above that screen size, start the animation again.
Here is my code, thanks in advance for your time:
// Get the viewport size!
var viewport = $(document).width();
if (viewport >= 1140) {
var InfiniteRotator =
{
init: function()
{
// hard set height of container
$('#circles').height('286.717px');
// initial fade-in time
var initialInterval = 3000;
// interval between items
var itemInterval = 5000;
// cross-fade time
var fadeTime = 2000;
// count number of items
var numberOfItem = $('.rotating-item').length;
// set current item
var currentItem = 0;
// create loop
var infiniteLoop = setInterval(function() {
// initial fade out
$('.rotating-item').eq(currentItem).fadeOut(fadeTime);
// set counter
if (currentItem == numberOfItem -1) {
currentItem = 0;
} else {
currentItem++;
}
// next item fade in
$('.rotating-item').eq(currentItem).fadeIn(fadeTime);
}, itemInterval);
}
}
// go Go GO!
InfiniteRotator.init();
}
Please note: I used this great tutorial to create the fading panels: http://trendmedia.com/news/infinite-rotating-images-using-jquery-javascript/
window.onresize = function() {
clearInterval(infiniteLoop)
}
Note that you must still be in your init function in order to get the infiniteLoop variable.
You can use
window.onresize = function(){ ... }
$(window).resize(function() {
//stop and reset animation in here.
});