Ionic 4 page dimensions after orientation change - ionic-framework

I have a component in my Ionic app, that requires the screen dimensions. I am trying to use the Platform plugin to grab the new screen dimensions, after the user changes the orientation of their device. I am trying to do so with the following code:
#Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.scss'],
})
export class MyComponent implements OnInit, OnDestroy {
deviceWidth: number;
deviceHeight: number;
subs = new Subscription();
constructor(private platform: Platform) {}
ngOnInit() {
subs.add(this.platform.resize.subscribe(async () => {
this.deviceWidth = this.platform.width();
this.deviceHeight = this.platform.height();
console.log(this.platformHeight, this.platformWidth);
});
}
ngOnDestroy() {
this.subs.unsubscribe();
}
}
The issue that I am running into is that platform.resize is called before the animation/transition to the new orientation is complete. And thus, platform.height() and platform.width() are incorrect (they both get set to the smallest dimension of the device). In order to test this, I tried the following for my resize subscription:
subs.add(this.platform.resize.subscribe(async () => {
console.log(`Initial Call- width: ${this.platform.width}, height: ${this.platform.height}`);
setTimeout({ // wait until long after the transition animation
console.log(`After Transition- width: ${this.platform.width}, height: ${this.platform.height}`);
}, 1000);
});
which yields the following, after an orientation change from landscape to portrait:
Initial Call- width: 414, height: 414
After Transition- width: 414, height: 896
Any thoughts on how I can get the proper width/height, without inserting some random setTimeout in the subscription?

The best way i found for my app was to use screen orientation (https://ionicframework.com/docs/v3/native/screen-orientation/).
With that framework you can check landscape/portrait orientation.
Then in your case you just have to make a promise inside the two IF you'll make to get proper size in each orientation

Related

Is there a way to make an ion-modal-sheet to snap the header in Ionic V6

I'm currently developing an app using Ionic V6 and i'm figured out if it was possible to make an ion-modal-sheet snap the header when it fully swiped like the Uber eats application ?
Thanks in advance for your answers and have a nice day !
For those who wondering how to do it, here's how i managed to get something similar:
first of all i've added an id to my header (my ion-header is wrapped inside a component called header) if your header is always in the same page of where you're creating the modal, use a template reference variable instead of an id:
<header
id="getHeight"
[title]="'Solutions disponibles'"
[displayGoBack]="true"></header>
then i've created a helper to:
Get the height of the header (can be different between iOS and Android)
Get the body height
Use the body height and the header height to return the height my modal should have in px and in %
export const getContentHeight = (): any => {
const header = document.querySelector('#getHeight');
const body = document.querySelector('body');
if (body && header) {
const percent = (100 - (header.clientHeight * 100 / body.clientHeight));
return {
height: body.clientHeight - header.clientHeight,
percent: percent
}
}
}
After that i've created another helper to change the visual aspect of my modal when breakpoint reach 0.9:
export const setModalSheetContentHeight = (modal: HTMLIonModalElement, breakpoint: number, expand: boolean): any => {
if (breakpoint >= 0.9 && !expand) {
modal.classList.add('no-radius');
modal.setCurrentBreakpoint(1);
expand = true;
} else if (breakpoint <= 0.9 && expand) {
modal.classList.remove('no-radius');
expand = false;
}
return expand;
}
The boolean "expand" avoid the helper to always set the modal breakpoint to 1.
Then i've created a method that add some listeners on the modal:
initModalListener(): void {
let expand = false;
// Define if the modal is fully expand
const content = getContentHeight();
// Return an object with content height in px and in %
addEventListener('ionModalWillPresent', () => {
this.modal.setAttribute('style', `--height: ${content.height}px`);
// Set the modal height before it shown to avoid visual bug
});
addEventListener('ionBreakpointDidChange', (e: any) => {
const breakpoint = e.detail.breakpoint;
expand = setModalSheetContentHeight(this.modal, breakpoint, expand);
});
}
And after all of that i call this method inside of the method that create my modal:
private async presentModal(): Promise<void> {
this.modal = await this.modalCtrl.create({
component: YourModalComponent,
breakpoints: [0.3, 0.65, 1],
initialBreakpoint: 0.3,
backdropBreakpoint: 1,
showBackdrop: false,
canDismiss: false,
keyboardClose: true,
id: 'modalSheet',
}
});
this.initModalListener();
await this.modal.present();
}
This is a first shot so i'm sure that there is plenty of thing to adjust but for now, it work pretty well with Ionic 6.

Half white screen when rotate to landscape ionic 4 IOS

I am building an IONIC 4 app in portrait mode. I have forced the app to stay in portrait mode in config.ts file and everything works fine in both android and IOS
On some pages, I am using camera-preview plugin to customize the camera screen. It needed to be in landscape mode so used Screen Orientation plugin to force it landscape on that page and start the camera.
ngOnInit() {
this.platform.ready().then(()=>{
if(this.platform.is('cordova')){
this.screenOrientation.lock(this.screenOrientation.ORIENTATIONS.LANDSCAPE);
this.cameraPreview.onBackButton().then(()=>{
console.log('Back button pushed');
this.close();
})
// this.presentAlertConfirm()
//make short delay of 500ms to start the camera preview
setTimeout(()=>{
this.initCameraPreview()
},500)
}
})
}
Works fine in android.
But in IOS, half of the screen is covered in white as in the image below.
Please help me out to resolve this issue
Solved the issue by modifying the size of the camera preview as
async initCameraPreview(){
await this.cameraPreview.startCamera(
{
x: 0,
y: 0,
width: this.isIOS ? window.screen.height : window.screen.width,
height: this.isIOS ? window.screen.width : window.screen.height,
toBack: true,
previewDrag: false,
tapPhoto: false,
camera: "back"
}
).then(
(res) => {
console.log(res)
},
(err) => {
console.log(err)
});
}

How can I access a Google Home devices screen dimensions?

I am trying to add image views for my Google action, however the images I have supplied do not always fit the screen. I noticed that the image reference says I can supply a height and width in pixels - however I need to know what their screen dimensions are to make it fit! Is there a way I can access this?
Here is my current implementation:
'use strict';
const { dialogflow } = require("actions-on-google");
const functions = require("firebase-functions");
const app = dialogflow();
app.intent('Default Welcome Intent', (conv) => {
conv.ask("testing....");
conv.ask(
new Image({
url: 'https://myurl.com/someimage.jpg',
alt: 'some image',
// width: NEED THIS VALUE
// height: NEED THIS VALUE
})
);
conv.ask("bla bla bla. ");
});
exports.yourAction = functions.https.onRequest(app);
There is currently no way of getting the screen dimensions for the device.
You can set the image to a reasonable size through device testing then use ImageDisplayOptions to adjust the behavior of the image resizing for different screen sizes.

Is there any way to make the background of a 3D-model transparent in a-scene in ionic?

My problem is to how make the white background of a-frame transparent that we just can see whatever we see from the iPhone camera plus the 3D-model.
I have been trying to make AR (Augmented Reality) working in Ionic iOS version. I realised that a-frame can not trigger webcam for some reasons in iOS. So one of the workaround came to my mind is to load 3D model by a-frame and and trigger the camera at the same time. This some how works, in 2/3 of the screen we can see the camera input and 1/3 the model is loaded with white background. If I can transparent the background of the model then at I would be very happy. Is there any way to make the background of the model transparent in Ionic? is there any other workaround for this problem?
what I have in home.page.html is simply:
`
Ionic Blank
<ion-content>
<a-scene *ngIf="iosReady"
renderer="alpha: true;
colorManagement: true;
sortObjects: true;
physicallyCorrectLights: true;
maxCanvasWidth: 1920;
maxCanvasHeight: 1920;">
<a-gltf-model position="1 1 -4"
src="/assets/models/LibertStatue.gltf" ></a-gltf-model>
</a-scene>
</ion-content>`
And in home.page.ts I have:
const cameraPreviewOpts: CameraPreviewOptions = {
x: 0,
y: 0,
width: window.screen.width,
height: window.screen.height,
camera: 'rear',
tapPhoto: true,
previewDrag: true,
toBack: true,
alpha: 1
}
CameraPreview.startCamera(cameraPreviewOpts).then(
(res) => {
console.log(res);
},
(err) => {
console.log(err);
});
});

Jumpy transitions on Chrome and Safari using FullScreen API (or resize)

I have created a portfolio-type (WordPress-based) website, using FullPage and Flexslider (as a absolute positioned pop-up), and it has a FullScreen button, which is currently giving me some nightmares, but only on the second ".section" in of the FullPage (it only has two sections).
I am also using SlimScroll.js as advised on the FullPage documentation as it can be taller than the window.
For Chrome the animation is "clunky", and when it goes fullscreen it waits like a second until it actually does. Please see the image below:
Screenshot of transition happening
I have added the following code and it worked for the first section, but not to the second section...:
html:not(.ios) .fp-section.active {
height: 100vh !important;
}
html:not(.ios) .fp-section.active .fp-tableCell {
height: 100vh !important;
}
On Safari, though, the transition is smooth but, every now and then, when it finishes it flickers...!
On Firefox there's not much problem as the fullscreen fades in and out. (Is there a way to replace it for a zoom-type animation?
My FullPage settings:
$('#fullpage').fullpage({
// Navigation
slideNavigation: false,
// Scrolling
easingcss3: 'cubic-bezier(0.850, 0.000, 0.250, 1.000)', //easeInOutCirc
scrollingSpeed: 500,
scrollOverflow: true,
// Design
controlArrows: false,
// Events
afterLoad: function(anchorLink, index) { // after changing section
if (index == 1){
// Load scrollDown link so that you don't have to load it afterwards
$('#main').load(scrollDown + ' .main-content', function(){
$.fn.fullpage.reBuild();
});
// Hide menu
if ( $( '#site-navigation' ).hasClass( 'toggled' ) ) {
$( '#site-navigation' ).removeClass('toggled');
$( '#site-navigation .menu-toggle').attr( 'aria-expanded', 'false' );
$( '#site-navigation ul').attr( 'aria-expanded', 'false' );
}
}
colorInversion();
popupSlider();
},
afterRender: function() { // so that it applies to first section too
colorInversion();
popupSlider();
},
afterSlideLoad: function( anchorLink, index, slideAnchor, slideIndex) { // after changing slide
//$.fn.fullpage.reBuild();
popupSlider();
}
});
My FlexSlider settings:
$('#popup-slider').flexslider({
animation: 'slide',
slideshow: false,
easing: 'easeInOutExpo',
animationSpeed: 0,
customDirectionNav: $(".flex-direction-nav a"),
// Usability features
video: true,
// Special Properties
manualControls: '.popup-slider-link',
// Callback API
start: function(slider){
$('.slides li *').click(function(event){
event.preventDefault();
slider.flexAnimate(slider.getTarget("next"));
});
},
after: function(){ // After each slider animation completes
flexslideColorInversion(); // Check for color inversion
$('#popup-slider').data('flexslider').vars.animationSpeed = 500; // Put animation speed back to 500
},
});
(Flexslider is initialised inside the popupslider() function.)
Is there a way to "fix" these issues?
Thank you so much in advance to anyone who may be able to help me with this.
EDIT:
I have seen that the lag in Chrome was because the popup was over the thumbnails and therefore was still resizing them even though they weren't in view; my solution to this was to apply a "display: none" to when the popup slider was on.
The Flicker in Safari is because FullPage.js changes the sections' sizes and their "translate3d", so there is a flicker when that adjustment occurs. The default Fullpage.js characteristic is to actually show part of the section above while it's adjusting, but as I am using 100vh for the .active section it doesnt show on Chrome, Opera or Firefox and only flickers in Safari (hence me wondering what the flicker was!)
Probably the only way around it is to recode Fullpage.js's translate3d (and height/width) codes also with "vh" so that it doesn't have to adjust the size. If any one has a ready code of this, that would be really appreciated! (IE8 is support is not required).
Cheers