Jump to content

working with images


eduardosuruagy

Recommended Posts

I would like to select some parts of an image and be able to link them to my database. Imagine a plan of a condominium, I want to mark the points of a block and link it to my record of blocks, when I open the image again it will already be selected, is there this possibility?

See that in the image I selected some courts and put letters just to show an example.

Sem título.jpg

Video.gif

Link to comment
Share on other sites

This can be done in Javascript, using the HTML Canvas object in an HTMLFrame,
catching mouse down events in the client and pushing the coordinates back to the server, saving the blocks.

For visual feedback points should be drawn at each click, with lines in between,
coloring the areas between the points, and for that to work it has to be done in JS.

Load the image, catch the mouse down coordinates and draw the lines, close the
area at 4 clicks and run the ajaxevent. Panning and scaling will complicate it a little.

Link to comment
Share on other sites

9 hours ago, Ron said:

Isso pode ser feito em Javascript, usando o objeto HTML Canvas em um HTMLFrame,
capturando eventos de mouse down no cliente e enviando as coordenadas de volta para o servidor, salvando os blocos.

Para feedback visual devem ser desenhados pontos a cada clique, com linhas entre eles,
colorindo as áreas entre os pontos, e para isso funcionar tem que ser feito em JS.

Carregue a imagem, pegue as coordenadas do mouse e desenhe as linhas, feche a
área com 4 cliques e execute o ajaxevent. A panorâmica e a escala irão complicar um pouco.

Thanks for the help, but I'm novice in JavaScript and HTML, if you can help me I appreciate it

Link to comment
Share on other sites

Hello,

2 hours ago, eduardosuruagy said:

Thanks for the help, but I'm novice in JavaScript and HTML, if you can help me I appreciate it

This can be done, as mentioned above, with the help of additional, ready-made JS solutions. But it will take some time and resources, and you may have to pay for extra work.

Link to comment
Share on other sites

2 hours ago, Sherzod said:

Olá,

Isso pode ser feito, conforme mencionado acima, com a ajuda de soluções JS adicionais e prontas. Mas levará algum tempo e recursos, e você pode ter que pagar por trabalho extra.

I'm willing to pay for the extra work, but first I'd need to know the cost.

Link to comment
Share on other sites

Attached is a test project, using JS to catch and serve the coordinates selected on an image.

This is the code for the HTMLFrame:

<canvas id="cnv">
<script type="text/javascript">

var canvas = $('#cnv')[0];
var ctx = canvas.getContext("2d");
var imgMap = new Image();
var mDown, started, mClosed = false;
var numPoints = 0;
var aCoords = [];
//imgMap.src = "files/city.jpg";  

function relMouseCoords(event){
    var totalOffsetX = 0;
    var totalOffsetY = 0;
    var canvasX = 0;
    var canvasY = 0;
    var currentElement = this;
    do{
        totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
        totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
    }
    while(currentElement = currentElement.offsetParent);
    canvasX = event.pageX - totalOffsetX;
    canvasY = event.pageY - totalOffsetY;
    return {x:canvasX, y:canvasY}
  }
  
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;

window.addEventListener('resize', updateView, true);
function updateView() {
  //canvas.width = MainForm.HTMLFrame.getWidth();
  //canvas.height = MainForm.HTMLFrame.getHeight(); 
  canvas.width = 600;
  canvas.height = 360;
  drawScreen();
}

function resetImg() {
  ctx.beginPath();
  started = false;
  mClosed = false;
  numPoints = 0;
  ctx.drawImage(imgMap, 0, 0, 600, 360); 
  ctx.closePath();
}

function loadImg() {
  imgMap.src = "files/city.jpg";
  resetImg();
}  

function drawScreen() {
  ctx.beginPath();
  ctx.drawImage(imgMap, 0, 0, 600, 360); 
  ctx.fillStyle ="#FF0000";
  ctx.lineWidth = 3;
  if(started) {
    ctx.moveTo(aCoords[0].x, aCoords[0].y);
    for(i=1;i<aCoords.length;i++)
      ctx.lineTo(aCoords[i].x, aCoords[i].y);
    if(mClosed){ctx.lineTo(aCoords[0].x, aCoords[0].y)};  
    ctx.stroke();
  }
  ctx.font = "16px Arial";
  ctx.fillText(numPoints, 10,15);
  ctx.closePath();
}

 $("#cnv").mousedown(function(event){
  	if(mDown)return;
	mDown = true;
   	coords = canvas.relMouseCoords(event);
	if(!started) {
	  aCoords = [];
	  aCoords[0] = coords;
	  started = true;
	  mClosed = false;
	  numPoints = 1;
	  ctx.strokeStyle ="#FF3333";
	} else 
	if (!mClosed) {
	  if ((Math.abs(coords.x-aCoords[0].x)<10) && (Math.abs(coords.y-aCoords[0].y)<10)) {
       //remove last point, as we close the curve
       numPoints--;
       aCoords.pop();
	   mClosed = true;
	   ctx.strokeStyle ="#333333";
       ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(aCoords) });
	  } else {
        //add another point
	    aCoords[numPoints] = coords;
	    numPoints++;
	  }
	  drawScreen();
	}
});
	
 $("#cnv").mouseup(function(event){
  mDown = false;
});
	
$("#cnv").mousemove(function(event){
  event.stopPropagation(); 
  if(mClosed)return;
  if(mDown)return;
  coords = canvas.relMouseCoords(event);	
  if(!mClosed) {
    //update last point as we move around
    aCoords[numPoints] = coords;
    drawScreen();
  }
});

updateView();

</script>

At the server side you just grab the coords:

procedure TMainForm.HTMLFrameAjaxEvent(Sender: TComponent; EventName: string;
  Params: TUniStrings);
begin
  if sameText(eventName, 'getCoords') then
    uniEdit1.text:=Params.Values['data'];
end;

 

Testprog.zip

test.png

  • Like 1
Link to comment
Share on other sites

Attached is another version, using p5.js, from p5js.org

p5() had to be initiated in on-demand global mode at the beginning, see https://github.com/processing/p5.js/wiki/p5.js-overview

The canvas is created within a div container, set up via a callback function with loadImage(), and the function draw() runs a continous loop.

<div id='cnvCont'></div>

<script type="text/javascript">

new p5();

let pStarted, pClosed = false;
let cArray = [];
let bg;
let imgLoaded = false;

class Coords {
  constructor(ix, iy) {
    this.x = ix;
    this.y = iy;
  }
}  

function setup() {
  loadImage('files/city.jpg', regImg);
}

function regImg(img) {
  bg = img;
  let cnv = createCanvas(bg.width,bg.height);
  cnv.parent('cnvCont');
  strokeWeight(2);
  imgLoaded = true;
}

function draw() {
  if (imgLoaded) background(bg);
  if (!pStarted) return;
  if (!pClosed)
    stroke(255, 0, 0);
  else
    stroke(0, 0, 255);
  let len = cArray.length;
  if (len>1) 
    for(i=0;i<len-1;i++)      
      line(cArray[i].x, cArray[i].y, cArray[i+1].x, cArray[i+1].y);
  if (!pClosed) 
    line(cArray[len-1].x, cArray[len-1].y, mouseX, mouseY);	
  else 
    line(cArray[len-1].x, cArray[len-1].y, cArray[0].x, cArray[0].y);
}

function mouseClicked() {
  if (!pClosed) cArray.push(new Coords(mouseX, mouseY));
  if (!pStarted) 
    pStarted = true;
  else 
  if ((!pClosed) && ((Math.abs(mouseX-cArray[0].x)<10) && (Math.abs(mouseY-cArray[0].y)<10))) {
    cArray.pop();
    pClosed = true;
    ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(cArray) });
  }
}

function resetCnv() {
  pStarted = false;
  pClosed = false;
  cArray = [];  
}	


</script>

 

Testprog.zip

  • Upvote 1
Link to comment
Share on other sites

Last update, moved some code into an object, so each polygon will do the hit testing itself.

 

<div id='cnvCont'></div>

<script type="text/javascript">

new p5();

let pStarted, pClosed = false;
let pArray = [];
let bg;
let imgLoaded = false;
let selP = -1;

class Coords {
  constructor(ix, iy) {
    this.x = ix;
    this.y = iy;
	this.selected = false;
  }
}  

class MPoly {
  constructor(x, y) {
    this.selected = false;
    this.closed = false;
    this.hover = false;
    this.vx = [];
    this.vx.push(new Coords(x,y));
    pStarted = true;
    pClosed = false;
  }
  
  addVx(x,y) {
    this.vx.push(new Coords(x,y));	
  }	 
  
  close(doPop) {
    if(doPop)this.vx.pop();
    this.closed = true;
    pClosed = true;
    pStarted = false;  
  }	  
  
  move(dx, dy) {
    for (let i=0;i<this.vx.length;i++) {
      this.vx[i].x += dx;
      this.vx[i].y += dy;
    }  
  }
  
  display() {
    let hit = collidePointPoly(mouseX, mouseY, this.vx);
    if(hit && this.closed) {
      cursor(MOVE); 
      this.hover = true;
    } else 
      this.hover = false;
    if ((mouseIsPressed === true) && hit && this.closed) 
      this.move(mouseX - pmouseX, mouseY - pmouseY);
    if(hit && this.closed) {
      stroke(0, 255, 0);  
    }  
    else if (!this.closed)
      stroke(255, 0, 0);
    else
      stroke(0, 0, 255);
    let len = this.vx.length;
    if (len>1) 
      for(let i=0;i<len-1;i++)      
        line(this.vx[i].x, this.vx[i].y, this.vx[i+1].x, this.vx[i+1].y);
    if (!this.closed) 
      line(this.vx[len-1].x, this.vx[len-1].y, mouseX, mouseY);	
    else 
      line(this.vx[len-1].x, this.vx[len-1].y, this.vx[0].x, this.vx[0].y);
  }
}

function setup() {
  loadImage('files/city.jpg', regImg);
}

function regImg(img) {
  bg = img;
  let cnv = createCanvas(bg.width,bg.height);
  cnv.parent('cnvCont');
  strokeWeight(2);
  imgLoaded = true;
}

function draw() {
  if (imgLoaded) background(bg);
  let len = pArray.length;
  if (len == 0) return;
  cursor(ARROW);
  for(let i=0;i<len;i++)  {
    pArray[i].display();
  } 
}

function mouseClicked() {
  let len = pArray.length;
  for(let i=0;i<len;i++)  
    if (pArray[i].hover) {
      selP = i;	
      return;
    } 
  if ((pStarted)&&(!pClosed)) 
    pArray[selP].addVx(mouseX, mouseY);
  if (!pStarted) {
    pArray.push(new MPoly(mouseX, mouseY));
    selP = pArray.length - 1;
  }	
  else 
  if ((!pClosed) && ((Math.abs(mouseX-pArray[selP].vx[0].x)<10) && (Math.abs(mouseY-pArray[selP].vx[0].y)<10))) {
    pArray[selP].close(true);
    ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(pArray[selP].vx) });
  }
}

function keyPressed() {
  let len = pArray.length;
  if (len == 0) return;
  len = pArray[selP].vx.length;
  if ((key = ESCAPE) && (len > 2)) {
    pArray[selP].close(false);
    ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(pArray[selP].vx) });
  }
}  

function resetCnv() {
  pStarted = false;
  pClosed = false;
  pArray = [];  
}	

</script>

 

 

Testprog.zip

Link to comment
Share on other sites

Last update, with one more class to internalize variables, for cleaner code.

It seems like p5 works pretty well with Unigui. Movable polygons with movable vertices.

Edit: Using literal object for polygons, for a bit more efficient code.

Edit 2: Added function for deleting selected polygon.

Edit 3: Added function for inserting and deleting vertices.

JS code:

<div id='cnvCont'></div>
<script type="text/javascript">

new p5();
let bgImg;
let imgLoaded = false;
const px = 8;
const minimumVx = 3;
const vxFillCol = 'white';
const selVxCol = 'red';
const vxCol = 'rgb(0,0,0)';
const hoverPolyCol = 'green';
const drawPolyCol = 'red';
const polyCol = 'blue';
const selPolyCol = 'black';
const polyStrokeW = 2;

let Vertex = function(ix, iy) {	  
  this.x = ix;
  this.y = iy;

  this.drawVx = function(selected) {
    if (selected) {
      stroke(selVxCol);
      strokeWeight(2);
    } else {
      stroke(vxCol);
      strokeWeight(1);
    }	
    fill(vxFillCol);
    rect(this.x-round(px/2), this.y-round(px/2), px);	  
  };
  
  this.move = function(dX, dY) {	  
    this.x += dX;
    this.y += dY;  
  };	
  
  this.hit = function(mX, mY) {
    return (collidePointRect(mX, mY, this.x-px, this.y-px, px*2, px*2));
  };  
};  

class Polygon {
  constructor(x, y) {
    this.isSelected = false;
    this.closed = false;
    this.hover = false;
    this.moveLock = false;
    this.vxhover = false;
    this.vxMoveLock = false;
    this.vxi = -1;
    this.vx = [];
    this.vx.push(new Vertex(x,y));
  }
  
  addVx(x,y) {
    this.vx.push(new Vertex(x,y));	
  }	 
  
  doClose() {
    this.closed = true;
    this.isSelected = true;
  }	  
  
  move(dX, dY) {
    this.vx.forEach( v => {
      v.x += dX;
      v.y += dY;
    }); 
  }
  
  drawPoly(len, mX, mY) {
    if (this.hover) {
      cursor(MOVE); 
      stroke(hoverPolyCol); 
    } else 
    if (!this.closed)
      stroke(drawPolyCol);	
    else  
      stroke(polyCol);
    if (this.isSelected) stroke(selPolyCol);
    strokeWeight(polyStrokeW);
    noFill();
    if (len>1) 
      this.vx.slice(0, len-1).forEach( (vx, i) => {
        line(vx.x, vx.y, this.vx[i+1].x, this.vx[i+1].y);	  
      });	
    let lastVx = this.vx[len-1], startVx = this.vx[0];	  
    (!this.closed) ?
      line(lastVx.x, lastVx.y, mX, mY) :
      line(lastVx.x, lastVx.y, startVx.x, startVx.y);  
  }	
  
  displayVx(len, mX, mY) {
    this.vxhover = false;	    
    this.vx.forEach((v, i) => {
      v.drawVx(i===this.vxi);
      if (!this.vxMoveLock)
        if (v.hit(mX, mY)) {	  
          this.vxi = i;
          this.vxhover = true;		
        }	
      });
  }	  
  
  moveVx(dX, dY) {
    if (!this.moveLock && (this.vxhover || this.vxMoveLock)) {
      cursor(HAND); 
      if (mouseIsPressed) {
        this.vxMoveLock = true;
        this.vx[this.vxi].move(dX, dY);
      } else 
        this.vxMoveLock = false;
    } else this.vxhover = false;	  
  }	
  
  movePoly(dX, dY) {  
    if (!this.vxMoveLock && (!this.vxhover) && (this.hover || this.moveLock)) {  
      if (mouseIsPressed) {
        this.moveLock = true;	
        this.move(dX, dY);
        this.vxi = -1;
        this.vxhover = false;
      } else 
        this.moveLock = false;	  
    }  
  }	 
  
  delVx() {
    if (this.vxi < 0) return;  
    this.vx.splice(this.vxi, 1);
    this.vxMoveLock = false;
  }  
  
  insertVx() {
    if (this.vxi < 0) return;  
    let vxn = this.vxi - 1;
    if (vxn < 0) vxn = this.vx.length - 1;	
    let ix = (round(this.vx[this.vxi].x + this.vx[vxn].x)/2);
    let iy = (round(this.vx[this.vxi].y + this.vx[vxn].y)/2);
    this.vx.splice(this.vxi, -1, new Vertex(ix,iy));  
  }	
  
  duplicate() {
    if (this.vxi < 0) return;
    let vi = this.vx[this.vxi];
    return this.vx.some( (vx, i) => {
      return (((abs(vx.x-vi.x))<10) && ((abs(vx.y-vi.y))<10) && (i!=this.vxi)); 
    });	
  }	  
  
  display(mX, mY, dX, dY) {
    this.hover = (collidePointPoly(mX, mY, this.vx) && (!polys.vxMoveLocked()) 
      && (!(polys.moveLocked() && !this.isSelected)) && (!polys.drawing()));  
    let len = this.vx.length;
    this.drawPoly(len, mX, mY);
    if (this.isSelected) {
      this.displayVx(len, mX, mY);
      this.movePoly(dX, dY);
      this.moveVx(dX, dY);
    }
  }
}

let polys = {
  started: false,
  closed: false,
  pArray: [],
  selIndex: -1,
  count: 0,
  
  ready: function() {
    return (!this.started);
  },
  
  drawing: function() {
    return ((this.started)&&(!this.closed));
  },  
  
  moveLocked: function() {
    return this.pArray.some( poly => {
      return (poly.moveLock===true);	
    });	
  },	
  
  vxMoveLocked: function() {
    return this.pArray.some( poly => {
      return (poly.vxMoveLock===true);	
	});	
  },
  
  clear: function() {
    this.started = false;
    this.closed = false;
    this.pArray = [];   
    this.selIndex = -1;
    this.count = 0;
  },	
  
  newPoly: function(mX, mY) {
    if ((mX<0) || (mY<0) || (mX>bgImg.width) || (mY>bgImg.height)) return;
    this.clearSelected();
    this.pArray.push(new Polygon(mX, mY)); 
    this.started = true;
    this.closed = false;
    this.count = this.pArray.length;
    this.selIndex = this.count - 1;	
  },
  
  addVx: function(mX, mY) {
    if ((mX<0) || (mY<0) || (mX>bgImg.width) || (mY>bgImg.height)) return;
    if (this.pArray.every( (poly, i) => {
      return (poly.hover && (i!=this.selIndex));
    })) return;	
    this.selected().addVx(mX,mY);	
  },
  
  canClose: function(mX, mY) {
    return ((Math.abs(mX-this.getX())<10) && (Math.abs(mY-this.getY())<10)); 
  },
  
  doClose: function() {
    this.selected().doClose();  
    this.started = false;  
    this.closed = true;
  },
  
  delSelected: function() {
    if (this.selIndex < 0) return false;
    if (this.started) {
      this.pArray.pop();
      this.started = false;
    } else
      this.pArray.splice(this.selIndex, 1); 
    this.count = this.pArray.length;	
    this.selIndex = -1;
    return true;
  },	
  
  clearSelected: function() {
    this.pArray.forEach( poly => {
      poly.isSelected = false;
    }); 
    this.selIndex = -1;
  },
  
  doSelect: function() {
    return this.pArray.some( (poly, i) => {
      if (poly.hover || poly.vxhover) {
        this.clearSelected();
    	this.selIndex = i;
    	poly.isSelected = true;  
    	return true;
      }	
    });	
  },
  
  selected: function() {
    if (polys.selIndex>-1) 
      return this.pArray[this.selIndex]; 
  },
  
  isSelected: function() {
    return (polys.selIndex>-1); 
  },  
  
  isEmpty: function() {
    return (this.count===0);  
  },
  
  isClosed: function() {
    return (this.closed);  
  },
  
  vxLen: function() {
    return this.selected().vx.length;  
  },
  
  getVx: function() {
    return this.selected().vx;  
  },
  
  getX: function() {
    return this.selected().vx[0].x; 
  },
  
  getY: function() {
    return this.selected().vx[0].y; 
  },
  
  dupCheck: function() {
    if ((this.count>0) && (this.selIndex>-1))
      return this.selected().duplicate();  
  },
  
  delVxDup: function() {
    if ((this.vxLen() > minimumVx)  && (this.dupCheck()))
      this.selected().delVx();
  },
  
  delVx: function() {
    if (this.vxLen() > minimumVx)
      this.selected().delVx();
  },
  
  hover: function() {
    this.pArray.forEach( poly => {
      if (poly.hover) return true;
    });
  }, 
  
  insertVx: function() {
    this.selected().insertVx(); 
  },	  
  
  display: function(mX, mY, dX, dY) {
    if (this.isEmpty()) return;
    cursor(ARROW);
    this.pArray.forEach( poly => {
      poly.display(mX, mY, dX, dY);
    });   
  }
}  

function setup() {
  loadImage('files/city.jpg', regImg);
}

function regImg(img) {
  bgImg = img;
  let cnv = createCanvas(bgImg.width,bgImg.height);
  cnv.parent('cnvCont');
  imgLoaded = true;
}

function draw() {
  if (imgLoaded) background(bgImg);
  polys.display(mouseX, mouseY, mouseX-pmouseX, mouseY-pmouseY);
}

function pushData() {
  ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(polys.getVx()) });	
}	

function mousePressed() {	
  if (polys.doSelect()) 
    return
  else
  if (polys.ready()) 
    polys.newPoly(mouseX, mouseY);
  else 
  if (polys.drawing()) {
    if (polys.canClose(mouseX, mouseY)) {
      polys.doClose();
      pushData();
    } else polys.addVx(mouseX, mouseY); 
  }	  
}

function mouseReleased() {
  if (!polys.isClosed()) return;
  polys.delVxDup();
}

function doubleClicked() {
  if (polys.isEmpty()) return;
  if (polys.isSelected()) polys.insertVx();
}

function keyPressed() {
  if (polys.isEmpty()) return;
  if ((key = ESCAPE) && (polys.vxLen() > (minimumVx - 1))) {
    polys.doClose();
    pushData();
  } else
  if ((key = ESCAPE) && (polys.vxLen() <= (minimumVx - 1)) && polys.drawing()) 
    polys.delSelected();
}  

function delVertex() {
  if (polys.isEmpty()) return;
  if (!polys.isClosed()) return;
  polys.delVx();
}	

function insertVertex() {
  if (polys.isEmpty()) return;
  if (polys.isSelected()) polys.insertVx();
}

function delSelected() {
  if (polys.isEmpty()) {
    ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'no polygons to delete' });		
    return;
  }	  
  if (polys.delSelected())
    ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'polygon deleted ok' });		
  else ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'no polygon selected' });		
}	

function resetCnv() {
  polys.clear(); 
}	

</script>

 

 

 

 

 

 

 

 

 

 

 

Testprog.zip

  • Thanks 2
Link to comment
Share on other sites

  • 3 months later...

Hello, 

I will share my code for draw in canvas on mobile and desktop devices:

 

<div class="wrapper">
  <canvas id="myCanvas" width="840px" height="900px"></canvas>
</div>

<script type="text/javascript">

$(function() {
  var mousePressed = false;
  var lastX, lastY;
  var canvas = $('#myCanvas')[0];
  var ctx;
  ctx = $('#myCanvas').get(0).getContext("2d");

  var color = '#000000';

  function log(str) {
    $(".status").html("<div>" + str + "<div>");
  }

/*
  $('#skinModal').click(function() {
    $(".spectrum-input").change(function() {
      color = $(this).val();
    });
  })

  $("#skin-condition-save").click(function() {
    document.getElementById('right_side_face_canvas').value = document.getElementById('myCanvas').toDataURL('image/png');
    document.getElementById('left_side_face_canvas').value = document.getElementById('myCanvasTwo').toDataURL('image/png');
  });
*/

  function getCoords(evt) {
    var coords = {
      x: 0,
      y: 0
    };
    if (evt.type.indexOf("touch") != -1) {
      /*alert (evt.originalEvent.touches[0].pageX);*/
      coords.x = evt.originalEvent.touches[0].pageX;/*evt.changedTouches[0].pageX;  // not work on mobile*/
      coords.y = evt.originalEvent.touches[0].pageY;/*evt.changedTouches[0].pageY;  // not work on mobile */
    } else {
      coords.x = evt.pageX;
      coords.y = evt.pageY;
    }

    return coords;
  }


  $('.wrapper').on("mousedown touchstart vmousedown vclick", "canvas", function(e) {
    e.preventDefault();
    log(e.type);
    var second = $(e.target).attr("id") === "myCanvasTwo";
    mousePressed = true;
    var c = getCoords(e);
    Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, false, second);
  });


  $('.wrapper').on("mousemove touchmove vmousemove", "canvas", function(e) {
    e.preventDefault();
    log(e.type);
    var second = $(e.target).attr("id") === "myCanvasTwo";
    var c = getCoords(e);
    if (mousePressed) {
      Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, true, second);
    }
  });

  $('.wrapper').on("mouseup mouseleave touchstop vmouseup", "canvas", function(e) {
    log(e.type);
    mousePressed = false;
  });

  function Draw(x, y, isDown, isSecond) {
    if (isDown) {
        ctx.beginPath();
        ctx.strokeStyle = color;
        ctx.lineWidth = $('#selWidth').val();
        ctx.lineJoin = "round";
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(x, y);
        ctx.closePath();
        ctx.stroke();
    }
    lastX = x;
    lastY = y;
  }

  function clearArea() {
    // Use the identity matrix while clearing the canvas
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  }

});

</script>
 

 

  • Thanks 1
Link to comment
Share on other sites

7 hours ago, irigsoft said:

Hello, 

I will share my code for draw in canvas on mobile and desktop devices:

 

<div class="wrapper">
  <canvas id="myCanvas" width="840px" height="900px"></canvas>
</div>

<script type="text/javascript">

$(function() {
  var mousePressed = false;
  var lastX, lastY;
  var canvas = $('#myCanvas')[0];
  var ctx;
  ctx = $('#myCanvas').get(0).getContext("2d");

  var color = '#000000';

  function log(str) {
    $(".status").html("<div>" + str + "<div>");
  }

/*
  $('#skinModal').click(function() {
    $(".spectrum-input").change(function() {
      color = $(this).val();
    });
  })

  $("#skin-condition-save").click(function() {
    document.getElementById('right_side_face_canvas').value = document.getElementById('myCanvas').toDataURL('image/png');
    document.getElementById('left_side_face_canvas').value = document.getElementById('myCanvasTwo').toDataURL('image/png');
  });
*/

  function getCoords(evt) {
    var coords = {
      x: 0,
      y: 0
    };
    if (evt.type.indexOf("touch") != -1) {
      /*alert (evt.originalEvent.touches[0].pageX);*/
      coords.x = evt.originalEvent.touches[0].pageX;/*evt.changedTouches[0].pageX;  // not work on mobile*/
      coords.y = evt.originalEvent.touches[0].pageY;/*evt.changedTouches[0].pageY;  // not work on mobile */
    } else {
      coords.x = evt.pageX;
      coords.y = evt.pageY;
    }

    return coords;
  }


  $('.wrapper').on("mousedown touchstart vmousedown vclick", "canvas", function(e) {
    e.preventDefault();
    log(e.type);
    var second = $(e.target).attr("id") === "myCanvasTwo";
    mousePressed = true;
    var c = getCoords(e);
    Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, false, second);
  });


  $('.wrapper').on("mousemove touchmove vmousemove", "canvas", function(e) {
    e.preventDefault();
    log(e.type);
    var second = $(e.target).attr("id") === "myCanvasTwo";
    var c = getCoords(e);
    if (mousePressed) {
      Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, true, second);
    }
  });

  $('.wrapper').on("mouseup mouseleave touchstop vmouseup", "canvas", function(e) {
    log(e.type);
    mousePressed = false;
  });

  function Draw(x, y, isDown, isSecond) {
    if (isDown) {
        ctx.beginPath();
        ctx.strokeStyle = color;
        ctx.lineWidth = $('#selWidth').val();
        ctx.lineJoin = "round";
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(x, y);
        ctx.closePath();
        ctx.stroke();
    }
    lastX = x;
    lastY = y;
  }

  function clearArea() {
    // Use the identity matrix while clearing the canvas
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  }

});

</script>
 

 

Thank you Irig,

If you don't mind, can you send a sample, showing how to and where to put your script ?

Thx again...

Link to comment
Share on other sites

21 minutes ago, Abaksoft said:

Many fields applications in area calculation :  Medical sector - Agricultural sector  ...

I'm using it for my mobile/desktop app for computer service and/or auto service businesses to have customers hand sign some documents through the app

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...