缩放一个图像会影响另一个图像

问题描述 投票:0回答:1

背景 :

我们在容器内显示两个面具....

用户点击两个面具并上传图片....

现在编辑文本显示在两个图像上....

一旦用户点击编辑文本,我们就会显示弹出框....

在那里我们可以看到Zoomin和Zoomout按钮正在显示....

重现问题的步骤:

1.点击Zoomin获得第1张图片5次....

2.现在点击Zoomin获取第二张图片....

第1张图像的缩放值现在等于第2张图像....

但是如果我们缩放一个图像,就不应该改变其他图像的缩放值....

这是16 seconds Video to show the issue

enter image description here

要求:

我可以通过为每个图像使用多个变量来静态地解决问题....

但我需要动态解决方案,因为我只使用一个变量为zoom_inzoom_out称为scale ....

这是Codepen

以下是片段:

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>
javascript jquery html5 zoom
1个回答
1
投票

问题是每次调用函数时都使用相同的var scale,并且每次scale都为其分配了前一个值。因此,您可以为每个元素使用不同比例的数组。

创建一个空数组:

var scales = [];

调用函数时,检查var(对于此元素)是否已存在:

if (scales[getId] === undefined) {
    scales[getId] = 1.25;
} else {
    scales[getId] += 0.25;  
}

if (scales[getId] === undefined) {
    scales[getId] = 0.75;
} else {
    scales[getId] -= 0.25;  
}

完整代码:

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;

var scales = [];

function zoom_in(data) {
  var getParent = data.parentElement.parentElement.parentElement;
  var getId = getParent.id.substring(getParent.id.length - 1);

  console.log(getId);

  if (scales[getId] === undefined) {
    scales[getId] = 1.25;
  } else {
    scales[getId] += 0.25;
  }

  $('.masked-img' + getId + ' #renderImage').css({
    transform: 'scale(' + scales[getId] + ')'
  });
}

function zoom_out(data) {
  var getParent = data.parentElement.parentElement.parentElement;
  var getId = getParent.id.substring(getParent.id.length - 1);
  console.log(getId);

  if (scales[getId] === undefined) {
    scales[getId] = 0.75;
  } else {
    scales[getId] -= 0.25;
  }

  $('.masked-img' + getId + ' #renderImage').css({
    transform: 'scale(' + scales[getId] + ')'
  });
}
.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;
}
<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>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
© www.soinside.com 2019 - 2024. All rights reserved.