Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/29/23 in all areas

  1. Hi, yes is not a problem. I add my own procedure to save image to file. DrawInCanvas_Mousemove_ex.7z
    1 point
  2. 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
    1 point
×
×
  • Create New...