Search code examples
javascripthtmlcsssvgcss-mask

Dragging one image makes other image to drag


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

Also if i upload image only in mask 1 and try to drag, the image will disappear , but if i upload images in both masks, than image will not disappear

video link2

Codepen : https://codepen.io/kidsdial/pen/PVJQrz

<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">

      <img id="target_imga"  alt="">

      <div></div>

    </div>
  </div>
</div>

<div class="minaimg masked-imgb"   ondragover="onDragOverSec(event)"ondragover="onDragOver(event)" >
  <div draggable="true" ondragstart="onDragStart(event)" id="uploadedImg2">
    <div class="minaimgb">

      <img id="target_imgb"  alt="">

      <div></div>

    </div>
  </div>
</div>

</div>

<style>

.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;

}



.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;
}

</style>


<script>

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 onDragStart(evt) {
  if (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;
}




</script>

Edit

Is it because those two images overlapped horizontally & in vertically?

enter image description here

enter image description here

Edit 2

For some the question is still not clear, In below images , If user try to drag part B , along with part B , Part C & Part D also dragging, but that should't happen.....

enter image description here


Solution

  • 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.