1//СкÑÐ¸Ð¿Ñ ÑÑÑеÑÑвенно пеÑеÑабоÑан, но не идеален 23.11.2022 2//СкÑÐ¸Ð¿Ñ ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±Ð»Ð°ÑÑей 3 4class areaDraw { 5 constructor(image, settings) { 6 this.valueSet(settings.value); 7 8 this.image = image; 9 this.settings = settings; 10 11 this.container = document.createElement('div'); 12 this.container.style.display = 'inline-block'; 13 this.container.style.position = 'relative'; 14 this.container.style.padding = 0; 15 this.image.before(this.container); 16 this.container.append(this.image); 17 18 this.canvas = document.createElement('canvas'); 19 20 this.canvas.style.margin = '0'; 21 this.canvas.style.padding = '0'; 22 23 this.canvas.style.width = '100%'; 24 this.canvas.style.height = '100%'; 25 this.canvas.style.position = 'absolute'; 26 this.canvas.style.top = 0; 27 this.canvas.style.left = 0; 28 this.container.append(this.canvas); 29 30 this.canvasContext = this.canvas.getContext('2d'); 31 32 this.btnReset = document.createElement('a'); 33 this.btnReset.innerHTML+='<i class="far fa-trash"></i>'; 34 this.container.after(this.btnReset); 35 36 37 this.btnReset.addEventListener('click', (e) => this.reset(e)); 38 this.canvas.addEventListener('mousedown', (e) => this.mousedown(e)); 39 this.canvas.addEventListener('contextmenu', (e) => this.rightclick(e)); 40 this.canvas.addEventListener('mouseup', (e) => this.stopdrag(e)); 41 42 var context = this; 43 if(!context.image.complete){ 44 context.image.addEventListener('load',function(){ 45 context.canvas.setAttribute('width', context.image.naturalWidth); 46 context.canvas.setAttribute('height', context.image.naturalHeight); 47 context.draw(); 48 }); 49 } else { 50 context.canvas.setAttribute('width', context.image.naturalWidth); 51 context.canvas.setAttribute('height', context.image.naturalHeight); 52 context.draw(); 53 } 54 55 context.listenerMove=function(e){ 56 context.move(e); 57 } 58 context.listenerMoveAll=function(e){ 59 context.moveall(e); 60 } 61 62 } 63 64 valueSet(value){ 65 value = value.replace(/[^0-9\,]/ig, ''); 66 if (value.length) { 67 this.points = value.split(',').map(function (point) { 68 return parseInt(point, 10); 69 }); 70 } else { 71 this.points = []; 72 } 73 } 74 75 //вÑÑиÑление множиÑÐµÐ»Ñ 76 multiplierGet(){ 77 return this.image.naturalWidth / this.canvas.clientWidth; 78 } 79 80 reset() { 81 this.points = []; 82 this.draw(); 83 this.record(); 84 }; 85 86 move(e) { 87 let x,y; 88 let multiplier = this.multiplierGet(); 89 x = e.offsetX; 90 y = e.offsetY; 91 if (!x) { 92 x = (e.pageX - this.canvas.getBoundingClientRect().x); 93 y = (e.pageY - this.canvas.getBoundingClientRect().y); 94 } 95 x = x*multiplier; 96 y = y*multiplier; 97 98 this.points[this.activePoint] = Math.round(x); 99 this.points[this.activePoint + 1] = Math.round(y); 100 this.draw(); 101 }; 102 103 moveall(e) { 104 let x,y; 105 let multiplier = this.multiplierGet(); 106 x = e.offsetX; 107 y = e.offsetY; 108 if (!x) { 109 x = (e.pageX - this.canvas.getBoundingClientRect().x); 110 y = (e.pageY - this.canvas.getBoundingClientRect().y); 111 } 112 x = x*multiplier; 113 y = y*multiplier; 114 115 if (!this.startpoint) { 116 this.startpoint = {x: Math.round(x), y: Math.round(y)}; 117 } 118 var sdvpoint = {x: Math.round(x), y: Math.round(y)}; 119 for (var i = 0; i < this.points.length; i++) { 120 this.points[i] = (sdvpoint.x - this.startpoint.x) + this.points[i]; 121 this.points[++i] = (sdvpoint.y - this.startpoint.y) + this.points[i]; 122 } 123 this.startpoint = sdvpoint; 124 this.draw(); 125 }; 126 127 stopdrag() { 128 this.canvas.removeEventListener('mousemove', this.listenerMove,true); 129 this.canvas.removeEventListener('mousemove', this.listenerMoveAll,true); 130 //this.canvas.removeEventListener('mousemove', (e) => { this.move(e) },true); 131 //this.canvas.removeEventListener('mousemove', (e) => { this.moveall(e) },true); 132 //$(this.canvas).off('mousemove'); 133 this.record(); 134 this.activePoint = null; 135 }; 136 137 rightclick = function (e) { 138 e.preventDefault(); 139 let x,y,dis; 140 141 let multiplier = this.multiplierGet(); 142 x = e.offsetX; 143 y = e.offsetY; 144 if (!x) { 145 x = (e.pageX - this.canvas.getBoundingClientRect().x); 146 y = (e.pageY - this.canvas.getBoundingClientRect().y); 147 } 148 x = x*multiplier; 149 y = y*multiplier; 150 151 for (var i = 0; i < this.points.length; i += 2) { 152 dis = Math.sqrt(Math.pow(x - this.points[i], 2) + Math.pow(y - this.points[i + 1], 2)); 153 if (dis < 6) { 154 this.points.splice(i, 2); 155 this.draw(); 156 this.record(); 157 return false;
158 } 159 } 160 return false; 161 }; 162 163 mousedown(e) { 164 e.preventDefault(); 165 let x, y, dis, lineDis, insertAt = this.points.length; 166 if (e.which === 3) { 167 return false; 168 } 169 170 let multiplier = this.multiplierGet(); 171 x = e.offsetX; 172 y = e.offsetY; 173 if (!x) { 174 x = (e.pageX - this.canvas.getBoundingClientRect().x); 175 y = (e.pageY - this.canvas.getBoundingClientRect().y); 176 } 177 x = x*multiplier; 178 y = y*multiplier; 179 180 181 if (this.points.length >= 6) { 182 let c = this.getCenter(); 183 this.canvasContext.fillRect(c.x - 4, c.y - 4, 8, 8); 184 dis = Math.sqrt(Math.pow(x - c.x, 2) + Math.pow(y - c.y, 2)); 185 if (dis < 6) { 186 this.startpoint = false; 187 //$(this.canvas).on('mousemove', (e) => this.moveall(e)); 188 this.canvas.addEventListener('mousemove', this.listenerMoveAll,true); 189 return false; 190 } 191 } 192 193 for (let i = 0; i < this.points.length; i += 2) { 194 dis = Math.sqrt(Math.pow(x - (this.points[i]), 2) + Math.pow(y - (this.points[i + 1]), 2)); 195 if (dis < 6) { 196 this.activePoint = i; 197 //$(this.canvas).on('mousemove', (e) => this.move(e)); 198 this.canvas.addEventListener('mousemove', this.listenerMove,true); 199 return false; 200 } 201 } 202 203 for (let i = 0; i < this.points.length; i += 2) { 204 if (i > 1) { 205 lineDis = this.dotLineLength( 206 x, y, 207 this.points[i], this.points[i + 1], 208 this.points[i - 2], this.points[i - 1], 209 true 210 ); 211 if (lineDis < 6) { 212 insertAt = i; 213 } 214 } 215 } 216 217 this.points.splice(insertAt, 0, Math.round(x), Math.round(y)); 218 this.activePoint = insertAt; 219 //$(this.canvas).on('mousemove', (e) => this.move(e)); 220 this.canvas.addEventListener('mousemove', this.listenerMove,true); 221 222 this.draw(); 223 this.record(); 224 225 return false; 226 }; 227 228 //оÑÑиÑоваÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ 229 draw() { 230 this.canvasContext.canvas.width = this.canvasContext.canvas.width; 231 232 if (this.points.length < 2) { 233 return; 234 } 235 this.canvasContext.globalCompositeOperation = 'destination-over'; 236 this.canvasContext.fillStyle = 'rgb(255,255,255)'; 237 this.canvasContext.strokeStyle = 'rgb(255,20,20)'; 238 this.canvasContext.lineWidth = 1; 239 if (this.points.length >= 6) { 240 var c = this.getCenter(); 241 this.canvasContext.fillRect(c.x - 4, c.y - 4, 8, 8); 242 } 243 this.canvasContext.beginPath(); 244 this.canvasContext.moveTo(this.points[0], this.points[1]); 245 for (var i = 0; i < this.points.length; i += 2) { 246 this.canvasContext.fillRect(this.points[i] - 2, this.points[i + 1] - 2, 4, 4); 247 this.canvasContext.strokeRect(this.points[i] - 2, this.points[i + 1] - 2, 4, 4); 248 if (this.points.length > 2 && i > 1) { 249 this.canvasContext.lineTo(this.points[i], this.points[i + 1]); 250 } 251 } 252 this.canvasContext.closePath(); 253 this.canvasContext.fillStyle = 'rgba(255,0,0,0.3)'; 254 this.canvasContext.fill(); 255 this.canvasContext.stroke(); 256 }; 257 258 //запиÑÑ ÑоÑек в поле 259 record() { 260 if(typeof(this.settings.onchange)==='function'){ 261 this.settings.onchange(this.points.join(',')); 262 } 263 }; 264 265 dotLineLength(x, y, x0, y0, x1, y1, o) { 266 function lineLength(x, y, x0, y0) { 267 return Math.sqrt((x -= x0) * x + (y -= y0) * y); 268 } 269 270 if (o && !(o = function (x, y, x0, y0, x1, y1) { 271 if (!(x1 - x0)) return {x: x0, y: y}; 272 else if (!(y1 - y0)) return {x: x, y: y0}; 273 var left, tg = -1 / ((y1 - y0) / (x1 - x0)); 274 return { 275 x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), 276 y: tg * left - tg * x + y 277 }; 278 }(x, y, x0, y0, x1, y1), o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))) { 279 var l1 = lineLength(x, y, x0, y0), l2 = lineLength(x, y, x1, y1); 280 return l1 > l2 ? l2 : l1; 281 } 282 else { 283 var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1; 284 return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b); 285 } 286 }; 287 288 //вÑÑиÑлиÑÑ ÑенÑÑалÑнÑÑ ÑоÑÐºÑ Ð¾Ð±Ð»Ð°ÑÑи 289 getCenter() { 290 var ptc = []; 291 for (i = 0; i < this.points.length; i++) { 292 ptc.push({x: this.points[i], y: this.points[++i]}); 293 } 294 var first = ptc[0], last = ptc[ptc.length - 1]; 295 if (first.x != last.x || first.y != last.y) ptc.push(first); 296 var twicearea = 0, 297 x = 0, y = 0, 298 nptc = ptc.length, 299 p1, p2, f; 300 for (var i = 0, j = nptc - 1; i < nptc; j = i++) { 301 p1 = ptc[i]; 302 p2 = ptc[j]; 303 f = p1.x * p2.y - p2.x * p1.y; 304 twicearea += f; 305 x += ( p1.x + p2.x ) * f; 306 y += ( p1.y + p2.y ) * f; 307 } 308 f = twicearea * 3; 309 return {x: x / f, y: y / f}; 310 }; 311}; 312 313document.addEventListener("DOMContentLoaded", function () { 314 let elAreas = document.querySelectorAll('[data-type="w_area_draw'); 315 elAreas.forEach((elArea) => { 316 317 let elField = elArea.closest('div').querySelector('input'); 318 319 let area = new areaDraw(elArea,{ 320 'value': elField.value, 321 'onchange': function(points){ 322 elField.value = points; 323 let elForm = elArea.closest('form'); 324 if(elForm){ 325 let event = document.createEvent('HTMLEvents'); 326 event.initEvent('change', true, true); 327 elForm.dispatchEvent(event); 328 } 329 } 330 }); 331 332 elField.addEventListener('change',function(){ 333 area.valueSet(this.value); 334 area.draw(); 335 }); 336 337 }); 338}); 339
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.