Search code examples
cordovaionic-frameworkcordova-pluginsionic4capacitor

Ionic 4: Cordova Camera Preview is hiding html-elements, even though "toBack" is set to "true"


For a university project I have to implement an Ionic App using Ionic 4.

The App is showing locations of Street Art in a Map using Geolocation.

In another menu-tab you can scan a QR-Code, which provides data about a specific Street Art from a .json and displays it in the camera preview using the cordova plugin.

The Scan is working perfectly and afterwards the camera preview is opening, but I cant see the objects from the .html even though "toBack" is set to "true".

I am really stuck with this problem and can't find any solution.

import { Component, OnInit, Inject, ViewEncapsulation } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { JsonDataService } from '../../json-data.service';
import { DOCUMENT } from '@angular/common';
import { Toast } from '@ionic-native/toast/ngx';
import { Router } from '@angular/router';
import { NavController } from '@ionic/angular';
import { CameraPreview, CameraPreviewOptions } from '@ionic-native/camera-preview/ngx';
import { Platform } from '@ionic/angular';


@Component({
  selector: 'app-ar',
  templateUrl: './ar.page.html',
  styleUrls: ['./ar.page.scss'],
})
export class ArPage implements OnInit {

  datenData = [];
  selectedProduct: any;
  productFound = false;


  constructor(
    private barcodeScanner: BarcodeScanner,
    private datenService: JsonDataService,
    private toast: Toast,
    private router: Router,
    public navCtrl: NavController, private cameraPreview: CameraPreview, private platform: Platform,
    @Inject(DOCUMENT) private _document) {
    fetch('../../../assets/data/data.json').then(res => res.json())
      .then(data => {
        this.datenData = data.jsondata;
        this.datenService.setJsondata(this.datenData);
        console.log(data);
      });
  }
  ngOnInit() {
    this.qrscan();
  }

  qrscan() {
    this.datenData = this.datenService.getJsondata();
    this.selectedProduct = {};
    this.barcodeScanner.scan().then((barcodeData) => {
      this.selectedProduct = this.datenData.find(daten => daten.qrcode === barcodeData.text);
      if (this.selectedProduct !== undefined) {
        this.productFound = true;
        this.camerapreview();
      } else {
        this.productFound = false;
        this.router.navigate(['/tabs/tab2']);
        this.toast.show(`Product not found`, '5000', 'center').subscribe(
          toast => {
            console.log(toast);
          }
        );
      }
    }, (err) => {
      this.toast.show(err, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
          this.router.navigate(['/tabs/tab2']);
        }
      );
    });
  }

  camerapreview() {
    const cameraPreviewOpts: CameraPreviewOptions = {
      width: window.screen.width,
      height: window.screen.height,
      previewDrag: true,
      toBack: true,
      alpha: 1,
      x: 0,
      y: 0,
      camera: 'rear',
    }
    // start camera
    this.cameraPreview.startCamera(cameraPreviewOpts);
  }
}
html, body, .ion-app, .ion-content, .nav-decor {
  background-color: transparent !important;
}
<ion-header>
  <ion-toolbar text-center>
    <ion-buttons slot="start" defaultHref="/tabs/tab2">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>ar</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
</ion-content>

I would be very greatful, if someone could help me with this issue.

Thank you indeed!


Edit:

Here is the github repository to it: https://github.com/alexandrasophiapetersen/ARapp.

In Pages/ar is an example QR-Code.

Screenshot of the current page (You can tell, that the html-objects are behind the camera preview):

Ar-Page


Solution

  • tl;dr: the cordova-camera-preview plugin isn't compatible with capacitor, see: capacitor/issues/1732 and cordova-plugin-camera-preview/issues/563


    Old answer: Did you make sure that your css is actually taking effect and is setting all important layers to transparent?

    If you put selectors like html in anything but the main app component they won't work out of the box because angular enables ViewEncapsulation by default.

    If this is indeed the case you can fix it by either moving the css into the stylesheet of the main app component or disabling ViewEncapsulation for the page in question:

    @Component({
      selector: 'app-ar',
      templateUrl: './ar.page.html',
      styleUrls: ['./ar.page.scss'],
      encapsulation: ViewEncapsulation.None
    })
    

    Update: try adding

    app-ar ion-content {
      --background: transparent;
    }
    

    the ion-content will otherwise hide the live preview:

    working preview