Dragging one image makes other image to drag

前端 未结 5 417
谎友^
谎友^ 2021-01-21 10:12

When i drag the right part of uploaded image in mask1 , than uploaded image in mask2 is dragging, but that should\'t happen....

Here is video link

相关标签:
5条回答
  • 2021-01-21 10:40

    I think this is what you are looking for:

    Code Pen

    fileupa.onchange = e => {
     target_imga.src = URL.createObjectURL(fileupa.files[0]);   
    }
    
    fileupb.onchange = e => {
     target_imgb.src = URL.createObjectURL(fileupb.files[0]);   
    }
    
    let prevX = 0, prevY = 0,translateX = 0, translateY = 0, scale = 1, zoomFactor = 0.1;
    let current_elm = null;
    
    function onDragStart(evt) {
      if (current_elm != null) return;
      if (evt.dataTransfer && evt.dataTransfer.setDragImage) {
        evt.dataTransfer.setDragImage(evt.target.nextElementSibling, 0, 0);
        current_elm = evt.target;
      }
      prevX = evt.clientX;
      prevY = evt.clientY;  
    }
    
    function dragEnd(event) {
      current_elm=null;
    }
    
    function onDragOver(evt) {
      translateX += evt.clientX - prevX;
      translateY += evt.clientY - prevY;
      prevX = evt.clientX;
      prevY = evt.clientY;
      updateStyle() 
    }
    
    
    function updateStyle() 
    {
      let transform = "translate(" +translateX+ "px, "+ translateY + "px) scale("+scale+")"; 
      if(current_elm != null) current_elm.style.transform = transform;
    }
    .container {
      border: 1px solid #DDDDDD;
      width: 612px;
      height: 612px;
      position: relative;
      background: red;
    }
    
    .masked-imga {
      -webkit-mask-image: url(https://i.postimg.cc/y8T0y7zY/heart1.png);
      mask-image: url(https://i.postimg.cc/y8T0y7zY/heart1.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;
      width: 259px;
      height: 278px;
      position: absolute;
      top: 221px;
      left: 23px;
    }
    
    .masked-imgb {
      -webkit-mask-image: url(https://i.postimg.cc/xdTMsB0G/heart2.png);
      mask-image: url(https://i.postimg.cc/xdTMsB0G/heart2.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;
      width: 416px;
      height: 388px;
      position: absolute;
      top: 111px;
      left: 173px;
    }
    
    .minaimga {
      display: block;
      background-color: white;
      height: 278px;
    }
    
    .minaimgb {
      display: block;
      background-color: white;
      height: 388px;
    }
    <input type="file" id="fileupa" />
    <input type="file" id="fileupb" />
    
    <div class="container" ondragover="onDragOver(event)" >
    
      <div class="minaimg masked-imga">
        <div draggable="true" ondragstart="onDragStart(event)" ondragend="dragEnd(event)" id="uploadedImg">
          <div class="minaimga">
            <img id="target_imga" alt="">
            <div></div>
          </div>
        </div>
      </div>
    
      <div class="minaimg masked-imgb">
        <div draggable="true" ondragstart="onDragStart(event)" ondragend="dragEnd(event)" id="uploadedImg2">
          <div class="minaimgb">
            <img id="target_imgb" alt="">
            <div></div>
          </div>
        </div>
      </div>
    
    </div>


    Here I just define ondragover on the .container div which is the container of both images. and also inside of the onDragStart function, I save the current dragged element into current_elm so that on the another call of onDragStart no thing happen until current_elm become null(if it is not null then it means that there is already another element which is dragging so we should not consider new element to drag.) and also in the dragEnd callback function, we should set current_elm to null to enable new dragging process if it is needed(I hope you understand what I mean ;).) another advantage of current_elm is that there is no need to define two type of updateStyle function because you can update relevant element using current_elm.

    Let me know if more explanation is needed.

    0 讨论(0)
  • 2021-01-21 10:47

    Because the elements overlap each other I think the best way to fix is by setting the z-index. its not perfect, when switched between element you have first to drag the element that not overlapped.

    fileupa.onchange = e => {
      target_imga.src = URL.createObjectURL(fileupa.files[0]);
      // set z-index
      document.querySelector(".masked-imga").style = 'z-index: ' + zIndex++;
    }
    
    fileupb.onchange = e => {
      target_imgb.src = URL.createObjectURL(fileupb.files[0]);
      // set z-index
      document.querySelector(".masked-imgb").style = 'z-index: ' + zIndex++;
    }
    
    let prevX = 0,
      prevY = 0,
      translateX = 0,
      translateY = 0,
      scale = 1,
      zoomFactor = 0.1;
    
    let zIndex = 1;
    
    function onDragStart(evt) {
      // set z-index of the parent element
      evt.target.closest(".minaimg").style = 'z-index: ' + zIndex++;
    
      if (evt.target.nextElementSibling && // fix if .nextElementSibling is not element
        evt.dataTransfer && evt.dataTransfer.setDragImage) {
        evt.dataTransfer.setDragImage(evt.target.nextElementSibling, 0, 0);
      }
      prevX = evt.clientX;
      prevY = evt.clientY;
    }
    
    function onDragOver(evt) {
      translateX += evt.clientX - prevX;
      translateY += evt.clientY - prevY;
      prevX = evt.clientX;
      prevY = evt.clientY;
      updateStyle();
    }
    
    function updateStyle() {
      let transform = "translate(" + translateX + "px, " + translateY + "px) scale(" + scale + ")";
    
      if (document.querySelector('#uploadedImg img'))
        document.querySelector('#uploadedImg img').style.transform = transform;
    }
    
    function onDragOverSec(evt) {
      translateX += evt.clientX - prevX;
      translateY += evt.clientY - prevY;
      prevX = evt.clientX;
      prevY = evt.clientY;
      updateStyleSec();
    }
    
    function updateStyleSec() {
      let transform = "translate(" + translateX + "px, " + translateY + "px) scale(" + scale + ")";
    
      if (document.querySelector('#uploadedImg2 img'))
        document.querySelector('#uploadedImg2 img').style.transform = transform;
    }
    .container {
      border: 1px solid #DDDDDD;
      width: 612px;
      height: 612px;
      position: relative;
      background: red;
    }
    
    .masked-imga {
      -webkit-mask-image: url(https://i.postimg.cc/y8T0y7zY/heart1.png);
      mask-image: url(https://i.postimg.cc/y8T0y7zY/heart1.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;
      width: 259px;
      height: 278px;
      position: absolute;
      top: 221px;
      left: 23px;
    }
    
    .masked-imgb {
      -webkit-mask-image: url(https://i.postimg.cc/xdTMsB0G/heart2.png);
      mask-image: url(https://i.postimg.cc/xdTMsB0G/heart2.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;
      width: 416px;
      height: 388px;
      position: absolute;
      top: 111px;
      left: 173px;
    }
    
    .minaimga {
      display: block;
      background-color: white;
      height: 278px;
    }
    
    .minaimgb {
      display: block;
      background-color: white;
      height: 388px;
    }
    <input type="file" id="fileupa" />
    <input type="file" id="fileupb" />
    
    <div class="container">
      <div class="minaimg masked-imga" ondragover="onDragOver(event)">
        <div draggable="true" ondragstart="onDragStart(event)" id="uploadedImg">
          <div class="minaimga">
            <img id="target_imga" alt="">
            <div></div>
          </div>
        </div>
      </div>
    
      <div id="masked_imgb"  class="minaimg masked-imgb" ondragover="onDragOverSec(event)">
        <div draggable="true" ondragstart="onDragStart(event)" id="uploadedImg2">
          <div class="minaimgb">
            <img id="target_imgb" alt="">
            <div></div>
          </div>
        </div>
      </div>
    </div>

    demo image

    0 讨论(0)
  • 2021-01-21 10:53

    Here's my solution. You must keep track which element started the drag.

    HTML

    <input type="file" id="fileupa" />
    <input type="file" id="fileupb" />
    
    <div class="container">
    
    <div class="minaimg masked-imga"   ondragover="onDragOver(event)"ondragover="onDragOver(event)" >
      <div draggable="true" ondragstart="onDragStart(event)" id="uploadedImg">
        <div class="minaimga">
          <div id="dragBox1" class="dragFromHere" style="left:70px;top:120px;"></div>
          <img id="target_imga"  alt="">
    
          <div></div>
    
        </div>
      </div>
    </div>
    
    <div class="minaimg masked-imgb" ondragover="onDragOverSec(event)" ondragover="onDragOver(event)" ondragend="dragEnd()">
      <div draggable="true" ondragstart="onDragStart(event)" id="uploadedImg2">
        <div class="minaimgb">
          <div id="dragBox2" class="dragFromHere" style="left:160px;top:160px;"></div>
          <img id="target_imgb"  alt="">
    
          <div></div>
    
        </div>
      </div>
    </div>
    
    </div>
    

    JS

    var elemInDrag = null;
    var canInitdrag = false;
    
    fileupa.onchange = e => {
     target_imga.src = URL.createObjectURL(fileupa.files[0]);   
    }
    
    fileupb.onchange = e => {
     target_imgb.src = URL.createObjectURL(fileupb.files[0]);   
    }
    
    let prevX = 0, prevY = 0,translateX = 0, translateY = 0, scale = 1, zoomFactor = 0.1;
    
    function dragEnd() {
      elemInDrag = null; 
      canInitdrag = false;
    }
    
    function onDragStart(evt) {
      var x = evt.clientX, y = evt.clientY;
      var divRect1 = document.getElementById('dragBox1').getBoundingClientRect();
      var divRect2 = document.getElementById('dragBox2').getBoundingClientRect();
    
      if (event.clientX >= divRect1.left && event.clientX <= divRect1.right &&
          event.clientY >= divRect1.top && event.clientY <= divRect1.bottom) {
          // Mouse is inside element.
          canInitdrag = true;
        }
    
      if (event.clientX >= divRect2.left && event.clientX <= divRect2.right &&
          event.clientY >= divRect2.top && event.clientY <= divRect2.bottom) {
          // Mouse is inside element.
           canInitdrag = true;
        }
      if (canInitdrag) {
      if ((typeof evt.target.id!='undefined') || (evt.target.id==elemInDrag)){
        elemInDrag = evt.target.id;
      if (evt.dataTransfer && evt.dataTransfer.setDragImage) {
        evt.dataTransfer.setDragImage(evt.target.nextElementSibling, 0, 0);
      }
      prevX = evt.clientX;
      prevY = evt.clientY;
      }
      }
    }
    
    function onDragOver(evt) {
      if ((typeof evt.target.id!='undefined') && (evt.target.id==elemInDrag)){
      translateX += evt.clientX - prevX;
      translateY += evt.clientY - prevY;
      prevX = evt.clientX;
      prevY = evt.clientY;
      updateStyle();
      }
    }
    
    function updateStyle() 
    { 
    let transform = "translate(" +translateX+ "px, "+ translateY + "px) scale("+scale+")"; 
    
    if(document.querySelector('#uploadedImg img'))
    document.querySelector('#uploadedImg img').style.transform = transform;
    }
    
    function onDragOverSec(evt) {
      if ((typeof evt.target.id!='undefined') && (evt.target.id==elemInDrag)){
      translateX += evt.clientX - prevX;
      translateY += evt.clientY - prevY;
      prevX = evt.clientX;
      prevY = evt.clientY;
      updateStyleSec();
      }
    }
    
    function updateStyleSec() 
    { 
    let transform = "translate(" +translateX+ "px, "+ translateY + "px) scale("+scale+")"; 
    
    if(document.querySelector('#uploadedImg2 img'))
    document.querySelector('#uploadedImg2 img').style.transform = transform;
    }
    

    CSS

    .container {
        border: 1px solid #DDDDDD;
        width: 612px;
        height: 612px;
        position:relative;
        background:red;
    }
    
    .masked-imga
    
    {
    
      -webkit-mask-image: url(http://139.59.24.243/ecom1/site/test/images/heart1.png);
      mask-image: url(http://139.59.24.243/ecom1/site/test/images/heart1.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;  
    
      width: 259px;
      height: 278px;
      position: absolute;
        top: 221px;
        left: 23px;
    
    }
    
    .dragFromHere {
      border:thin;
      border-style:dotted;
      border-color:red;
      display:inline-block;
      width:80px;
      height:80px;
      position:absolute;
      z-index:99;
      pointer-events:none;
    }
    
    
    .masked-imgb 
    {
    
      -webkit-mask-image: url(http://139.59.24.243/ecom1/site/test/images/heart2.png);
      mask-image: url(http://139.59.24.243/ecom1/site/test/images/heart2.png);
      -webkit-mask-position: center center;
      mask-position: center center;
      -webkit-mask-repeat: no-repeat;
      mask-repeat: no-repeat;  
    
        width: 416px;
        height: 388px;
        position: absolute;
        top: 111px;
        left: 173px;
    }
    
    .minaimga
    {
      display: block;
      background-color: white;
      height: 278px;
    }
    
    .minaimgb 
    {
      display: block;
      background-color: white;
      height: 388px;
    }
    

    This way, drag only will work on the image you started the drag operation, and it will not involve the other element when you step over the area.

    Combine this with the CSS clip path to exclude the overlaping of the two images and you will have solved the issue of the inner corners.

    EDIT: Now the dragging can only be initiated from inside the red squares.Those are the "safe zones" where the elements do not overlap. The safe zones must be defined for each combination of masks images used.

    0 讨论(0)
  • 2021-01-21 11:01

    You can use CSS clip-path property to cut off HTML element corners as you want. It's easy to get right value via tool, please google 'css clip-path maker'.

    .masked-imga
        -webkit-clip-path: polygon(0 9%, 0 0, 35% 0%, 49% 0, 56% 27%, 73% 46%, 100% 61%, 100% 100%, 65% 100%, 0 100%, 0 100%, 0 30%);
        clip-path: polygon(0 9%, 0 0, 35% 0%, 49% 0, 56% 27%, 73% 46%, 100% 61%, 100% 100%, 65% 100%, 0 100%, 0 100%, 0 30%);
    
    .masked-imgb
        -webkit-clip-path: polygon(0 9%, 0 0, 35% 0%, 100% 0, 100% 0, 100% 0, 100% 61%, 100% 100%, 58% 100%, 40% 90%, 18% 63%, 0 39%);
        clip-path: polygon(0 9%, 0 0, 35% 0%, 100% 0, 100% 0, 100% 0, 100% 61%, 100% 100%, 58% 100%, 40% 90%, 18% 63%, 0 39%);
    
    0 讨论(0)
  • 2021-01-21 11:03

    Why are you defining the ondragover attribute twice? In any case, after defining onDragOverSec, you are later rewriting it as onDragOver, thereby triggering the event handler that you are using for the first element.

    <div class="minaimg masked-imgb"   ondragover="onDragOverSec(event)"ondragover="onDragOver(event)" >
    

    As a side note, this code could be rewritten to be be more DRY, by passing the differences between the two cases as variables to the same function, rather than two copies of each function

    0 讨论(0)
提交回复
热议问题