用外部图像替换内部图像 [英] Replace the Inside image by Outside image

查看:181
本文介绍了用外部图像替换内部图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用户点击Mask&上传图片....

User click on Mask & upload the image....

显示相同图片两次,同时修改文字显示在图片上....

Its displaying same image two times, also Edit Text is displaying on image....

用户点击编辑文字后,我们会显示弹出框....

Once user click on Edit Text, we are displaying pop up box....

我们可以看到 Zoomin & 缩小按钮正在显示....

There we can see Zoomin & Zoomout buttons are displaying....

问题

点击这些按钮后,其缩放外部图片,而不是内部图片....

Once we click on those buttons, its zooming the outside image, but not the inside image....

要求

所以我想用外部图像替换Inside图像&删除内部图像,以便缩放功能适用于上传的图像....

So I want to replace the Inside image by outside image & Delete the Inside image , so that zoom feature will work for uploaded image....

codepen: https://codepen.io/kidsdial/pen/ OGGyYd

var target;
    const imageUrl = "https://i.imgur.com/RzEm1WK.png";

    let jsonData = {
        "layers": [{
            "x": 0,
            "height": 612,
            "layers": [{
                "x": 160,
                "src": "ax0HVTs.png",
                "y": 291,
                "height": 296,
                "width": 429,
                "name": "mask_1"
            },
                {
                    "x": 25,
                    "src": "hEM2kEP.png",
                    "height": 324,
                    "width": 471,
                    "y": 22,
                    "name": "mask_2"
                }
            ],
            "y": 0,
            "width": 612
        }]
    };

    const containerElement = $('#container');
    const fileUp = $('#fileup');

    $(function() {

        // Upload image onclick mask image

        containerElement.click(function(e) {
            var res = e.target;
            target = res.id;
            // console.log(target);
            if (e.target.getContext) {
                // click only inside Non Transparent part
                var pixel = e.target.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;
                if (pixel[3] === 255) {
                    setTimeout(() => {
                        $('#fileup').click();
                    }, 20);
                }
            }
        });

        // Fetch mask images from json file - IGNORE this code

        function getAllSrc(layers) {
            let arr = [];
            layers.forEach(layer => {
                if (layer.src) {
                    arr.push({
                        src: layer.src,
                        x: layer.x,
                        y: layer.y,
                        height: layer.height,
                        width: layer.width,
                        name: layer.name
                    });
                } else if (layer.layers) {
                    let newArr = getAllSrc(layer.layers);
                    if (newArr.length > 0) {
                        newArr.forEach(({
                                            src,
                                            x,
                                            y,
                                            height,
                                            width,
                                            name
                                        }) => {
                            arr.push({
                                src,
                                x: (layer.x + x),
                                y: (layer.y + y),
                                height,
                                width,
                                name: (name)
                            });
                        });
                    }
                }
            });
            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;
            let counter = 0;
            let table = [];

            // container dimensions
            containerElement.css('width', width + "px").css('height', height + "px").addClass('temp');
            //end

            for (let {
                src,
                x,
                y,
                name
            } of arr) {

                //Get Height and width of mask image [ edit button ]
                var ImagePosition = arr;
                //code end

                var mask = $(".container").mask({
                    imageUrl: imageUrl,

                    // Fetch Mask images
                    maskImageUrl: 'https://i.imgur.com/' + src,
                    // end

                    onMaskImageCreate: function(img) {
                        // Mask image positions
                        img.css({
                            "position": "absolute",
                            "left": x + "px",
                            "top": y + "px"
                        });
                        // end

                    },
                    id: counter
                });
                table.push(mask);
                fileup.onchange = function() {

                    let mask2 = table[target];
                    const imgView = URL.createObjectURL(fileup.files[0]);
                    const newImageLoadedId = mask2.loadImage(URL.createObjectURL(fileup.files[0]));
                    document.getElementById('fileup').value = "";

                    if (($(".masked-img" + newImageLoadedId + ' #renderImage').length) === 0) {
                        $('.masked-img' + newImageLoadedId).append("<img id='renderImage' style='width: 300px' src=" + imgView + ">");
                    } else {
                        $('#renderImage').attr('src', imgView);
                    }

                    //  Edit image - IGNORE this code

                    if ($(".masked-img" + newImageLoadedId).length === 1) {
                        $("<span class=\"pip pip" + newImageLoadedId + "\">" +
                            "<a onclick='document.getElementById(\"dark" + newImageLoadedId + "\").style.display=\"block\";'><span class=\"edit edit" + newImageLoadedId + "\" >Edit </span></a>" +
                            "</span>").insertAfter(".masked-img" + newImageLoadedId).css({
                            "left": ImagePosition[newImageLoadedId].x + (ImagePosition[newImageLoadedId].width / 2) + "px",
                            "top": ImagePosition[newImageLoadedId].y + (ImagePosition[newImageLoadedId].height / 2) + "px"
                        });;
                        $("<div id=\'dark" + newImageLoadedId + "\' class=\'dark_content\'>" +
                            $('#demoTemplate').html() +
                            "<a href=\"javascript:void(0)\" onclick=\"document.getElementById(\'dark" + newImageLoadedId + "\').style.display=\'none\'\">Close</a>" + "</div>").appendTo(".pip" + newImageLoadedId).css({
                            "left": $('.edit' + newImageLoadedId).width() + 2 + "px",
                            "top": "0px"
                        });
                    }
                    //  end
                };
                counter++;
            }
        }
        json(jsonData);
    }); // end of function

    // Image code

    (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.getImagePosition = function() {
                return {
                    x: settings.x,
                    y: settings.y,
                    scale: settings.scale
                };
            };

            container.updateStyle = function() {
                return new Promise((resolve, reject) => {
                    context.beginPath();
                    context.globalCompositeOperation = "source-over";
                    image = new Image();
                    image.setAttribute('crossOrigin', 'anonymous');
                    image.src = settings.maskImageUrl;
                    // console.log(image.src);
                    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
                        });
                        resolve();
                    };
                });
            };

            function renderInnerImage() {
                // img = $('#renderImage'); // new Image()
                img = new Image();
                img.setAttribute('crossOrigin', 'anonymous');
                img.src = settings.imageUrl;
                // console.log(image.src);
                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;
                };
            }

            // change the draggable image

            container.loadImage = function(imageUrl) {
                console.log("load");
                settings.y = startY;
                settings.x = startX;
                // console.log(settings.y);
                // console.log(settings.x);
                prevX = prevY = 0;
                settings.imageUrl = imageUrl;
                // console.log(settings.imageUrl);
                initImage = true;
                container.updateStyle().then(renderInnerImage);
                // sirpepole  Add this
                return settings.id;
            };

            container.loadMaskImage = function(imageUrl, from) {
                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
            });
            // Edit image
            div.addClass('masked-img' + settings.id);
            // end
            return container;
        };
    }(jQuery));

    // zoom

    var angle = 0;
    var scale = 1;

    function zoom_in(data) {
        var getParent = data.parentElement.parentElement.parentElement;
        var getId = getParent.id.substring(getParent.id.length - 1);
        console.log(getId);
        scale += .25;
        $('.masked-img' + getId + ' #renderImage').css({
            transform: 'scale('+ scale +')'
        });
    }

    function zoom_out(data) {
        var getParent = data.parentElement.parentElement.parentElement;
        var getId = getParent.id.substring(getParent.id.length - 1);
        console.log(getId);
        scale -= .25;
        $('.masked-img' + getId + ' #renderImage').css({
            transform: 'scale('+ scale +')'
        });
    }

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

    .container img {
        position: absolute;
        top: 0;
        bottom: 250px;
        left: 0;
        right: 0;
        margin: auto;
        z-index: 999;
    }

    .masked-img {
        overflow: hidden;
        position: relative;
    }

    .pip {
        display: inline-block;
        margin: 0;
        position: absolute;
    }

    .edit {
        display: block;
        background: #444;
        border: 1px solid black;
        color: white;
        text-align: center;
        cursor: pointer;
        position: absolute;
        z-index: 3;
    }

    .edit:hover {
        background: white;
        color: black;
        position: absolute;
        z-index: 3;
    }

    .dark_content {
        display: none;
        position: relative;
        top: 25%;
        left: 25%;
        width: 250px;
        height: 250px;
        padding: 16px;
        border: 16px solid orange;
        background-color: white;
        z-index: 1002;
        overflow: auto;
    }

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>

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

<div id="container"class="container">
</div>

<template id='demoTemplate'>
   <span>
      <div class="btn-group">
         <button type="button" class="js-zoom-in" onclick="zoom_in(this)">Zoom In</button>
         <button type="button" class="js-zoom-out" onclick="zoom_out(this)">Zoom Out</button>
      </div>
      <img id="image" src ="" style ="display:none">
   </span>
</template>

推荐答案

你可以用CSS替换你的整个画布代码,这样你就可以使用 transform:scale(2) with mask in mask:

You can replace your whole canvas code with CSS, so you will be able to use transform: scale(2) with image inside mask:

var img = document.querySelector('img');
var zoom = 1;
document.querySelector('#zoom_in').addEventListener('click', function(e) {
  zoom += 0.2;
  img.style.transform = 'scale(' + zoom +')';
});
document.querySelector('#zoom_out').addEventListener('click', function(e) {
  zoom -= 0.2;
  img.style.transform = 'scale(' + zoom +')';
});

.clip {
  -webkit-mask-image: url(https://i.imgur.com/ax0HVTs.png);
  -webkit-mask-repeat: no-repeat;
  mask-image: url(https://i.imgur.com/ax0HVTs.png);
  mask-repeat: no-repeat;
  mask: url(https://i.imgur.com/ax0HVTs.png);
}

<div class="clip">
   <img src="http://placekitten.com/500/300"/>
</div>
<button id="zoom_in">+</button>
<button id="zoom_out">-</button>

仅在Chrome中测试,如果你想要更多的浏览器支持,你可能需要调查什么是前缀以及跨浏览器代码的样子(如果你能找到它,你可以询问有关跨浏览器CSS掩码的问题,那么它已经过时了跨浏览器剪贴蒙版旧,没有好的答案。)

Tested only in Chrome, if you want more browsers support you would probably need to investigate what are prefixes and how Cross-Browser code look like (if you can find it you can ask question about "cross browser CSS mask" it one is outdated Cross-browser clipping masks old and there're no good answers).

本文显示有关剪辑路径和掩码的更多信息
https: //css-tricks.com/clipping-masking-css/

This article show more info about clip-path and mask https://css-tricks.com/clipping-masking-css/

此解决方案不适用于所有浏览器(此处为support https://caniuse.com/#feat=css-masks )但它可能是一些用途。

This solution will not work in every browser (here is support https://caniuse.com/#feat=css-masks) but it may be of some use.

如果你想用帆布制作它更复杂,我不认为这是正确的问题,你可以雇用某人更新掩码插件,为你添加缩放支持(因为它需要在缩放插件中完成,可能像画布上的缩放图像然后应用掩码,抱歉没有检查掩码插件是如何工作的。)

If you would like to make it with canvas it more complex and I don't think this is the right place to ask, you can probably hire someone to update the mask plugin for you to add support for zoom (because it need to be done in zoom plugin, maybe something like scale image on canvas and then apply the mask, Sorry didn't check how the mask plugin exactly work).

编辑:这应该为目录中的文件创建css文件:

EDIT: this should create css file for files in directory:

const {promisify} = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
const statAsync = promisify(fs.stat);
const writeFileAsync = promisify(fs.writeFile);

readFileAsync('./masks').then(async (data) =>
    var css = [];
    for (let file of data) {
        const stat = await statAsync(file);
        if (stat.isFile()) {
            css.push(`.mask_${i} {
               -webkit-mask-image: url(${file});
               -webkit-mask-repeat: no-repeat;
               mask-image: url(${file});
               mask-repeat: no-repeat;
               mask: url(${file});
           }`);
         }
    }
    await writeFileAsync('masks.css', css.join('\n'));
    console.log(`css file written ${css.length} rules`);
});

这篇关于用外部图像替换内部图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆