eduardosuruagy Posted March 31, 2023 Share Posted March 31, 2023 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. Quote Link to comment Share on other sites More sharing options...
Sherzod Posted March 31, 2023 Share Posted March 31, 2023 Hello, 9 hours ago, eduardosuruagy said: I would like to select some parts of an image and be able to link them to my database. Just a question. Scaling is not used? Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted March 31, 2023 Author Share Posted March 31, 2023 5 hours ago, Sherzod said: Olá, Só uma pergunta. A escala não é usada? I didn't understand your question, but this is just to show the customer where the block is that he will buy the land. It doesn't have to be anything very precise. Quote Link to comment Share on other sites More sharing options...
Sherzod Posted March 31, 2023 Share Posted March 31, 2023 Your case is not clear to me. Maybe this post will help you a little. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 1, 2023 Author Share Posted April 1, 2023 18 hours ago, Sherzod said: Seu caso não está claro para mim. Talvez este post te ajude um pouco. I wanted to draw on an image, like this one in the picture above that I placed. Did you get it? In this example you sent, you can't draw on the image. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 4, 2023 Author Share Posted April 4, 2023 Can anyone help me in this case? Quote Link to comment Share on other sites More sharing options...
mikromundo Posted April 5, 2023 Share Posted April 5, 2023 Try HTML AREA: https://www.w3schools.com/tags/tag_area.asp 1 Quote Link to comment Share on other sites More sharing options...
Ron Posted April 6, 2023 Share Posted April 6, 2023 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. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 6, 2023 Author Share Posted April 6, 2023 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 Quote Link to comment Share on other sites More sharing options...
Sherzod Posted April 6, 2023 Share Posted April 6, 2023 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. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 6, 2023 Author Share Posted April 6, 2023 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. Quote Link to comment Share on other sites More sharing options...
Sherzod Posted April 6, 2023 Share Posted April 6, 2023 @eduardosuruagy OK. Then you need to once again provide a full description of what needs to be done. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 6, 2023 Author Share Posted April 6, 2023 34 minutes ago, Sherzod said: @eduardosuruagy OK. Em seguida, você precisa fornecer novamente uma descrição completa do que precisa ser feito. Can I send a message in private? Quote Link to comment Share on other sites More sharing options...
Sherzod Posted April 6, 2023 Share Posted April 6, 2023 Yes. Quote Link to comment Share on other sites More sharing options...
eduardosuruagy Posted April 11, 2023 Author Share Posted April 11, 2023 On 06/04/2023 at 20:35, Sherzod said: Sim. I sent you a private message Quote Link to comment Share on other sites More sharing options...
Sherzod Posted April 11, 2023 Share Posted April 11, 2023 19 minutes ago, eduardosuruagy said: I sent you a private message Yes, I saw. I'll try to reply soon. 1 Quote Link to comment Share on other sites More sharing options...
Ron Posted April 13, 2023 Share Posted April 13, 2023 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 1 Quote Link to comment Share on other sites More sharing options...
Ron Posted April 19, 2023 Share Posted April 19, 2023 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 1 Quote Link to comment Share on other sites More sharing options...
Ron Posted April 20, 2023 Share Posted April 20, 2023 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 Quote Link to comment Share on other sites More sharing options...
Ron Posted April 22, 2023 Share Posted April 22, 2023 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 2 Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 26, 2023 Share Posted July 26, 2023 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> 1 Quote Link to comment Share on other sites More sharing options...
Abaksoft Posted July 26, 2023 Share Posted July 26, 2023 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... Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 27, 2023 Share Posted July 27, 2023 8 hours ago, Abaksoft said: Thank you Irig, If you don't mind, can you send a sample, showing how to and where to put your script ? Thx again... Hi, yes is not a problem. I add my own procedure to save image to file. DrawInCanvas_Mousemove_ex.7z 1 2 Quote Link to comment Share on other sites More sharing options...
Abaksoft Posted July 27, 2023 Share Posted July 27, 2023 4 hours ago, irigsoft said: Hi, yes is not a problem. I add my own procedure to save image to file. DrawInCanvas_Mousemove_ex.7z 33.53 kB · 1 download Great, This give me ideas : Many fields applications in area calculation : Medical sector - Agricultural sector ... Many thx Irig. 1 Quote Link to comment Share on other sites More sharing options...
irigsoft Posted July 27, 2023 Share Posted July 27, 2023 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 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.