Home > database >  Error in camera App / Type error: null on 'getContext'
Error in camera App / Type error: null on 'getContext'

Time:10-14

I have a b-modal with a camara app.

First I had my <video> and my canvas seperate - but now I want to have them overlapping each other. So first I want to show my video with my button make photo - if I press this my canvas with the taken photo and the other two buttons delete upload should be shown.

But I always get following error (I made a comment in my code where the error is):

[Vue warn]: Error in v-on handler: "TypeError: Cannot read properties of null (reading 'getContext')"

How can I handle this? Thanks!

<template>
  <div :id="IDParent 'camera'">
    <div class="text-center" info>
      <div center :close="false">
        <p class="heading">Make photo</p>
      </div>
      <div>
        <video v-if="hide" class="mb-4" ref="video" id="video" width="100%" height="100%" autoplay />
        <canvas v-if="!hide" class="mb-4" id="responsive-canvas"></canvas>
        <div class="row mb-5">
          <div class="col-md-12">
            <b-button v-if="hide" variant="block p-3 colorSuccess" @click="takePicture()"><b-icon icon="camera-fill"></b-icon> Make Photo</b-button>
          </div>
          <div class="col-md-4">
            <b-button v-if="!hide" variant="block p-3 colorDanger mb-2" @click="deletePicture()"><b-icon icon="exclamation-circle-fill"></b-icon> Delete </b-button>
          </div>
          <div class="col-md-8">
            <b-button v-if="!hide" variant="block p-3 colorSuccess" @click="uploadPicture()"><b-icon icon="cloud-upload"></b-icon> upload photo</b-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>

export default {
  data() {
    return {
      video: {},
      canvas: {},
      captures: [],
      push: false,
      hide: true,
    }
  },

  props: [
    "IDParent",
    ],

  mounted() {
    this.video = this.$refs.video;
    if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
             this.video.srcObject = stream;
                this.video.play();
                this.video.onplay = function () {
                };
                this.video.play();
        });
    }
    },

  methods: {

    closeModal() {
      
    },

    uploadPicture() {

    },

    takePicture() {
      if(this.hide == true) {
      const picture = document.querySelector("canvas"); //ERROR IN THIS LINE! 
      const ctx = picture.getContext("2d");
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";
      ctx.drawImage(document.querySelector("video"), 0, 0, picture.width, picture.height);
      }
      this.hide = false;
    },

    showCanvas() {
        var canvas = document.getElementById('responsive-canvas');
        var heightRatio = 0.75;
        canvas.height = canvas.width * heightRatio;
    },

    deletePicture() {
      const inputPicture = document.querySelector("canvas");
      const context = inputPicture.getContext("2d");
      context.clearRect(0, 0, inputPicture.width, inputPicture.height);

      this.hide = true;
    },

    capture() {
        this.canvas = this.$refs.canvas;
        this.canvas.getContext("2d").drawImage(this.video, 0, 0, 640, 480);
        this.captures.push();
    },
  }
}

</script>

CodePudding user response:

If you carefully observe the below function,

 takePicture() {
      if(this.hide == true) {
      const picture = document.querySelector("canvas"); //ERROR IN THIS LINE! 
      const ctx = picture.getContext("2d");
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";
      ctx.drawImage(document.querySelector("video"), 0, 0, picture.width, picture.height);
      }
      this.hide = false;
    },

the above gets triggered on clicking the below button

<b-button v-if="hide" variant="block p-3 colorSuccess" @click="takePicture()"><b-icon icon="camera-fill"></b-icon> Make Photo</b-button>

Note the condition v-if="hide", at this instant you canvas is hidden from the Dom because of the below condition that you have used

<canvas v-if="!hide" class="mb-4" id="responsive-canvas"></canvas>

Thats the reason why when you try to query it, its showing error.

Modify your condition so that its available on DOM and then try to access it

  • Related