Upload Image onclick on Multiple mask Images

2019-05-01 05:58发布

问题:

Once user click on Mask image, we are allowing user to upload custom image, this is working fine if there is single mask image : https://codepen.io/kidsdial/pen/jJBVON

Requirement :

but if there are multiple mask images, then also user should be able to upload custom images on all mask images [ something like https://codepen.io/kidsdial/pen/rRmYPr ] , but right now its working only for single image....

2 images codepen : https://codepen.io/kidsdial/pen/xBLrjY

8 images codepen : https://codepen.io/kidsdial/pen/ywMVOY

var mask;

let jsonData = {
  "path" : " newyear collage\/",
  "info" : {
    "author" : "",
    "keywords" : "",
    "file" : "newyear collage",
    "date" : "sRGB",
    "title" : "",
    "description" : "Normal",
    "generator" : "Export Kit v1.2.8"
  },
  "name" : "newyear collage",
  "layers" : [
    {
      "x" : 0,
      "height" : 612,
      "layers" : [
        {
          "x" : 0,
          "color" : "0xFFFFFF",
          "height" : 612,
          "y" : 0,
          "width" : 612,
          "shapeType" : "rectangle",
          "type" : "shape",
          "name" : "bg_rectangle"
        },
        {
          "x" : 160,
          "height" : 296,
          "layers" : [
            {
              "x" : 0,
              "height" : 296,
              "src" : "ax0HVTs.png",
              "y" : 0,
              "width" : 429,
              "type" : "image",
              "name" : "mask_image_1"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 188,
              "y" : 122,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse1"
            }
          ],
          "y" : 291,
          "width" : 429,
          "type" : "group",
          "name" : "user_image_1"
        },
        {
          "x" : 25,
          "height" : 324,
          "layers" : [
            {
              "x" : 0,
              "height" : 324,
              "src" : "hEM2kEP.png",
              "y" : 0,
              "width" : 471,
              "type" : "image",
              "name" : "mask_image_2"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 209,
              "y" : 136,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse_2"
            }
          ],
          "y" : 22,
          "width" : 471,
          "type" : "group",
          "name" : "user_image_2"
        }
      ],
      "y" : 0,
      "width" : 612,
      "type" : "group",
      "name" : "newyearcollage08"
    }
  ]
};

$(document).ready(function() {

    $('.container').click(function(e) {
        setTimeout(() => {
            $('#fileup').click();
        }, 20)
    });



    function getAllSrc(layers) {
        let arr = [];
        layers.forEach(layer => {
            if (layer.src) {
                arr.push({
                    src: layer.src,
                    x: layer.x,
                    y: layer.y
                });
            } else if (layer.layers) {
                let newArr = getAllSrc(layer.layers);
                if (newArr.length > 0) {
                    newArr.forEach(({
                        src,
                        x,
                        y
                    }) => {
                        arr.push({
                            src,
                            x: (layer.x + x),
                            y: (layer.y + y)
                        });
                    });
                }
            }
        });
        return arr;
    }



    function json(data)

    {
        var width = 0;
        var height = 0;
        let arr = getAllSrc(data.layers);

        let layer1 = data.layers;
        width = layer1[0].width;
        height = layer1[0].height;

        for (let {
                src,
                x,
                y
            } of arr) {
            $(".container").css('width', width + "px").css('height', height + "px").addClass('temp');

            var mask = $(".container").mask({
                maskImageUrl: 'https://i.imgur.com/' + src,
                onMaskImageCreate: function(img) {

                    img.css({
                        "position": "absolute",
                        "left": x + "px",
                        "top": y + "px"
                    });
                }
            });

            fileup.onchange = function() {
                mask.loadImage(URL.createObjectURL(fileup.files[0]));
            };
        }

    }
    json(jsonData);

}); // end of document ready

// jq plugin for mask
(function($) {
    var JQmasks = [];
    $.fn.mask = function(options) {
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            maskImageUrl: undefined,
            imageUrl: undefined,
            scale: 1,
            id: new Date().getUTCMilliseconds().toString(),
            x: 0, // image start position
            y: 0, // image start position
            onMaskImageCreate: function(div) {},
        }, options);


        var container = $(this);

        let prevX = 0,
            prevY = 0,
            draggable = false,
            img,
            canvas,
            context,
            image,
            timeout,
            initImage = false,
            startX = settings.x,
            startY = settings.y,
            div;

        container.mousePosition = function(event) {
            return {
                x: event.pageX || event.offsetX,
                y: event.pageY || event.offsetY
            };
        }

        container.selected = function(ev) {
            var pos = container.mousePosition(ev);
            var item = $(".masked-img canvas").filter(function() {
                var offset = $(this).offset()
                var x = pos.x - offset.left;
                var y = pos.y - offset.top;
                var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
                return d[0] > 0
            });

            JQmasks.forEach(function(el) {
                var id = item.length > 0 ? $(item).attr("id") : "";
                if (el.id == id)
                    el.item.enable();
                else el.item.disable();
            });
        };

        container.enable = function() {
            draggable = true;
            $(canvas).attr("active", "true");
            div.css({
                "z-index": 2
            });
        }

        container.disable = function() {
            draggable = false;
            $(canvas).attr("active", "false");
            div.css({
                "z-index": 1
            });
        }

        container.onDragStart = function(evt) {
            container.selected(evt);
            prevX = evt.clientX;
            prevY = evt.clientY;
            var img = new Image();
            evt.originalEvent.dataTransfer.setDragImage(img, 10, 10);
            evt.originalEvent.dataTransfer.setData('text/plain', 'anything');
        };

        container.getImagePosition = function() {
            return {
                x: settings.x,
                y: settings.y,
                scale: settings.scale
            };
        };

        container.onDragOver = function(evt) {
            if (draggable && $(canvas).attr("active") === "true") {
                var x = settings.x + evt.clientX - prevX;
                var y = settings.y + evt.clientY - prevY;
                if (x == settings.x && y == settings.y)
                    return; // position has not changed
                settings.x += evt.clientX - prevX;
                settings.y += evt.clientY - prevY;
                prevX = evt.clientX;
                prevY = evt.clientY;
                container.updateStyle();
            }
        };

        container.updateStyle = function() {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.beginPath();
                context.globalCompositeOperation = "source-over";
                image = new Image();
                image.setAttribute('crossOrigin', 'anonymous');
                image.src = settings.maskImageUrl;
                image.onload = function() {
                    canvas.width = image.width;
                    canvas.height = image.height;
                    context.drawImage(image, 0, 0, image.width, image.height);
                    div.css({
                        "width": image.width,
                        "height": image.height
                    });
                };

                img = new Image();
                img.src = settings.imageUrl;
                img.setAttribute('crossOrigin', 'anonymous');
                img.onload = function() {
                    settings.x = settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
                    settings.y = settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale)) / 2 : settings.y;
                    context.globalCompositeOperation = 'source-atop';
                    context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
                    initImage = false;
                };
            }, 0);
        };

        // change the draggable image
        container.loadImage = function(imageUrl) {
            if (img)
                img.remove();
            // reset the code.
            settings.y = startY;
            settings.x = startX;
            prevX = prevY = 0;
            settings.imageUrl = imageUrl;
            initImage = true;
            container.updateStyle();
        };

        // change the masked Image
        container.loadMaskImage = function(imageUrl, from) {
            if (div)
                div.remove();
            canvas = document.createElement("canvas");
            context = canvas.getContext('2d');
            canvas.setAttribute("draggable", "true");
            canvas.setAttribute("id", settings.id);
            settings.maskImageUrl = imageUrl;
            div = $("<div/>", {
                "class": "masked-img"
            }).append(canvas);

            // div.find("canvas").on('touchstart mousedown', function(event)
            div.find("canvas").on('dragstart', function(event) {

                if (event.handled === false) return;
                event.handled = true;
                container.onDragStart(event);
            });

            div.find("canvas").on('touchend mouseup', function(event) {
                if (event.handled === false) return;
                event.handled = true;
                container.selected(event);
            });

            div.find("canvas").bind("dragover", container.onDragOver);
            container.append(div);
            if (settings.onMaskImageCreate)
                settings.onMaskImageCreate(div);
            container.loadImage(settings.imageUrl);
        };
        container.loadMaskImage(settings.maskImageUrl);
        JQmasks.push({
            item: container,
            id: settings.id
        })
        return container;
    };
}(jQuery));
.temp {
background: black;
}

.container {
	background: black;
  position: relative;
 
}

.masked-img {
	overflow: hidden;
	margin-top: 30px;
	position: relative;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<input id="fileup" name="fileup" type="file" style="display:none" >

<div class="container">

</div>

video link

Edit

I tried as Static way : https://codepen.io/kidsdial/pen/xBLrjY , here for 2 images, i included 2 <input type="file" > , for 3 images i may need to add 3 input files , is it possible to fix the number of or is there any other dynamic hack, so that it will work for any number of mask images ?

回答1:

Here is a working solution.I just update the way how you are getting data . I saved all masks in an array . Than look for the array associated to the target click

    var mask;
var target;
let jsonData = {
  "path" : " UNEVENSHAPES\/",
  "info" : {
    "author" : "",
    "keywords" : "",
    "file" : "UNEVENSHAPES",
    "date" : "Uncalibrated",
    "title" : "",
    "description" : "Normal",
    "generator" : "Export Kit v1.2.8"
  },
  "name" : "UNEVENSHAPES",
  "layers" : [
    {
      "x" : 0,
      "height" : 612,
      "layers" : [
        {
          "x" : 0,
          "color" : "0xFFFFFF",
          "height" : 612,
          "y" : 0,
          "width" : 612,
          "shapeType" : "rectangle",
          "type" : "shape",
          "name" : "rectangle1"
        },
        {
          "x" : 20,
          "height" : 377,
          "layers" : [
            {
              "x" : 0,
              "height" : 377,
              "src" : "d15ad70281961be451263b418a07798b_frame0.png",
              "y" : 0,
              "width" : 218,
              "type" : "image",
              "name" : "mask_pic1"
            },
            {
              "radius" : "27 \/ 27",
              "color" : "0xACACAC",
              "x" : 52,
              "y" : 257,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse1"
            }
          ],
          "y" : 215,
          "width" : 218,
          "type" : "group",
          "name" : "user_pic1"
        },
        {
          "x" : 191,
          "height" : 120,
          "layers" : [
            {
              "x" : 0,
              "height" : 120,
              "src" : "2b5d28d0439bc3ce1d856e6c4e5607be_frame1.png",
              "y" : 0,
              "width" : 268,
              "type" : "image",
              "name" : "mask_pic2"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 115,
              "y" : 43,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse2"
            }
          ],
          "y" : 472,
          "width" : 268,
          "type" : "group",
          "name" : "user_pic2"
        },
        {
          "x" : 414,
          "height" : 302,
          "layers" : [
            {
              "x" : 0,
              "height" : 302,
              "src" : "52c93b6e0a0ffeeb670d0981f89f7fa5_frame2.png",
              "y" : 0,
              "width" : 178,
              "type" : "image",
              "name" : "mask_pic3"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 69,
              "y" : 182,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse3"
            }
          ],
          "y" : 290,
          "width" : 178,
          "type" : "group",
          "name" : "user_pic3"
        },
        {
          "x" : 374,
          "height" : 377,
          "layers" : [
            {
              "x" : 0,
              "height" : 377,
              "src" : "e92f354018aa8f7e6d279601a868a6b2_frame3.png",
              "y" : 0,
              "width" : 218,
              "type" : "image",
              "name" : "mask_pic4"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 129,
              "y" : 60,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse4"
            }
          ],
          "y" : 20,
          "width" : 218,
          "type" : "group",
          "name" : "user_pic4"
        },
        {
          "x" : 150,
          "height" : 120,
          "layers" : [
            {
              "x" : 0,
              "height" : 120,
              "src" : "010054750abb290d1bd7fcecfab60524_frame4.png",
              "y" : 0,
              "width" : 269,
              "type" : "image",
              "name" : "mask_pic5"
            },
            {
              "radius" : "27 \/ 27",
              "color" : "0xACACAC",
              "x" : 103,
              "y" : 15,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse5"
            }
          ],
          "y" : 20,
          "width" : 269,
          "type" : "group",
          "name" : "user_pic5"
        },
        {
          "x" : 20,
          "height" : 302,
          "layers" : [
            {
              "x" : 0,
              "height" : 302,
              "src" : "e7a5874b58376883adbeafea7ce5e572_frame5.png",
              "y" : 0,
              "width" : 176,
              "type" : "image",
              "name" : "mask_pic6"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 50,
              "y" : 68,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse6"
            }
          ],
          "y" : 20,
          "width" : 176,
          "type" : "group",
          "name" : "user_pic6"
        },
        {
          "x" : 222,
          "height" : 335,
          "layers" : [
            {
              "x" : 0,
              "height" : 335,
              "src" : "591743efa89d8ee936a6d660d52e82b2_frame6.png",
              "y" : 0,
              "width" : 265,
              "type" : "image",
              "name" : "mask_pic7"
            },
            {
              "radius" : "26 \/ 27",
              "color" : "0xACACAC",
              "x" : 126,
              "y" : 114,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse7"
            }
          ],
          "y" : 123,
          "width" : 265,
          "type" : "group",
          "name" : "user_pic7"
        },
        {
          "x" : 123,
          "height" : 334,
          "layers" : [
            {
              "x" : 0,
              "height" : 334,
              "src" : "22997a60cf61d7b59e92620b86ab86d6_frame7.png",
              "y" : 0,
              "width" : 264,
              "type" : "image",
              "name" : "mask_pic8"
            },
            {
              "radius" : "27 \/ 27",
              "color" : "0xACACAC",
              "x" : 73,
              "y" : 167,
              "height" : 53,
              "width" : 53,
              "shapeType" : "ellipse",
              "type" : "shape",
              "name" : "useradd_ellipse8"
            }
          ],
          "y" : 155,
          "width" : 264,
          "type" : "group",
          "name" : "user_pic8"
        }
      ],
      "y" : 0,
      "width" : 612,
      "type" : "group",
      "name" : "unevenshape04"
    }
  ]
};

$(document).ready(function() {


    $('.container').click(function(e) {
        console.log(e);
        var res =  e.target;
        target = res.id;
        console.log(target);
        setTimeout(() => {
            $('#fileup').click();
        }, 20)


    });


    function getAllSrc(layers){
  let arr = [];
  layers.forEach(layer => {
    if(layer.src){
      arr.push({src: layer.src, x: layer.x , y: layer.y});
    }
    else if(layer.layers){
      let newArr = getAllSrc(layer.layers);
      if(newArr.length > 0){
        newArr.forEach(({src, x,y}) =>{
          arr.push({src, x: (layer.x + x) , y: (layer.y + y)   });
        });
      }
    }
  });
  return arr;
}



    function json(data)

    {
        var width = 0;
        var height = 0;

    /*  
        let layer1 = data.layers;   
        width = layer1[0].width;
        height = layer1[0].height;
        let layer2 = layer1[0].layers;

    */  
        let arr = getAllSrc(data.layers);

        let layer1 = data.layers;
        width = layer1[0].width;
        height = layer1[0].height;
        let counter = 0;
        let table = [];
    //    for (i = 1; i < layer2.length; i++) {
          for (let {src, x,y} of arr) { 

          //  var x = layer2[i].x;
          //  var y = layer2[i].y;
          //  var src = layer2[i].layers[0].src;
            $(".container").css('width', width + "px").css('height', height + "px").addClass('temp');

            var mask = $(".container").mask({
                maskImageUrl: 'http://piccellsapp.com:1337/parse/files/PfAppId/' + src,
                onMaskImageCreate: function(img) {

                    img.css({
                        "position": "absolute",
                        "left": x + "px",
                        "top": y + "px"
                    });

                },
                id : counter
            });
            table.push(mask);
            fileup.onchange = function() {
                // get the element associated to it.
                let mask2 = table[target];
                mask2.loadImage(URL.createObjectURL(fileup.files[0]));
            };
            counter++;
        }

    }
    json(jsonData);

}); // end of document ready
// jq plugin for mask
(function($) {
    var JQmasks = [];
    $.fn.mask = function(options) {
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            maskImageUrl: undefined,
            imageUrl: undefined,
            scale: 1,
            id: new Date().getUTCMilliseconds().toString(),
            x: 0, // image start position
            y: 0, // image start position
            onMaskImageCreate: function(div) {},
        }, options);


        var container = $(this);

        let prevX = 0,
            prevY = 0,
            draggable = false,
            img,
            canvas,
            context,
            image,
            timeout,
            initImage = false,
            startX = settings.x,
            startY = settings.y,
            div;

        container.mousePosition = function(event) {
            return {
                x: event.pageX || event.offsetX,
                y: event.pageY || event.offsetY
            };
        }

        container.selected = function(ev) {
            var pos = container.mousePosition(ev);
            var item = $(".masked-img canvas").filter(function() {
                var offset = $(this).offset()
                var x = pos.x - offset.left;
                var y = pos.y - offset.top;
                var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
                return d[0] > 0
            });

            JQmasks.forEach(function(el) {
                var id = item.length > 0 ? $(item).attr("id") : "";
                if (el.id == id)
                    el.item.enable();
                else el.item.disable();
            });
        };

        container.enable = function() {
            draggable = true;
            $(canvas).attr("active", "true");
            div.css({
                "z-index": 2
            });
        }

        container.disable = function() {
            draggable = false;
            $(canvas).attr("active", "false");
            div.css({
                "z-index": 1
            });
        }

        container.onDragStart = function(evt) {
            container.selected(evt);
            prevX = evt.clientX;
            prevY = evt.clientY;
            var img = new Image();
        evt.originalEvent.dataTransfer.setDragImage(img, 10, 10);
        evt.originalEvent.dataTransfer.setData('text/plain', 'anything');           
        };

        container.getImagePosition = function() {
            return {
                x: settings.x,
                y: settings.y,
                scale: settings.scale
            };
        };

        container.onDragOver = function(evt) {
            if (draggable && $(canvas).attr("active") === "true") {
                var x = settings.x + evt.clientX - prevX;
                var y = settings.y + evt.clientY - prevY;
                if (x == settings.x && y == settings.y)
                    return; // position has not changed
                settings.x += evt.clientX - prevX;
                settings.y += evt.clientY - prevY;
                prevX = evt.clientX;
                prevY = evt.clientY;
                container.updateStyle();
            }
        };

        container.updateStyle = function() {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.beginPath();
                context.globalCompositeOperation = "source-over";
                image = new Image();
                image.setAttribute('crossOrigin', 'anonymous');
                image.src = settings.maskImageUrl;
                image.onload = function() {
                    canvas.width = image.width;
                    canvas.height = image.height;
                    context.drawImage(image, 0, 0, image.width, image.height);
                    div.css({
                        "width": image.width,
                        "height": image.height
                    });                 
                };

                img = new Image();
                img.src = settings.imageUrl;
                img.setAttribute('crossOrigin', 'anonymous');
                img.onload = function() {
                    settings.x = settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
                    settings.y = settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale)) / 2 : settings.y;
                    context.globalCompositeOperation = 'source-atop';
                    context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
                    initImage = false;
                };
            }, 0);
        };

        // change the draggable image
        container.loadImage = function(imageUrl) {
        console.log("load");
            if (img)
                img.remove();
            // reset the code.
            settings.y = startY;
            settings.x = startX;
            prevX = prevY = 0;
            settings.imageUrl = imageUrl;
            initImage = true;
            container.updateStyle();
        };

        // change the masked Image
        container.loadMaskImage = function(imageUrl, from) {
            if (div)
                div.remove();
            canvas = document.createElement("canvas");
            context = canvas.getContext('2d');
            canvas.setAttribute("draggable", "true");
            canvas.setAttribute("id", settings.id);
            settings.maskImageUrl = imageUrl;
            div = $("<div/>", {
                "class": "masked-img"
            }).append(canvas);

            // div.find("canvas").on('touchstart mousedown', function(event)
            div.find("canvas").on('dragstart', function(event) {

                if (event.handled === false) return;
                event.handled = true;
                container.onDragStart(event);
            });

            div.find("canvas").on('touchend mouseup', function(event) {
                if (event.handled === false) return;
                event.handled = true;
                container.selected(event);
            });

            div.find("canvas").bind("dragover", container.onDragOver);
            container.append(div);
            if (settings.onMaskImageCreate)
                settings.onMaskImageCreate(div);
            container.loadImage(settings.imageUrl);
        };
        container.loadMaskImage(settings.maskImageUrl);
        JQmasks.push({
            item: container,
            id: settings.id
        })
        return container;
    };
}(jQuery));


回答2:

Since you're using canvas elements for the actual drawings, we can take advantage of that:

$('.container').click(function(e) {
  var elements = document.elementsFromPoint(e.clientX, e.clientY);
  elements.some(element => {
    if(!element.getContext) return false;
    var rect = element.getBoundingClientRect();
    var x = e.pageX - rect.left;
    var y = e.pageY - rect.top;
    var pixel = element.getContext('2d').getImageData(x,y,1,1).data;
    if(pixel[3] === 255) {
      setTimeout(() => {
          $('#fileup').click();
      }, 20);
      return true;
    }
    return false;
  });
});

clientX and clientY are the coordinates of the click relative to the client area (the area of the page currently visible in the browser). Using these with document.elementsFromPoint() gives us all the elements that were under the click location.

Then we scan through all the found elements, checking if they have the property getContext. .some() lets us iterate through the array of elements while also letting us terminate early if we choose. We test for getContext to see if it's a canvas element and, if it's not, we can skip it.

If it is a canvas, we can move on to the next step. getContext('2d') grabs the canvas' drawing context from which we can pull raw pixel data via getImageData().

pageX and pageY from the event are the click coordinates relative to the whole page. getBoundingClientRect() gets us the element's location relative to the page. Combining those gives us the coordinate of the click relative to the element. We use that in getImageData() to grab the canvas pixel data at the click location in that canvas.

Pixel data is interleaved red, blue, green, and alpha (opacity) values, ranging from 0 to 255 for each. Since we grabbed a single pixel, it will have 4 values, the last one being alpha. We can then use that to determine whether or not we trigger the file dialog.

If we happen to find an opaque pixel at the click location in a canvas, we can trigger the file dialog and then skip the rest of the elements by returning true from the .some() callback.