text: export class speakerBadgePage {
  
      constructor(element) {
          this.canvas = element.querySelector("canvas");
  
          this.speakerId = this.canvas.getAttribute("data-speaker-id");
          this.speakerName = this.canvas.getAttribute("data-speaker-name");
          this.canvas.addEventListener("dragover", this.handleDragOver.bind(this));
          this.canvas.addEventListener("drop", this.handleDrop.bind(this));
  
          this.drawBadge();
      }
  
      handleDragOver(event) {
          event.stopPropagation();
          event.preventDefault();
          event.dataTransfer.dropEffect = 'copy'; // Makes the browser display a "copy" cursor.
      }
  
      handleDrop(event) {
          event.stopPropagation();
          event.preventDefault();
  
          const files = event.dataTransfer.files;
          if (files.length == 0) return;
  
          // More than one file could have been dropped, we'll just use the first.
          const file = files[0];
          if (this.isImageType(file.type)) {
              this.readFile(file)
                  .then((file) => this.loadImage(file))
                  .then((file) => this.drawBadge(file));
          } else {
              alert("Please drop an image file.");
          }
      }
  
      drawBadge(image) {
          // TODO: Get the canvas's (this.canvas) context and assign to this.context
          this.context = this.canvas.getContext("2d");
  
          // TODO: Draw the following by calling the helper methods of `this`
          //       background
          //       top text
          //       speaker name
          //       image (or placeholder if no image)
          //       bar code (passing this.speakerId)
          this.drawBackground();
          this.drawTopText();
          this.drawSpeakerName();
          if (image) {
              this.drawSpeakerImage(image);
          } else {
              this.drawImagePlaceholder();
          }
          this.drawBarCode(this.speakerId);
      }
  
      drawBackground() {
          // TODO: Fill the canvas with a white rectangle
          this.context.fillStyle = "white";
          this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
      }
  
      drawSpeakerImage(image) {
          // TODO: Draw the image on the canvas
          //       Draw only the center square of the image
          //       Draw at:
          //       x, y = 20, 20
          //       w, h = 160, 160
          const size = Math.min(image.width, image.height);
          const sourceX = image.width / 2 - size / 2;
          const sourceY = image.height / 2 - size / 2;
          this.context.drawImage(image, sourceX, sourceY, size, size, 20, 20, 160, 160);
      }
  
      drawImagePlaceholder() {
          this.context.strokeStyle = "2px #888";
          this.context.strokeRect(20, 20, 160, 160);
          this.context.font = "12px sans-serif";
          this.context.textBaseline = "middle";
          this.context.textAlign = "center";
          this.context.fillStyle = "black";
          this.context.fillText("Drag your profile photo here", 100, 100);
      }
  
      drawTopText() {
          this.context.font = "20px sans-serif";
          this.context.fillStyle = "black";
          this.context.textBaseline = "top";
          this.context.textAlign = "left";
          this.context.fillText("ContosoConf 2013 Speaker:", 200, 20);
      }
  
      drawSpeakerName() {
          // TODO: Draw this.speakerName on the canvas
          //       x, y = 200, 60
          //       font = 40px sans-serif
          //       fill style = black
          //       text baseline = top
          //       text align = left
          this.context.font = "40px sans-serif";
          this.context.fileStyle = "black";
          this.context.baseLine = "top";
          this.context.textAlign = "left";
          this.context.fillText(this.speakerName, 200, 60);
      }
  
      drawBarCode(text) {
          text = "*" + text + "*"; // Wrap in "*" deliminators.
          const encodings = {
              "0": "bwbWBwBwb",
              "1": "BwbWbwbwB",
              "2": "bwBWbwbwB",
              "3": "BwBWbwbwb",
              "4": "bwbWBwbwB",
              "5": "BwbWBwbwb",
              "6": "bwBWBwbwb",
              "7": "bwbWbwBwB",
              "8": "BwbWbwBwb",
              "9": "bwBWbwBwb",
              "*": "bWbwBwBwb"
          };
          let x = 200, y = 140, height = 40, thick = 6, thin = 2;
          for (let charIndex = 0; charIndex < text.length; charIndex++) {
              const code = encodings[text[charIndex]];
              for (let stripeIndex = 0; stripeIndex < code.length; stripeIndex++) {
                  if (stripeIndex % 2 === 0) {
                      this.context.fillStyle = "black";
                  } else {
                      this.context.fillStyle = "white";
                  }
                  const isWideStripe = code.charCodeAt(stripeIndex) < 91;
                  if (isWideStripe) {
                      this.context.fillRect(x, y, thick, height);
                      x += thick;
                  } else {
                      this.context.fillRect(x, y, thin, height);
                      x += thin;
                  }
              }
  
              if (charIndex < text.length - 1) {
                  // Space between each
                  this.context.fillStyle = "white";
                  this.context.fillRect(x, y, thin, height);
                  x += thin;
              }
          }
      }
  
      isImageType(type) {
          const imageTypes = ["image/jpeg", "image/jpg", "image/png"];
          return imageTypes.indexOf(type) === 0;
      }
  
      readFile(file) {
          // Return a new promise.
          return new Promise(function (resolve, reject) {
  
              const reader = new FileReader();
  
              reader.onload = function (loadEvent) {
                  const fileDataUrl = loadEvent.target.result;
  
                  resolve([fileDataUrl]);
              };
  
              reader.readAsDataURL(file);
          });
      }
  
      
  
      loadImage(imageUrl) {
  
          // Return a new promise.
          return new Promise(function (resolve, reject) {
              const image = new Image();
  
              image.onload = function () {
                  resolve(image);
              };
  
              image.src = imageUrl; // This starts the image loading
          });
          
      }
  }