How to display a Canvas in a Bootstrap Modal

不问归期 提交于 2021-01-28 08:59:53

问题


I created a map where you can book bikes via Javascript. The user is supposed to : 1) select a bike station (green station = bikes are available) 2) click on a button (reserver button) 3) sign in a canvas (in a modal)

The page is here : http://p4547.phpnet.org/bikes/reservation.html

In my javascript, the Class Object is called this way :


      document.addEventListener("DOMContentLoaded", event => {
        new Signature();

This code is working fine if the canvas is located in the body of the page. But the code is not working if the canvas is located in the modal.

I tried to code this way :

$('#bookingmodal').on('shown.bs.modal',function(event){
new Signature();

    });


My modal ID is : #bookingmodal


回答1:


Your problem is in the calculation of the coordinates for the mouse-position inside the canvas. If you resize the page to a really small window the drawing sometimes works (with an ugly offset).

I took your Signature-class and replaced the calculation for the mouse-position inside the canvas with a function that calculates the correct position of the mouse and also handles possible scaling of the bitmap used by the canvas:

updateMousePosition(mX, mY) {
  let rect = this.canvas.getBoundingClientRect();
  let scaleX = this.canvas.width / rect.width;
  let scaleY = this.canvas.height / rect.height;
  this.cursorX = (mX - rect.left) * scaleX;
  this.cursorY = (mY - rect.top) * scaleY;
}

Example:

class Signature {
  constructor() {
    this.color = "#000000";
    this.sign = false;
    this.begin_sign = false;
    this.width_line = 5;
    this.canvas = document.getElementById('canvas');
    this.offsetLeft = this.canvas.offsetLeft;
    this.offsetTop = this.canvas.offsetTop;
    this.context = canvas.getContext('2d');
    this.context.lineJoin = 'round';
    this.context.lineCap = 'round';
    this.whenMouseDown();
    this.whenMouseUp();
    this.whenMouseMove();
    this.createSignature();
    this.clearCanvas();
    this.resetCanvas();
  }

  updateMousePosition(mX, mY) {
    let rect = this.canvas.getBoundingClientRect();
    let scaleX = this.canvas.width / rect.width;
    let scaleY = this.canvas.height / rect.height;
    this.cursorX = (mX - rect.left) * scaleX;
    this.cursorY = (mY - rect.top) * scaleY;
  }
  
  whenMouseDown() {
    document.addEventListener("mousedown", ({
      pageX,
      pageY
    }) => {
      this.sign = true;
      this.updateMousePosition(pageX, pageY);
    })
  }

  whenMouseUp() {
    document.addEventListener("mouseup", () => {
      this.sign = false;
      this.begin_sign = false;
    })
  }

  whenMouseMove() {
    this.canvas.addEventListener('mousemove', ({
      pageX,
      pageY
    }) => {
      if (this.sign) {
        this.updateMousePosition(pageX, pageY);
        this.createSignature();
      }
    })
  }

  createSignature() {
    if (!this.begin_sign) {
      this.context.beginPath();
      this.context.moveTo(this.cursorX, this.cursorY);
      this.begin_sign = true;
    } else {
      this.context.lineTo(this.cursorX, this.cursorY);
      this.context.strokeStyle = this.color;
      this.context.lineWidth = this.width_line;
      this.context.stroke();
    }
  }

  clearCanvas() {
    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }

  resetCanvas() {
    document.getElementById("reset").addEventListener("click", () => {
      this.clearCanvas();
    })
  }
}

document.addEventListener("DOMContentLoaded", event => {
  new Signature();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<button type="button" class="btn btn-success" data-target="#bookingmodal" data-toggle="modal">Réserver</button>

<div aria-labelledby="exampleModalLongTitle" class="modal fade" id="bookingmodal" role="dialog" tabindex="-1" style="display: none;" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLongTitle">Réservation</h5><button aria-label="Close" class="close" data-dismiss="modal" type="button"><span aria-hidden="true">×</span></button>
        </div>
        <div class="modal-body">
          <div class="guide">
            <div class="row item">
              <div class="col-md-12 order-md-2">
                <h2 class="item-heading">Signature. <span class="text-muted">Signez pour valider votre réservation.</span></h2>
                  <canvas id="canvas" width="250" height="250">
                  </canvas>
                  <form>
                       <input type="button" id="reset" value="Réinitialiser" class="btn btn-danger">
                  </form>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-secondary" data-dismiss="modal" type="button">Fermer</button>
        </div>
      </div>
    </div>
  </div>


来源:https://stackoverflow.com/questions/56719260/how-to-display-a-canvas-in-a-bootstrap-modal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!