Shadow rounded rectangle

html JavaScript
<canvas id="canvas" width="2000" height="2000"></canvas>
<script>
  window.onload = function () {
    function urlToFile(url, filename, mimeType) {
      mimeType = mimeType || (url.match(/^data:([^;]+);/) || '')[1];
      return (fetch(url)
        .then(function (res) {
          return res.arrayBuffer();
        })
        .then(function (buf) {
          return new File([buf], filename, {
            type: mimeType
          });
        })
      );
    }

    CanvasRenderingContext2D.prototype.roundRect = function (x, y, width, height, radius) {
      if (width < 2 * radius) radius = width / 2;
      if (height < 2 * radius) radius = height / 2;
      this.beginPath();
      this.moveTo(x + radius, y);
      this.arcTo(x + width, y, x + width, y + height, radius);
      this.arcTo(x + width, y + height, x, y + height, radius);
      this.arcTo(x, y + height, x, y, radius);
      this.arcTo(x, y, x + width, y, radius);
      this.closePath();
      return this;
    }

    let canvas = document.getElementById("canvas");
    let ctx = canvas.getContext("2d");

    let margine = 10;
    let rect = {
      x: margine,
      y: margine,
      width: canvas.width - (margine * 2),
      height: canvas.height - (margine * 2)
    }

    ctx.shadowBlur = 4;
    ctx.shadowColor = "black";

    // Fill in canvas
    ctx.roundRect(rect.x, rect.y, rect.width, rect.height, 20);
    ctx.fillStyle = 'rgba(255, 255, 255, 1)';
    ctx.fill();

    // Convert to file
    urlToFile(canvas.toDataURL("image/svg"), 'img.svg')
      .then(function (file) {
        console.log(file);
        var elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(file);
        elem.download = file.name;
        document.body.appendChild(elem);
        elem.click();
        document.body.removeChild(elem);
      })
  }
</script>

Download canvas

window.onload = function () {
  let canvas = document.getElementById("canvas");
  let ctx = canvas.getContext("2d");

  let margin = 20;
  let rect = {
    x: margin,
    y: margin,
    width: canvas.width - (margin * 2),
    height: canvas.height - (margin * 2)
  }

  // Fill in canvas
  ctx.beginPath();
  ctx.rect(rect.x, rect.y, rect.width, rect.height, 20);
  ctx.stroke();

  let elem = window.document.createElement('a');
  elem.href = canvas.toDataURL("image/png");
  elem.download = 'img.png';
  elem.innerText = "download"
  document.body.appendChild(elem);
  // auto click
  //elem.click();
  //document.body.removeChild(elem);
}

Js prototype

html JavaScript
<div id="output"></div>
<script>
  String.prototype.affiche = function () { // => function don't permit "this"
    document.getElementById('output').innerHTML = this;
  }
  let text1 = "Text to display one";
  let text2 = "Text to display two";
</script>
<button onclick="text1.affiche();">text1.affiche()</button>
<button onclick="text2.affiche();">text2.affiche()</button>

DOM propagation

html JavaScript
  <h2>Box with propagation</h2>
  <div id="boxWithPropagation" class="box">
    <div>
      <div>
      </div>
    </div>
  </div>
  <h2>Box with propagation reverse</h2>
  <div id="boxWithPropagationReverse" class="box">
    <div>
      <div>
      </div>
    </div>
  </div>
  <h2>Box without propagation</h2>
  <div id="boxWithoutPropagation" class="box">
    <div>
      <div>
      </div>
    </div>
  </div>
  <script>
    // Box with propagation
    document.querySelector("#boxWithPropagation").addEventListener("click", () => {
      alert("parent box");
    }, false);
    document.querySelector("#boxWithPropagation > div").addEventListener("click", () => {
      alert("child box");
    }, false);
    document.querySelector("#boxWithPropagation > div > div").addEventListener("click", () => {
      alert("child of child box");
    }, false);

    // Box with propagation reverse
    document.querySelector("#boxWithPropagationReverse").addEventListener("click", () => {
      alert("parent box");
    }, true);
    document.querySelector("#boxWithPropagationReverse > div").addEventListener("click", () => {
      alert("child box");
    }, true);
    document.querySelector("#boxWithPropagationReverse > div > div").addEventListener("click", () => {
      alert("child of child box");
    }, true);

    // Box without propagation
    document.querySelector("#boxWithoutPropagation").addEventListener("click", e => {
      alert("parent box");
      e.stopPropagation();
    });
    document.querySelector("#boxWithoutPropagation > div").addEventListener("click", e => {
      alert("child box");
      e.stopPropagation();
    });
    document.querySelector("#boxWithoutPropagation > div > div").addEventListener("click", e => {
      alert("child of child box");
      e.stopPropagation();
    });
  </script>

Box with propagation

Box with propagation reverse

Box without propagation

Web notification

html JavaScript
<script type="text/javascript">
  function notifyMe() {
    if (Notification.permission !== "granted")
      Notification.requestPermission();
    else
      new Notification('Notification for test', {
        icon: 'data:image/png;base64,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IAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAAQEAkBAIAAEBAJAQCAABAQCQEAgAGoplf8fCRAlRC/GkxYAAAAASUVORK5CYII=',
        body: "Test notification body!",
      }).addEventListener("click", () => window.open("https://magicorp.fr"));
  }
</script>
<button onclick="notifyMe()">Notify moi!</button>

In website notification

html JavaScript
<style>
  #notification {
    max-height: 200px;
    right: 20px;
    top: 20px;
    position: fixed;
    pointer-events: none;
  }

  .notification {
    width: 350px;
    border-radius: 8px;
    padding: 12px;
    text-overflow: ellipsis;
    overflow: hidden;
    animation-name: animationNotification;
    animation-duration: 4s;
  }

  .notification_success {
    background-color: rgba(0, 204, 0, 0.8);
    border: 1px solid rgba(0, 214, 0, 1);
    color: rgb(0, 128, 0);
    margin: 4px;
  }

  .notification_error {
    background-color: rgba(204, 0, 0, 0.8);
    border: 1px solid rgba(214, 0, 0, 1);
    color: rgb(102, 0, 0);
    margin: 4px;
  }

  @keyframes animationNotification {
    0% { opacity: 0; }
    10% { opacity: 0.8; }
    20% { opacity: 1; }
    90% { opacity: 1; }
    100% { opacity: 0; }
  }
</style>

<button class="btn btn-success" onclick="successNotification()">Success notification</button>
<button class="btn btn-danger" onclick="errorNotification()">Error notification</button>
<div id="notification">
  <span></span>
</div>
<script>
  let notification = document.querySelector("#notification");

  function successNotification() {
    notification.insertAdjacentHTML('afterbegin',
      '<p class="notification notification_success">Success notification</p>');
    notification.firstElementChild.addEventListener('animationend',
      function () {
        this.parentNode.removeChild(this)
      });
  }

  function errorNotification() {
    notification.insertAdjacentHTML('afterbegin',
      '<p class="notification notification_error">Error notification</p>');
    notification.firstElementChild.addEventListener('animationend',
      function () {
        this.parentNode.removeChild(this)
      });
  };
</script>

Web geolocation

function getLocation() {
  if (navigator.geolocation)
    navigator.geolocation.getCurrentPosition(pos =>
      document.querySelector("#output").innerHTML = "Latitude: " + pos.coords.latitude +
      "<br>Longitude: " + pos.coords.longitude +
      "<br>Accuracy: " + pos.coords.accuracy +
      "<br>Altitude: " + pos.coords.altitude +
      "<br>Altitude accuracy: " + pos.coords.altitudeAccuracy +
      "<br>Heading: " + pos.coords.heading +
      "<br>Speed: " + pos.coords.speed
    );
  else
    document.querySelector("#output").innerHTML =
    "la geolocation apo n'es pas disponible dans cotre navigateur.";
}

Rand bg color for web page

let bg_colour = Math.floor(Math.random() * 16777215).toString(16);
bg_colour = "#" + ("000000" + bg_colour).slice(-6);
document.querySelector("#colorBox").style.backgroundColor = bg_colour;

Base in js

document.querySelector('#result').innerHTML = parseInt(num, base).toString(newbase);
= __

Open local file

html JavaScript
<video id="v"></video>
<input type="file" id="file" onchange="onChange()" >
<script type="text/javascript">
let URL = window.URL || window.webkitURL;
let video = document.querySelector('#v');
function onChange() {
  let file = document.querySelector('#file');
  video.src = URL.createObjectURL(file.files[0]);;
  video.load();
  video.addEventListener("loadeddata", () => video.play());
}
</script>

Toggle fullscreen html element

function toggleFullScreen(elem) {
  if (document.fullScreenElement || document.mozFullScreenElement || document.webkitIsFullScreen) {
    if (document.cancelFullScreen) document.cancelFullScreen();
    else if (document.mozCancelFullScreen) document.mozCancelFullScreen();
    else if (document.webkitCancelFullScreen) document.webkitCancelFullScreen();
  } else {
    if (elem.requestFullScreen) elem.requestFullScreen();
    else if (elem.mozRequestFullScreen) elem.mozRequestFullScreen();
    else if (elem.webkitRequestFullScreen) elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  }
}

Context menu in web

html JavaScript
<style>
  .context {
    position: absolute;
  }
  .elm-menu {
    margin: 8px;
    padding: 0 4px;
  }

  .elm-menu:hover {
    background-color: #eee;
  }

  .elm {
    height: 100px;
    width: 100px;
    margin: 8px;
    padding: 0 4px;
    background-color: yellow;
    color: blue;
  }

  .cmenu {
    background-color: #fff;
    z-index: 2300;
    display: block;
    position: absolute;
    box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
    text-decoration: none;
    cursor: default;
    margin-top: -4px;
    min-height: 50px;
    min-width: 100px;
    max-height: 640px;
  }
</style>
<div id="cmenu" class="cmenu" style="display:none">
  <div class="elm-menu">default</div>
  <div class="elm-menu">menu</div>
</div>
<div id="cmenu1" class="cmenu" style="display:none">
  <div class="elm-menu">elm1</div>
  <div class="elm-menu">menu</div>
  <div class="elm-menu">contextuel</div>
</div>
<div id="cmenu2" class="cmenu" style="display:none">
  <div class="elm-menu">elm2</div>
  <div class="elm-menu">menu</div>
  <div class="elm-menu">contextuel</div>
</div>
<div class="context">
  <div data-menu="#cmenu">Text for test default menu</div>
  <div data-menu="#cmenu1" class="elm">Box for test menu 1</div>
  <div data-menu="#cmenu2" class="elm">Box for test menu 2</div>
</div>
<script>
  let context = document.querySelector(".context");
  context.addEventListener('contextmenu', elem => {
    elem.preventDefault();

    // Show menu
    document.querySelectorAll(".cmenu").forEach(i => i.style.display = "none");
    if (!elem.srcElement.dataset.menu) return;
    let menu = document.querySelector(elem.srcElement.dataset.menu)
    menu.style.display = "block";
    let mouse = (() => {
      console.log(elem);
      if (elem.layerX || elem.layerY)
        return {
          x: elem.layerX + 10,
          y: elem.layerY + 10
        }
      return {
        x: 0,
        y: 0
      }
    })();

    menu.style.left = (context.innerWidth - mouse.x < menu.offsetWidth) ?
      context.innerWidth - menu.offsetWidth + "px" : mouse.x + "px";

    menu.style.top = (context.innerHeight - mouse.y < menu.offsetHeight) ?
      context.innerHeight - menu.offsetHeight + "px" :
      mouse.y + "px";
  });
  context.addEventListener('click', () =>
    document.querySelectorAll(".cmenu").forEach(i => i.style.display = "none")
  );
</script>
Text for test default menu
Box for test menu 1
Box for test menu 2

RefExp

let str = document.querySelector('#text').value
let patt = new RegExp(document.querySelector('#patt').value);
document.querySelector("#resultTest").innerHTML = patt.test(str);
document.querySelector("#resultExec").innerHTML = patt.exec(str);
Pattern match : Result :

My word at me

html JavaScript
    <style>
    .contents{
      width: 80%;
      height: 600px;
      margin: 50px 8px 8px 8px;
      padding: 8px;
      min-height: 60px;
      background-color: #fff;
      outline: none;
    }
    #toolbar{
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      overflow-x: auto;
      content: "";
      display: table;
      width: max-content;
      overflow: hidden;
      border: 1px solid #ccc;
      color: #000;
      background-color: #f1f1f1;
      position: fixed;
      top: 0;
      z-index: 1;
      margin: 8px;
    }
    #bm i{
      top: -147px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #ul i{
      top: -84px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #ol i{
      top: -84px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #sup i{
      top: -126px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #sub i{
      top: -126px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #bold i{
      top: -1px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #italic i{
      top: -146px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #underline i{
      top: -21px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #strike i{
      top: -22px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #remove i{
      top: 0px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #link i{
      top: -166px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #image i{
      top: -167px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #Center i{
      top: -42px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #Full i{
      top: -42px;
      left: -0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #Left i{
      top: -62px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #Right i{
      top: -62px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #undo i{
      top: -105px;
      left: 0px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #redo i{
      top: -105px;
      left: -21px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #video i{
      top: -187px;
      left: 60px;
      position: absolute;
      content: url(toolbarIconGoogle.png);
    }
    #fontName{
      height: 23px;
    }
    #fontName option{
      background-color: #fff;
    }
    .item-m-i{
      width: 21px;
      height: 21px;
    }
    .item-m{
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      cursor: pointer;
      white-space: normal;
      margin: 4px;
      float: left;
      border: 1px solid rgba(0, 0, 0, 0);
      border-radius: 4px;
      display: block;
      vertical-align: middle;
      overflow: hidden;
      text-decoration: none;
      background-color: inherit;
      text-align: center;
      cursor: pointer;
      position: relative;
    }
    .item-m:hover{
      border: 1px solid #ccc;
    }
    .am{
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      cursor: pointer;
      background-color: inherit;
      border-radius: 4px;
      border: 1px solid rgba(0,0,0,0);
    }
    .am:hover {
      border: 1px solid #aaa;
    }
    .am:hover .aam{
      border-left: 1px solid #aaa;
    }
    .m{
      display: none;
      position: fixed;
      background-color: #fff;
      top: 30px;
      z-index: 1;
      margin: 0px;
      border-radius: 4px;
      border: 1px solid #ccc;
    }
    .aam{
      display: initial;
      border-left: 1px solid rgba(0,0,0,0);
    }
    input[type=color]{
      width: 60px;
    }
    .modal{
      background-color: white;
      height: 100px;
      width: 200px;
      position: fixed;
      z-index: 101;
      top: calc(50% - 50px);
      left: calc(50% - 100px);
      display: none;
    }
    #modal-bg{
      width: 100%;
      height: 100%;
      position: fixed;
      top: 0px;
      left: 0px;
      background-color: rgba(0,0,0,0.5);
      z-index: 100;
      display: none;
    }
    </style>
  <div>
    <div id="toolbar">
      <a class="item-m item-m-i" id="undo"><i></i></a>
      <a class="item-m item-m-i" id="redo"><i></i></a>
      <div class="item-m item-m-i" id="bm"><i class="aam"></i>
        <div class="m" id="m">
          <div class="item-m" id="p">normal</div>
          <a class="item-m" id="h1">Titre1</a>
          <a class="item-m" id="h2">Titre2</a>
          <a class="item-m" id="h3">Titre3</a>
          <a class="item-m" id="h4">Titre4</a>
          <a class="item-m" id="h5">Titre5</a>
        </div>
      </div>
      <select class="item-m" id="fontName">
        <option value="Arial">Arial</option>
        <option value="Calibri">Calibri</option>
        <option value="Comic Sans MS">Comic Sans MS</option>
      </select>
      <a class="item-m item-m-i" id="bold"><i></i></a>
      <a class="item-m item-m-i" id="italic"><i></i></a>
      <a class="item-m item-m-i" id="underline"><i></i></a>
      <a class="item-m item-m-i" id="strike"><i></i></a>
      <div class="item-m am" id="color">color
        <div class="aam" id="bm1">&#x25BE;
          <div class="m" id="m1">
            <input class="item-m aam" type="color" id="textcolor">
          </div>
        </div>
      </div>
      <div class="item-m am" id="bgColor">bgcolor
        <div class="aam" id="bm2">&#x25BE;
          <div class="m" id="m2">
            <input class="item-m aam" type="color" id="backgColor">
          </div>
        </div>
      </div>
      <a class="item-m item-m-i" id="Left"><i></i></a>
      <a class="item-m item-m-i" id="Center"><i></i></a>
      <a class="item-m item-m-i" id="Right"><i></i></a>
      <a class="item-m item-m-i" id="Full"><i></i></a>
      <a class="item-m item-m-i" id="ul"><i></i></a>
      <a class="item-m item-m-i" id="ol"><i></i></a>
      <a class="item-m item-m-i" id="sup"><i></i></a>
      <a class="item-m item-m-i" id="sub"><i></i></a>
      <a class="item-m item-m-i" id="remove"><i></i></a>
      <a class="item-m item-m-i" id="link"><i></i></a>
      <a class="item-m item-m-i" id="image"><i></i></a>
      <a class="item-m" style="width: 80px; text-align: left;" id="video">video &<i></i></a>
  </div>
  <div class="modal" id="modal-link"><div>Entre ton lien :</div><div id="url-m" contenteditable=true></div><button id="btn-link">valider</button></div>
  <div class="modal" id="modal-img"><div></div><button id="btn-img">valider</button></div>
  <div class="modal" id="modal-src"><div>Entre ton code :</div><div id="code-m" contenteditable=true></div><button id="btn-src">valider</button></div>
  <div id="modal-bg"></div>
  <div autofocus class="contents" contenteditable=true>ew ew fweafs d fdfdsaa sfdsadf<div align="center"><img src="http://chris.photobooks.com/tests/rte/moz_resizing/testImage.jpg" alt="Test Image" width="233" height="211"><img src="http://chris.photobooks.com/tests/rte/moz_resizing/testImage.jpg" alt="Test Image" width="234" height="211"> </div><div align="center" style="text-align: left;">asdfkasifjaskdfkosakdflaskfdlasdfas</div><div align="center" style="text-align: left;">&nbsp;fasdf</div><div align="center" style="text-align: left;">sadf asdf asldkfjhuygusidf aojsf asdf sahdfijohasidfh iashdhasiudfhaushdfuhasdfuihasiudfhuiashfiuhasdfa</div><div align="center" style="text-align: left;">sfasmdf nisadifhasidfasdfijasidfjashdf ijasidfjoiasjdfoiasdf</div><div align="center" style="text-align: left;">as dfAsdf nasjiodfhni asdfuias dfhasd fashdfafjas dfasd f</div><div align="center" style="text-align: left;">asdf&nbsp;</div><div align="center" style="text-align: left;">asdfasdfasdf asdfasdfasdfasdfasdf asdfasdfa sdgfa sdfasdfas df</div><div align="center" style="text-align: left;">asdfasdfasdbfu gasdfashdf asjhd ihasdijfhasidhfuashdioasfajsoijfasijfas</div></div></div>
  <script>
  var contadd;
  setInterval(function() {
    if (document.queryCommandValue('bold')=='false') {
      $("#bold").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#bold").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('italic')=='false') {
      $("#italic").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#italic").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('underline')=='false') {
      $("#underline").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#underline").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('StrikeThrough')=='false') {
      $("#strike").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#strike").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('InsertUnorderedList')=='false') {
      $("#ul").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#ul").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('InsertOrderedList')=='false') {
      $("#ol").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#ol").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('superscript')=='false') {
      $("#sup").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#sup").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('subscript')=='false') {
      $("#sub").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#sub").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('justifyCenter')=='false') {
      $("#Center").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#Center").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('justifyFull')=='false') {
      $("#Full").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#Full").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('justifyLeft')=='false') {
      $("#Left").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#Left").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    if (document.queryCommandValue('justifyRight')=='false') {
      $("#Right").css("border", "1px solid rgba(0, 0, 0, 0)").css("background-color", "inherit");
    }else {
      $("#Right").css("border", "1px solid #ccc").css("background-color", "#ccc");
    }
    $("#color").css("color", document.queryCommandValue ('ForeColor'));
    $("#bgColor").css("color", document.queryCommandValue ('backColor'));
  },100)
  var x = true;
  var mod = true;
  $('#link').click( function() {
    mod = false;
    $('#modal-link').show();
    $('#modal-bg').show();
  });
  $('#image').click( function() {
    mod = false;
    $('#modal-img').show();
    $('#modal-bg').show();
  });
  $('#video').click( function() {
    mod = false;
    $('#modal-src').show();
    $('#modal-bg').show();
  });
  $('.contents').focus();
  $('.contents').on('blur',function(){
    if (mod) {
      $('.contents').focus();
    }
  });
  $("body").click( function(e) {
    if (!$(e.target).hasClass("aam")) {
      $('.m').hide();
    }
  })
  $('#bm').children().click(function() {
    $('.m').hide();
    if (x) {
      document.getElementById('m').style.display = "grid";
      x = false;
    }else {
      $('#m').hide();
      x = true;
    }
  })
  $('#bm1').click(function() {
    $('.m').hide();
    $('#m1').toggle();
  })
  $('#bm2').click( function() {
    $('.m').hide();
    $('#m2').toggle();
  })
  $('#p').on('click', function() {
    methods.formatBlock.apply(this, ["<p>"]);
  })
  $('#h1').on('click', function() {
    methods.formatBlock.apply(this, ["<h1>"]);
  })
  $('#h2').on('click', function() {
    methods.formatBlock.apply(this, ["<h2>"]);
  })
  $('#h3').on('click', function() {
    methods.formatBlock.apply(this, ["<h3>"]);
  })
  $('#h4').on('click', function() {
    methods.formatBlock.apply(this, ["<h4>"]);
  })
  $('#h5').on('click', function() {
    methods.formatBlock.apply(this, ["<h5>"]);
  })
  $('#ul').on('click', function() {
    methods.unorderedList.apply(this);
  })
  $('#ol').on('click', function() {
    methods.orderedList.apply(this);
  })
  $('#sup').on('click', function() {
    methods.superscript.apply(this);
  })
  $('#sub').on('click', function() {
    methods.subscript.apply(this);
  })
  $('#bold').on('click', function() {
    methods.bold.apply(this);
  })
  $('#italic').on('click', function() {
    methods.italic.apply(this);
  })
  $('#underline').on('click', function() {
    methods.underline.apply(this);
  })
  $('#strike').on('click', function() {
    methods.strike.apply(this);
  })
  $('#remove').on('click', function() {
    methods.removeFormat.apply(this);
  })
  $('#btn-link').on('click', function() {
    mod = true;
    $('.contents').focus();
    $('.modal').hide();
    $('#modal-bg').hide();
    methods.createLink.apply(this, [$('#url-m').html()]);
    $('#url-m').html("");
  })
  $('#btn-img').on('click', function() {
    mod = true;
    $('.contents').focus();
    $('.modal').hide();
    $('#modal-bg').hide();
    methods.insertImage.apply(this, [$('#').html()]);
    $('#url-m').html("");
  })
  $('#btn-src').on('click', function() {
    mod = true;
    $('.contents').focus();
    $('.modal').hide();
    $('#modal-bg').hide();
    methods.insertVideo.apply(this, [$('#code-m').html()]);
    $('#code-m').html("");
  })
  $('#Center').on('click', function() {
    methods.justifyCenter.apply(this);
  })
  $('#Full').on('click', function() {
    methods.justifyFull.apply(this);
  })
  $('#Left').on('click', function() {
    methods.justifyLeft.apply(this);
  })
  $('#Right').on('click', function() {
    methods.justifyRight.apply(this);
  })
  $('#color').on('click', function() {
    methods.textcolor.apply(this, [$('#textcolor').val()])
  })
  $('#bgColor').on('click', function() {
    methods.backgColor.apply(this, [$('#backgColor').val()])
  })
  $('#undo').on('click', function() {
    methods.undo.apply(this)
  })
  $('#redo').on('click', function() {
    methods.redo.apply(this)
  })
  $('#textcolor').on('change', function(){
    methods.textcolor.apply(this, [$(this).val()]);
  })
  $('#backgColor').on('change', function(){
    methods.backgColor.apply(this, [$(this).val()]);
  })
  $('#fontName').on('change', function(){
    methods.fontName.apply(this, [$(this).val()]);
  })
  var methods = {
    bold: function() {
      document.execCommand("bold", false, null);
    },
    italic: function() {
      document.execCommand("italic", false, null);
    },
    underline: function() {
      document.execCommand("underline", false, null);
    },
    strike: function() {
      document.execCommand("StrikeThrough", false, null);
    },
    orderedList: function() {
      document.execCommand("InsertOrderedList", false, null);
    },
    unorderedList: function() {
      document.execCommand("InsertUnorderedList", false, null);
    },
    superscript: function() {
      document.execCommand("superscript", false, null);
    },
    subscript: function() {
      document.execCommand("subscript", false, null);
    },
    createLink: function(contadd) {
      document.execCommand("createLink", false, contadd);
    },
    insertImage: function(contadd) {
      document.execCommand("InsertImage", false, contadd);
    },
    insertVideo: function(contadd) {
      document.execCommand('insertHTML', false, contadd);
    },
    formatBlock: function(block) {
      document.execCommand("FormatBlock", null, block);
    },
    removeFormat: function() {
      document.execCommand("removeFormat", false, null);
    },
    textcolor: function(color) {
      document.execCommand("ForeColor", false, color);
    },
    backgColor: function(color) {
      document.execCommand("backColor", false, color);
    },
    justifyCenter: function() {
      document.execCommand("justifyCenter", false, null);
    },
    justifyFull: function() {
      document.execCommand("justifyFull", false, null);
    },
    justifyLeft: function() {
      document.execCommand("justifyLeft", false, null);
    },
    justifyRight: function() {
      document.execCommand("justifyRight", false, null);
    },
    undo: function() {
      document.execCommand("undo", false, null);
    },
    redo: function() {
      document.execCommand("redo", false, null);
    },
    fontName: function(font) {
      document.execCommand("fontName", false, font);
    }
  }
  document.execCommand("enableObjectResizing", false, true);
  // TODO: img redimention, orderedList...
  </script>
color
â–¾
bgcolor
â–¾
video &
ew ew fweafs d fdfdsaa sfdsadf
Test ImageTest Image
asdfkasifjaskdfkosakdflaskfdlasdfas
 fasdf
sadf asdf asldkfjhuygusidf aojsf asdf sahdfijohasidfh iashdhasiudfhaushdfuhasdfuihasiudfhuiashfiuhasdfa
sfasmdf nisadifhasidfasdfijasidfjashdf ijasidfjoiasjdfoiasdf
as dfAsdf nasjiodfhni asdfuias dfhasd fashdfafjas dfasd f
asdf 
asdfasdfasdf asdfasdfasdfasdfasdf asdfasdfa sdgfa sdfasdfas df
asdfasdfasdbfu gasdfashdf asjhd ihasdijfhasidhfuashdioasfajsoijfasijfas

Image zoom

html JavaScript
<img src="img/kitten.jpg" alt="kitten" id="kitty">
<div id="view" style="background-image: url('img/kitten.jpg')"></div>
<script>
  document.querySelector("#kitty").addEventListener("mousemove", function (e) {
    document.querySelector("#view").style.backgroundPosition = (((-e.offsetX) * 2) + 50) + "px " + (((-e.offsetY) * 2) + 50) + "px";
  });
</script>
kitten

Load image on client side

html JavaScript
<input type="file" onchange="updateUri(event)">
<img id="output">
<script>
  function updateUri(e) {
    if (!e.target.files && !e.target.files[0]) return;

    let reader = new FileReader(); // Create render
    reader.addEventListener("load", () =>
      // On data loaded on render add result to image element
      document.querySelector('#output').src = reader.result
    );

    reader.readAsDataURL(e.target.files[0]);
  }
</script>

Get time

setInterval(
  () =>
    document.querySelector("#clock").innerHTML = (new Date()).toUTCString(),
  1000
);

Internet status

setInterval(
  () => document.querySelector("#internetstatue").innerHTML = navigator.onLine? "online" : "offline", 
  1000
);
// or
window.addEventListener('online', (event) =>
  document.querySelector("#internetstatue").innerHTML = "online" 
);
window.addEventListener('offline', (event) =>
  document.querySelector("#internetstatue").innerHTML = "offline" 
);
Statue :
calcule en coure

Show / hide HTML element

html JavaScript
<button onclick="toggleElem(event)">hide</button>
<div style="height: 100px; width: 100px; background-color: red;" id="block"></div>
<script>
  function toggleElem(e) {
    if (e.target.innerText != "show") {
      document.querySelector("#block").style.display = "none";
      e.target.innerText = "show";
    } else {
      document.querySelector("#block").style.display = "block";
      e.target.innerText = "hide";
    }
  }
</script>

Timer (setInterval, OOP in js)

html JavaScript
<div id="timer">00:00:00</div>
<button onClick="toggleTimer(event)">start</button>
<button onClick="timer.reset()">Reset</button>
<script>
  class Timer {
    constructor() {
      this.heurs = 0;
      this.minute = 0;
      this.seconde = 0;
      this.interval = null;
    }
    start() {
      if (!this.interval)
        this.interval = setInterval(() => {
          if (this.seconde >= 59) {
            ++this.minute;
            this.seconde = 0;
          } else ++this.seconde;
          if (this.minute >= 59) {
            ++this.heurs;
            this.minute = 0;
          }
          this.elem.innerText =
          (this.heurs < 10? "0" : "") + this.heurs + ":" +
          (this.minute < 10? "0" : "") + this.minute + ":" +
          (this.seconde < 10? "0" : "") + this.seconde;
        }, 1000);
    }
    stop() {
      if (this.interval) clearInterval(this.interval);
      this.interval = null;
    }
    reset() {
      this.heurs = 0;
      this.minute = 0;
      this.seconde = 0;
      this.elem.innerText =
          (this.heurs < 10? "0" : "") + this.heurs + ":" +
          (this.minute < 10? "0" : "") + this.minute + ":" +
          (this.seconde < 10? "0" : "") + this.seconde;
    }
    setDisplay(elem) {
      this.elem = elem;
    }
  }

  let timer = new Timer();
  timer.setDisplay(document.querySelector("#timer"));
  function toggleTimer(e) {
    if (!timer.interval) {
      e.target.innerText = "stop";
      timer.start();
    } else {
      e.target.innerText = "start";
      timer.stop();
    }
  }
</script>
00:00:00

SetTimeout

html JavaScript
<div id="res">...</div>
<button onClick="timeout(event)">start</button>
<script>
  function timeout(e) {
    if (e.target.innerText == "start") {
      document.querySelector("#res").innerText = "Finish in 5 seconds";
      e.target.disabled = true;
      e.target.innerText = "reset";
      setTimeout(() => {
        document.querySelector("#res").innerText = "Finish";
        e.target.disabled = false;
      }, 5000);
    } else {
      e.target.innerText = "start";
      document.querySelector("#res").innerText = "...";
    }
  }
</script>
...

Mouse move

html JavaScript
Mouve your mouse here
<pre id="output"></pre>
<script>
  let output = document.querySelector("#output");
  output.parentElement.addEventListener("mousemove", function (e) {
    output.innerText = "Compared to page => pageX: " + e.pageX + ", pageY: " + e.pageY + "\n" +
      "Compared to window => clientX: " + e.clientX + ", clientY: " + e.clientY + "\n" +
      "Compared to screen => screenX: " + e.screenX + ", screenY: " + e.screenY + "\n" +
      "Compared to element => offsetX: " + e.offsetX + ", offsetY: " + e.offsetY + "\n" +
      "Compared to page => layerX: " + e.layerX + ", layerY: " + e.layerY + "\n" +
      "Compared to window => x: " + e.x + ", y: " + e.y + "\n" +
      "Compared to before cursor position => movementX: " + e.movementX + ", movementY: " + e.movementY
  });
</script>
Mouve your mouse here


            

DOM events

html JavaScript
<!-- https://developer.mozilla.org/en-US/docs/Web/Events -->
<div class="cube" onclick="((e) => $(e.target).toggle(1000))(event)">Toggle square on click</div>
<div class="cube" ondblclick="((e) => $(e.target).toggle(1000))(event)">Toggle square on dblclick</div>
<div class="cube" onmouseenter="((e) => $(e.target).toggle(1000))(event)">Toggle square on mouseenter</div>
<div class="cube" onmouseleave="((e) => $(e.target).toggle(1000))(event)">Toggle square on mouseleave</div>
<div class="cube" onmouseover="((e) => $(e.target).toggle(1000))(event)">Toggle square on mouseover</div>
<div class="cube" onkeyup="((e) => $(e.target).toggle(1000))(event)" contenteditable="true">Toggle square on keyup</div>
<div class="cube" onkeydown="((e) => $(e.target).toggle(1000))(event)" contenteditable="true">Toggle square on keydown</div>
Toggle square on click
Toggle square on dblclick
Toggle square on mouseenter
Toggle square on mouseleave
Toggle square on mouseover
Toggle square on keyup
Toggle square on keydown

Keyboard input

document.querySelector("#keyInput").addEventListener('keydown', function (e) {
  e.preventDefault();
  document.querySelector("#keyCode").innerText =
    "Key code (Deprecated): " + e.keyCode +
    "\nkey: " + e.key +
    "\ncode: " + e.code +
    "\ntype: " + e.type +
    "\nctrlKey: " + e.ctrlKey +
    "\naltKey: " + e.altKey +
    "\nmetaKey: " + e.metaKey +
    "\nshiftKey: " + e.shiftKey +
    "\nisComposing: " + e.isComposing +
    "\nlocation: " + e.location +
    "\nrepeat: " + e.repeat;

  document.querySelector("#msg").innerText = showMsg(e.keyCode);
});
document.querySelector("#keyInput").addEventListener('keyup', function (e) {
  document.querySelector("#keyCode").innerText =
    "Key code (Deprecated): " + e.keyCode +
    "\nkey: " + e.key +
    "\ncode: " + e.code +
    "\ntype: " + e.type +
    "\nctrlKey: " + e.ctrlKey +
    "\naltKey: " + e.altKey +
    "\nmetaKey: " + e.metaKey +
    "\nshiftKey: " + e.shiftKey +
    "\nisComposing: " + e.isComposing +
    "\nlocation: " + e.location +
    "\nrepeat: " + e.repeat;

  document.querySelector("#msg").innerText = showMsg(e.keyCode);
});

function showMsg(key) {
  switch (key) {
    case 37:
      return "left";
      break;
    case 38:
      return "up";
      break;
    case 39:
      return "right";
      break;
    case 40:
      return "down";
      break;
    default:
      return "An other key";
      break;
  }
}

Barcode and camera

html JavaScript
<div>
  <div class="camBox">
    <video id="video" autoplay>Video stream not available.</video>
    <button id="takePicture" disabled>
      <i class="material-icons">photo_camera</i>
    </button>
  </div>
  <div class="camBox">
    <img id="photoPreview" alt="Camera capture" />
  </div>
</div>
<script>
  (async () => {
    let video = document.querySelector("#video");
    let photoPreview = document.querySelector("#photoPreview");
    let takePicture = document.querySelector("#takePicture");
    let canvas = document.createElement("canvas");

    video.addEventListener("mouseover", async function() {
      try {
        let cameraStream = await navigator.mediaDevices.getUserMedia({
          video: {
            facingMode: "environment",
          },
          audio: false,
        });
        // on stream start video
        video.srcObject = cameraStream;
        video.play();

        // Enable button
        takePicture.disabled = false;
        takePicture.addEventListener(
          "click",
          function (ev) {
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;

            // Take video picture
            canvas
              .getContext("2d")
              .drawImage(video, 0, 0, canvas.width, canvas.height);

            // Show picture to preview
            photoPreview.setAttribute("src", canvas.toDataURL("image/png"));

            ev.preventDefault();
          },
          false
        );
      } catch (err) {
        console.error("Error: " + err);
      }
    });
  })();
</script>
<style>
  :root {
    --video-height: 256px;
  }

  .camBox {
    position: relative;
    border-radius: 8px;
    background-color: black;
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
    width: calc(var(--video-height) * 16 / 9);
    height: var(--video-height);
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    margin: 8px;
  }

  .camBox video {
    height: 100%;
    object-fit: fill;
  }

  .camBox img {
    height: 100%;
    object-fit: fill;
  }

  #takePicture {
    position: absolute;
    bottom: 24px;
    right: 24px;
    height: 48px;
    width: 48px;
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    border: none;
    outline: none;
    background-color: white;
  }

  #takePicture:hover {
    box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24),
      0 17px 50px 0 rgba(0, 0, 0, 0.19);
  }

  #takePicture:active {
    transform: translateY(2px);
  }
</style>
Camera capture

Audio panner

html JavaScript
<input type="range" id="volumefasdfsffpqwjfoqwifqwef98" min="0" max="2" value="1" list="gain-vals" step="0.01" />
<datalist id="gain-vals">
	<option value="0" label="min">
	<option value="2" label="max">
</datalist>
<label for="volumefasdfsffpqwjfoqwifqwef98">VOL</label>

<input type="range" id="pannerfasdfsffpqwjfoqwifqwef98" list="pan-vals" min="-1" max="1" value="0" step="0.01" />
<datalist id="pan-vals">
	<option value="-1" label="left">
	<option value="1" label="right">
</datalist>
<label for="pannerfasdfsffpqwjfoqwifqwef98">PAN</label>
<audio id="audiofasdfsffpqwjfoqwifqwef98" src="https://dept-info.labri.fr/~thibault/a-audio/C'est%20l'histoire%20d'un%20A%20-%20mp3/03%20Et%20une%20couche%20de%20TTY.mp3"></audio>
<button id="btnfasdfsffpqwjfoqwifqwef98">click</button>

<script type="text/javascript">
document.querySelector('#btnfasdfsffpqwjfoqwifqwef98').addEventListener('click', function() {
	const AudioContext = window.AudioContext || window.webkitAudioContext;
	const audioElement = document.querySelector('#audiofasdfsffpqwjfoqwifqwef98');
	let audioCtx;
  if(!audioCtx) {
		audioCtx = new AudioContext();
		let track = audioCtx.createMediaElementSource(audioElement);
                //let myArrayBuffer = audioCtx.createBuffer(2, audioCtx.sampleRate * 2.0, audioCtx.sampleRate);

                //for (let channel = 0; channel < 2; channel++)
                //  for (let i = 0; i < audioCtx.sampleRate * 2.0; i++) myArrayBuffer.getChannelData(channel)[i] = Math.random() * 2 - 1;

                //let track = audioCtx.createBufferSource();
                //track.buffer = myArrayBuffer;
		// volume
		const gainNode = audioCtx.createGain();

		const volumeControl = document.querySelector('#volumefasdfsffpqwjfoqwifqwef98');
		volumeControl.addEventListener('input', function() {
			gainNode.gain.value = this.value;
		}, false);

		// panning
		const pannerOptions = { pan: 0 };
		const panner = new StereoPannerNode(audioCtx, pannerOptions);

		const pannerControl = document.querySelector('#pannerfasdfsffpqwjfoqwifqwef98');
		pannerControl.addEventListener('input', function() {
			panner.pan.value = this.value;
		}, false);

		// connect our graph
		track.connect(gainNode).connect(panner).connect(audioCtx.destination);
  //track.start();
	}
	audioElement.play();
})
</script>

Audio oscillator

document.querySelector('#fdsafsadfhiguasfdhihsafusahdfsafdoqwipfqw5').onclick = function () {
    AudioContext = window.AudioContext || window.webkitAudioContext;
    let audioCtx = new AudioContext();

    const oscillator = audioCtx.createOscillator();
    const gainNode = audioCtx.createGain();


    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);

    oscillator.type = "sine";
    oscillator.frequency.value = 440;
    oscillator.start(0);

    gainNode.gain.value = 0.1;
  }

Web countdown

html JavaScript
<head>
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }

    body {
      display: grid;
      place-items: center;
    }
  </style>
</head>
<body>
  <H1>DM in : <span id="datetime"></span></H1>
  <script>
    let dateTimeUTC = new Date("2022-01-01T00:00:00.000Z"); // UTC date time form ISO
    setInterval(
      () => {
        let dateTimeNowUTC = new Date();
        let isPast = dateTimeUTC.getTime() < dateTimeNowUTC.getTime();
        let dateTimeDiffPast = new Date(dateTimeNowUTC - dateTimeUTC);
        let dateTimeDiff = new Date(dateTimeUTC - dateTimeNowUTC);

        let currentDateTimeDiff = isPast ? dateTimeDiffPast : dateTimeDiff;

        let year = 1970 - currentDateTimeDiff.getUTCFullYear();
        let month = currentDateTimeDiff.getUTCMonth();
        let day = 1 - currentDateTimeDiff.getUTCDate();
        let hours = currentDateTimeDiff.getUTCHours();
        let minutes = currentDateTimeDiff.getUTCMinutes();
        let seconds = currentDateTimeDiff.getUTCSeconds();

        let str = Math.abs(year) + "y " + Math.abs(month) + "m " + Math.abs(day) + "d " + Math.abs(hours) + ":" + Math.abs(minutes) + ":" + Math.abs(seconds);
        document.querySelector("#datetime").innerHTML = isPast ? "+" + str : str;
      },
      1000
    );
  </script>
</body>

DM in :

Screen capture

html JavaScript
<video id="video" height="400" autoplay></video>
<button id="toggle">toggle</button>
<script>
  (async () => {
    let capture = false;
    const videoElem = document.querySelector("#video");

    async function toggleCapture(event) {
      if (capture) {
        videoElem.srcObject.getTracks().forEach((track) => track.stop());
        videoElem.srcObject = null;
        capture = false;
      } else {
        try {
          let captureStream = await navigator.mediaDevices.getDisplayMedia({
            video: {
              cursor: "none",
            },
            audio: true,
          });

          videoElem.srcObject = captureStream;

          // Dump debug
          for (const track of videoElem.srcObject.getVideoTracks()) {
            console.info("Track");
            console.info(track);
            console.info("Track settings:");
            console.info(JSON.stringify(track.getSettings(), null, 2));
            console.info("Track constraints:");
            console.info(JSON.stringify(track.getConstraints(), null, 2));
          }
        } catch (err) {
          console.error("Error: " + err);
        }
        capture = true;
      }
    }
    document
      .querySelector("#toggle")
      .addEventListener("click", toggleCapture, false);
  })();
</script>

Screen recorde

html JavaScript
<video id="video" height="400" autoplay></video>
<button id="toggle">toggle capture</button>
<button id="togglerec">toggle recorde</button>
<script>
  (async () => {
    let capture = false;
    const videoElem = document.querySelector("#video");

    async function toggleCapture(event) {
      if (capture) {
        videoElem.srcObject.getTracks().forEach((track) => track.stop());
        videoElem.srcObject = null;
        capture = false;
      } else {
        try {
          let captureStream = await navigator.mediaDevices.getDisplayMedia({
            video: {
              cursor: "never",
            },
            audio: true,
          });

          videoElem.srcObject = captureStream;

          // Recorde
          let rec = new MediaRecorder(captureStream);
          let fileWritableStream;
          let handleFile;

          async function saveChunk(event) {
            let blob = new Blob([event.data], {
              type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
            });
            await fileWritableStream.write(blob);
          }

          rec.addEventListener("start", async function (event) {
            rec.addEventListener("dataavailable", saveChunk);
            fileWritableStream = await handleFile.createWritable();
          });

          rec.addEventListener("stop", async function (event) {
            rec.removeEventListener("dataavailable", saveChunk);
            await fileWritableStream.close();
          });

          async function toggleRec(event) {
            if (rec.state == "recording") rec.stop();
            else {
              handleFile = await window.showSaveFilePicker();
              rec.start(1000 /* One seconde */);
            }
          }

          document
            .querySelector("#togglerec")
            .addEventListener("click", toggleRec, false);

          // Dump debug
          for (const track of videoElem.srcObject.getVideoTracks()) {
            console.info("Track");
            console.info(track);
            console.info("Track settings:");
            console.info(JSON.stringify(track.getSettings(), null, 2));
            console.info("Track constraints:");
            console.info(JSON.stringify(track.getConstraints(), null, 2));
          }
        } catch (err) {
          console.error("Error: " + err);
        }
        capture = true;
      }
    }

    document
      .querySelector("#toggle")
      .addEventListener("click", toggleCapture, false);
  })();
</script>

Reduce

javascript JavaScript
array.reduce((buffer, item, index, originalArray) => {/* process */}, bufferInit);

// examples :
[6, 3, 8].reduce((acc, item) => acc + item, 0);

// two following line do the same thing
[6, 3, 8].reduce((buff, item) => (buff.push(Math.sqrt(item)), buff), []);
[6, 3, 8].reduce((buff, item) => {buff.push(Math.sqrt(item)); return buff;}, []);

Js string manipulation

"test012345".slice(-5); // five last digits return "12345"

"ABC".charCodeAt(0); // return 65 for the first char
"123".split(''); // sting to chars array
String.fromCharCode(65, 66, 67); // return 'ABC'

["1", "4", "5"].every(i => i.match(/\d/i)); // every match

Audio loopback

(async () => {
  const audioElement = document.body.appendChild(document.createElement("audio"));
  audioElement.setAttribute("autoplay", "autoplay");
  audioElement.srcObject = await navigator.mediaDevices.getUserMedia({
    audio: true,
  });
})();

Audio input/output

document.querySelector("#btnStart").addEventListener("click", async () => {
  // DOM elements
  const audioElement = document.createElement("audio");
  audioElement.setAttribute("controls", true);
  audioElement.setAttribute("autoplay", "autoplay");
  document.body.appendChild(audioElement);

  // Capture audio
  const inputMediaStream = await navigator.mediaDevices.getUserMedia({
    audio: true,
  });
  const audioContext = new AudioContext();

  // Source
  const audioSourceStream =
    audioContext.createMediaStreamSource(inputMediaStream);
  // const audioSourceElement = audioContext.createMediaElementSource(audioElement);
  // const audioSourceTrack = audioContext.createMediaStreamTrackSource(inputMediaStream.getAudioTracks()[0]);

  // Destination
  const audioDestinationStream =
    audioContext.createMediaStreamDestination();
  const audioDestinationDefault = audioContext.destination;

  // Connect source to destination
  // audioSourceStream.connect(audioDestinationDefault);
  audioSourceStream.connect(audioDestinationStream);

  // Bind audioDestinationStream to audio element
  const outputMediaStream = new MediaStream();
  outputMediaStream.addTrack(
    audioDestinationStream.stream.getAudioTracks()[0]
  );
  audioElement.srcObject = outputMediaStream;

  // draw
  const canvas = document.createElement("canvas");
  document.body.appendChild(canvas);
  const canvasContext = canvas.getContext("2d");

  // following code found here: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createAnalyser
  const analyser = audioContext.createAnalyser();
  analyser.minDecibels = -90;
  analyser.maxDecibels = -10;
  analyser.smoothingTimeConstant = 0.85;
  analyser.connect(audioDestinationStream);
  // const bufferLength = analyser.frequencyBinCount;

  const width = canvas.width;
  const height = canvas.height;

  analyser.fftSize = 2048;
  const bufferLength = analyser.fftSize;
  // const dataArray = new Float32Array(bufferLength);
  const dataArray = new Uint8Array(bufferLength);

  canvasContext.clearRect(0, 0, width, height);

  const draw = function () {
    drawVisual = requestAnimationFrame(draw);
    analyser.getByteTimeDomainData(dataArray);

    canvasContext.fillStyle = "rgb(200, 200, 200)";
    canvasContext.clearRect(0, 0, width, height);
    canvasContext.lineWidth = 2;
    canvasContext.strokeStyle = "rgb(0, 0, 0)";
    canvasContext.beginPath();

    const sliceWidth = (width * 1.0) / bufferLength;
    let x = 0;
    for (let i = 0; i < bufferLength; i++) {
      let v = dataArray[i] / 128.0;
      let y = (v * height) / 2;
      if (i === 0) {
        canvasContext.moveTo(x, y);
      } else {
        canvasContext.lineTo(x, y);
      }
      x += sliceWidth;
    }
    canvasContext.lineTo(width, height / 2);
    canvasContext.stroke();
  };

  draw();

  // record
  // const chunks = [];
  // const mediaRecorder = new MediaRecorder(dest.stream);
  // mediaRecorder.start();
  // mediaRecorder.stop();
  // mediaRecorder.addEventListener("dataavailable", e => chunks.push(e.data));
  // mediaRecorder.addEventListener("stop", e => {
  //   const blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
  //   document.querySelector("audio").src = URL.createObjectURL(blob);
  // });
});

Web vibeate

window.navigator.vibrate(120000);

Bind callback lihandler listener to a class

class Perso {
    #element;
    #name;
    #onClick(event) {
        let currentElement = event.target;
        let persoInstance = this; // the Perso instance
        console.log(currentElement, persoInstance);
    }
    constructor(name, color) {
        this.#name = name;
        this.#element = document.createElement("div");
        this.#element.style.width = "40px";
        this.#element.style.height = "40px";
        this.#element.style.backgroundColor = color;
        this.#element.title = name;
        document.body.appendChild(this.#element);
        this.#element.addEventListener('click', this.#onClick.bind(this));
    }
    get name() {
        return this.#name;
    }
}
const toto = new Perso("Toto", "blue");
const titi = new Perso("Titi", "red");

Mouse capture

elem.addEventListener("click", function() {
  elem.requestPointerLock();
});
Click here