Canvas page with header/footer displayed wrong when opening first time

Hi,

I got a strange bug since migrating from Ionic 4 to Ionic 5.

I have a modal with a canvas to draw on pictures. The canvas is fullscreen and there are translucent toolbars in the header and footer. The footer toolbar contains an ion-radio-group and an ion-range.

After each restart of the app, the first time (and only the first time) I enter the page with the canvas, the picture gets displayed wrong. It’s not fullscreen and behind the header and footer is a white background. Then the image is scrollable, what means that the header and footer aren’t overlaping the ion-content. After closing the canvas and reopening it, everything works fine, no matter if it’s a new picture or the same. It only doesn’t work the very first time after closing and opening the app again.

I noticed that this bug only occurs if the ion-range or ion-radio-group are in the header or footer toolbar. If I remove them, everything is fine.

The bug exists in Android and iOS.

With Ionic 4, everything worked as expected, but with Ionic 5 it does not. Is this a bug or am I missing a change from Ionic 4 to Ionic 5?

The template:

<ion-header [className]="drawing === false ? 'toolsVisible' : 'toolsHidden'">
  <ion-toolbar>

    <ion-buttons slot="start">
      <ion-button (click)="saveAndQuit()">
        <ion-icon slot="icon-only" name="checkmark"></ion-icon>
      </ion-button>
    </ion-buttons>

    <ion-buttons slot="end">
      <ion-button (click)="clearCanvas()">
        <ion-icon slot="icon-only" name="refresh"></ion-icon>
      </ion-button>
    </ion-buttons>

  </ion-toolbar>
</ion-header>

<ion-content fullscreen forceOverscroll="false">
  <div id="canvas-container">
    <canvas #imgCanvas (touchstart)="startDrawing($event)" (touchmove)="moveDrawing($event)" (touchend)="endDrawing()">
    </canvas>
  </div>
</ion-content>

<ion-footer [className]="drawing === false ? 'toolsVisible' : 'toolsHidden'">
  <ion-toolbar>

    <ion-row>
      <ion-col *ngFor="let color of colors" class="color-block" [style.background]="color" tappable (click)="selectColor(color)"></ion-col>
    </ion-row>

    <ion-radio-group [(ngModel)]="selectedColor">
      <ion-row>
        <ion-col *ngFor="let color of colors" class="ion-text-center">
          <ion-radio [value]="color"></ion-radio>
        </ion-col>
      </ion-row>
    </ion-radio-group>

    <ion-range min="2" max="20" [(ngModel)]="brushSize">
      <ion-icon id="thinBrushIcon" slot="start" name="ellipse"></ion-icon>
      <ion-icon slot="end" name="ellipse"></ion-icon>
    </ion-range>

  </ion-toolbar>
</ion-footer>

Left screenshot: First time entering the page --> broken
Right screenshot: Second time entering the page --> working

I tried a few fixes, but nothing worked. I would be very happy, If someone has a clue what the problem is…

What version of Ionic framework are you using?

I’m using:

  • Ionic v5.2.2
  • Angular v9.1.9
  • Cordova Android v8.1.0
  • Cordova iOS v5.1.1

Btw, the page is opened as a modal.

I guess somewhere you are calculating the size of the canvas, to fit the modal? Is that happening before the modal is completely finished opening?

The size is calculated at ngAfterViewInit(). This is called each time I open the modal, so the size is calculated each time the modal was opened.

I don’t know Angular so just throwing out ideas… try delaying calculating the canvas size for a second or so (temporarily, as a test) to see if the modal is not fully drawn first time.

Also, what about using the ionModalDidPresent modal event, would that solve the problem if in fact the modal is not fully drawn?

I tried it, but it didn’t work.

What I noticed was, that it doesn’t matter if the canvas is loaded or not. Actually, if I load the modal with the ion-header, ion-footer and an empty ion-content, it still doesn’t behave correctly. If I color the backgrounds of header/footer and content differently, you can see that the first time you open the modal the ion-content is not fullsize. So it’s not a problem with the canvas :frowning:

At least you’ve narrowed it down a bit now. Over to the Ionic Team then.

So I tested the whole thing with a new blank Ionic starter project. Just the home screen and a button which opens the following modal page:

HTML

<ion-header>

  <ion-toolbar>

    <ion-buttons slot="start">
      <ion-button>
        <ion-icon slot="icon-only" name="checkmark"></ion-icon>
      </ion-button>
    </ion-buttons>

    <ion-buttons slot="end">
      <ion-button>
        <ion-icon slot="icon-only" name="refresh"></ion-icon>
      </ion-button>
    </ion-buttons>

  </ion-toolbar>

</ion-header>

<ion-content fullscreen forceOverscroll="false">

</ion-content>

<ion-footer>

  <ion-toolbar>

    <ion-range min="2" max="20" [(ngModel)]="brushSize">
      <ion-icon id="thinBrushIcon" slot="start" name="ellipse"></ion-icon>
      <ion-icon slot="end" name="ellipse"></ion-icon>
    </ion-range>

  </ion-toolbar>

</ion-footer>

SCSS

ion-header, ion-footer {
  --background: pink !important;
}

ion-content {
  --background: black !important;
}

ion-toolbar {
  visibility: hidden;

  --background: #222428d1;

  ion-button {
    width: inherit !important;
    height: inherit !important;
    --color: white !important;
  }

  ion-icon {
    color: white;
  }

  #thinBrushIcon {
    font-size: 8px !important;
  }
}

Component

import { Component, OnInit } from '@angular/core';

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

  brushSize = 5;

  constructor() { }

  ngOnInit() {
  }

}

I tried this simple app with Android and ionic serve and the bug occurs on both platforms.

So it’s most likely a bug with Ionic 5, isn’t it? @mhartington

1 Like

Not 100% sure since you’ve just given pseudo-code.
Can you provide a demo in the form of a github repo?

Otherwise, it’s hard to tell what the issue is from just guessing

Sure, I just opened an issue today. You can find a reproduction repo there, I already got a reply from another member of the Ionic team. Thanks for your time!

Hmm, alright I can see the issue.

You should wait until we get a confirmation here before opening an issue.
Reduces the chance of opening something that is a fix on your end vs anything else.

1 Like

Yea, I know, sorry… But I just was pretty damn sure about this one because I recreated the bug on several platforms with several variations and I spend a lot of time with going through my end over and over again. I guess I was just not patient enough for your reply here :sweat_smile: