Search code examples
javascriptoverlaygreasemonkeytampermonkey

How to overlay a figure using Greasemonkey (or Tampermonkey)?


How do I draw a circle on a specific position over a website using Greasemonkey?

I tried this, but it didn't work:

// ==UserScript==
// @name         test
// @match        stackoverflow.com/

var canv = document.createElement('canvas');
canv.id = 'someId';

var c=document.getElementById("someId");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.arc(100,75,50,0,2*Math.PI);
ctx.stroke();

Solution

  • The immediate problem with that code is that nowhere was something like .appendChild(canv) used to actually add it to the page.


    But if you really want to overlay a figure on some 3rd-party website, you need more than that.
    You need to:

    1. Get a handle to the target "figure" (image or other node).
    2. Create a canvas of the same size and add it to the page.
    3. Use CSS to position over the target node(s) from step 1. To make this part easier, I suggest wrapping the target node(s) in a <div> or <span>. See below.
    4. Draw to the canvas as desired.

    For example, suppose the target webpage has some kawaii picture that you must markup:
          It's ADORABLE!

    Here's one way with this complete script:

    // ==UserScript==
    // @name     _Overlay the only image
    // @match    *://YOUR_SERVER.COM/YOUR_PATH/*
    // @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
    // @grant    GM_addStyle
    // @grant    GM.listValues 
    // ==/UserScript==
    //- The @grant directives are needed to restore the proper sandbox.
    
    var jImg    = $("img");
    /*-- Contain the image in a position-relative element so that the canvas can use
        absolute positioning to fly over it.
    */
    jImg.wrap (
        $("<span>", {id:"gmWrpSpn", style: "display: inline-block; position: relative;"} )
    );
    var targW = jImg[0].width,  targH = jImg[0].height;
    var jCanvas = $(`<canvas width=${targW} height=${targH}>`).css ( {
        position: "absolute",
        top: 0,
        left: 0
    } ).insertAfter (jImg);
    var cCntxt          = jCanvas[0].getContext ("2d");
    cCntxt.lineWidth    = 7;
    cCntxt.strokeStyle  = '#FF8300';
    cCntxt.beginPath ();
    cCntxt.moveTo ( 30, 170);
    cCntxt.lineTo (100,  30);
    cCntxt.lineTo (170, 170);
    cCntxt.closePath ();
    cCntxt.stroke ();
    cCntxt.beginPath ();
    cCntxt.moveTo (100,  30);
    cCntxt.lineTo (100, 170);
    cCntxt.stroke ();
    cCntxt.beginPath ();
    cCntxt.arc (100.5, 127.5855, 42.4145, 0, 2*Math.PI);
    cCntxt.stroke ();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <p>Lorem Ipsum <img src="https://i.sstatic.net/itbfI.jpg"></p>

    Run the code snippet to see the script in action.