1

I have two div of same dimension which overlap each other using z-index. Ist div contain image and 2nd div contain a canvas

I am trying to draw image on canvas same place as Ist div. I am using hammerjs library to zoomin/out , reposition and rotate image. I found these code somewhere else

function getMeta(url){   

     img = new Image();
    var remoteImage = {}
    img.src = url;
    remoteImage.width = img.naturalWidth
    remoteImage.height = img.naturalHeight
    remoteImage.src = url;
    return remoteImage
}

var urlImage = getMeta('https://www.penghu-nsa.gov.tw/FileDownload/Album/Big/20161012162551758864338.jpg')

var text = document.querySelector("#text");
var oImg=document.querySelector("#img_scan");

oImg.style['transition-duration'] = '100ms';
var timeInMs = 0;
var preAngle = 0;
var rotateAngle = 0;
var preRotation = 0;


var originalSize = {
    width : oImg.offsetWidth,
    height : oImg.offsetHeight,
}


var current = {
    x : 0,
    y : 0,
    z : 1,
    angle : 0,
    width: originalSize.width,
    height: originalSize.height,
}

var last = {
    x : 0,
    y : 0,
    z : 1,
}

var oImgRec = oImg.getBoundingClientRect();

var cx = oImgRec.left + oImgRec.width * 0.5;

var cy = oImgRec.top + oImgRec.height * 0.5;

var imageCenter = {
    x:cx,
    y:cy
}

var pinchImageCenter = {}

var deltaIssue = { x: 0, y: 0 };

var pinchStart = { x: undefined, y: undefined, isPanend:false}

var panendDeltaFix = {x:0,y:0,isPanend:false}

var pinchZoomOrigin = undefined;

var lastEvent = ''

var hammer = new Hammer(oImg);

hammer.get('pinch').set({enable: true});

hammer.get('pan').set({direction: Hammer.DIRECTION_ALL}).recognizeWith(hammer.get('pinch'));

hammer.on("pinchstart", function(e) {

    last.x = current.x;
    last.y = current.y;
    pinchStart.x = e.center.x;
    pinchStart.y = e.center.y;
    pinchImageCenter = {
        x: imageCenter.x + last.x,
        y: imageCenter.y + last.y
    }

    
    lastEvent = 'pinchstart';

});

hammer.on("pinchmove", function(e) {

    if(preAngle == 0){
        preAngle = Math.round(e.rotation);
        preRotation = Math.round(e.rotation);
    }else{
        if(Math.abs(Math.round(e.rotation)-preRotation)>=300){

            if(e.rotation > 0){
                preAngle+=360;
            }else if(e.rotation < 0){
                preAngle-=360;

            }

        }

        current.angle = rotateAngle + (Math.round(e.rotation)-preAngle);
        preRotation = Math.round(e.rotation);

    }


    var newScale = (last.z * e.scale) >= 0.1 ? (last.z * e.scale) : 0.1;

    var d = scaleCal(e.center, pinchImageCenter, last.z, newScale)

    current.x = d.x + last.x;

    current.y = d.y + last.y;

    current.z = d.z + last.z;

    update();

    lastEvent = 'pinchmove';
});

hammer.on("pinchend", function(e) {
    last.x = current.x;
    last.y = current.y;
    last.z = current.z;
    rotateAngle = current.angle;
    preAngle = 0;
    lastEvent = 'pinchend';

});

hammer.on("panmove", function(e) {
    var panDelta = {
        x:e.deltaX,
        y:e.deltaY
    }


    if (lastEvent !== 'panmove') {

        deltaIssue = {
            x: panDelta.x,
            y: panDelta.y
        }
    }

    current.x = (last.x+panDelta.x-deltaIssue.x);

    current.y = (last.y+panDelta.y-deltaIssue.y);

    lastEvent = 'panmove'
    update();
});

hammer.on("panend", function(e) {
    last.x = current.x;
    last.y = current.y;
    lastEvent = 'panend';
});

hammer.on('tap', function(e) {

    if((Date.now()-timeInMs)<300){

        if(last.z > 1){
            last.z = 1;
            current.z = 1;
            update();
        }else if(last.z <= 1){
            last.z = 2;
            current.z = 2;
            update();
        }
    }

    timeInMs = Date.now();
    lastEvent = 'tap';

});

function scaleCal(eCenter, originCenter, currentScale, newScale) {

    var zoomDistance = newScale - currentScale;

    var x = (originCenter.x - eCenter.x)*(zoomDistance)/currentScale;

    var y = (originCenter.y - eCenter.y)*(zoomDistance)/currentScale;

    var output = {
        x: x,
        y: y,
        z: zoomDistance
    }
    return output
}

function update() {

    current.height = originalSize.height * current.z;

    current.width = originalSize.width * current.z;

    if(current.z < 0.1){
        current.z = 0.1;
    }

    oImg.style.transform = " translate3d(" + current.x + "px, " + current.y + "px, 0)rotate("+current.angle+"deg)scale("+current.z+")"

}

So by above code user can zoomin/zoom out , rotate image . After they set image in their desired position i am putting that image on canvas so i can use dataurl method to save image later.

I tried below code to draw image on canvas same place as div ,same dimension and with same angle but sadly image is not getting exactly same positioned as div


var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

$("#btn").click(copyoncanvas);

function copyoncanvas(){

var bound=objimg.getBoundingClientRect();

var objimg=new Image();

objimg.src="https://www.penghu-nsa.gov.tw/FileDownload/Album/Big/20161012162551758864338.jpg";

ctx.drawImage(objimg,bound.left,bound.top,current.width,current.height);

drawRotated(current.angle,bound.left,bound.top);
}



function drawRotated(degrees,l,t){

const objimg=document.getElementById("img_scan");

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.save();

var x=canvas.width/2;

var y=canvas.height/2;

ctx.translate(x,y);

ctx.rotate(degrees * Math.PI/180);

ctx.drawImage(objimg,-l,-t,current.width,current.height);

ctx.restore();

}

I think my problem is with drawrotated function because it work fine without using it but i want to rotate image on canvas too

HTML

<div id="container">
        
<div class="box"><canvas id="canvas"></canvas></div>
      
<div id="imgcont">

<img src="https://www.penghu-nsa.gov.tw/FileDownload/Album/Big/20161012162551758864338.jpg" id="img_scan" class="img-custom-img2"/>

</div>
  
</div>

<button id="btn">Copy on canvas</button>

CSS

#container{
  position:relative;margin: 0px; 
padding:0px;background:#ff0;
top:0px; overflow:hidden;
width:300px;
border:1px solid #000; height:250}

    #img_scan,.box{
      width:100%; height:100%;      
        position: absolute;
        top: 0;
        left: 0; margin:0; padding:0px
    }

.box{z-index:98;height:250}

#canvas{width:100%;margin:0;
padding:0;
width:300;height:250}

#img_scan{width:300px;height:250px}

#imgcont{width:100%;height:250px;z-index:99}
5
  • Can you post the relevant HTML and CSS as well? Just the minimum needed to reproduce the issue. Commented Dec 31, 2022 at 18:50
  • @FiddlingAway I posted css and html see edited question . Please help if you can . thanks Commented Dec 31, 2022 at 19:04
  • If I understand your code correctly, you're combining the two Javascript blocks into one? Or are you just using the second one? Commented Dec 31, 2022 at 21:01
  • @FiddlingAway i am using both blocks . first block will allow users to set image in their desired position in div and second block of code will draw image on canvas. I will hide image later and save canvas later by data url method Commented Dec 31, 2022 at 23:56
  • Ah, I see now that it's a mobile thing. Unfortunately, I can't help with that - I don't have a smart phone with which I could test and debug, and messing about with emulated touch gestures for desktop and touchemulator.js produces nothing (I can't zoom, rotate, etc). Commented Jan 1, 2023 at 10:55

0

Browse other questions tagged or ask your own question.