class Primitive { constructor(ctx) { this.ctx = ctx; } parsePoints(line) { let array = line.split(' '); let points = array.map(function(value) { let point = value.split(','); point[0] = Number(point[0]); point[1] = Number(point[1]); return point; }); return points; } moverLine(points) { this.ctx.moveTo(points[0][0], points[0][1]); for (let i = 1; i < points.length; i++) { this.ctx.lineTo(points[i][0], points[i][1]); } } line(points, lineWidth, strokeStyle) { points = this.parsePoints(points); this.ctx.lineWidth = lineWidth; this.ctx.strokeStyle = strokeStyle; this.moverLine(points); this.ctx.stroke(); this.ctx.closePath(); } strokeCircle(x, y, r, lineWidth, strokeStyle) { this.ctx.lineWidth = lineWidth; this.ctx.strokeStyle = strokeStyle; this.ctx.beginPath(); this.ctx.arc(x, y, r, 0, Math.PI * 2); this.ctx.closePath(); this.ctx.stroke(); } strokePolygon(points, lineWidth, strokeStyle) { points = this.parsePoints(points); this.ctx.lineWidth = lineWidth; this.ctx.strokeStyle = strokeStyle; console.log(this.ctx.strokeStyle); this.ctx.beginPath(); this.moverLine(points); this.ctx.closePath(); this.ctx.stroke(); } strokeRect(x, y, w, h, lineWidth, strokeStyle) { this.ctx.lineWidth = lineWidth; this.ctx.strokeStyle = strokeStyle; this.ctx.strokeRect(x, y, w, h); } fillCircle(x, y, r, fillStyle) { this.ctx.fillStyle = fillStyle; this.ctx.beginPath(); this.ctx.arc(x, y, r, 0, Math.PI * 2); this.ctx.closePath(); this.ctx.fill(); } fillPolygon(points, fillStyle) { points = this.parsePoints(points); this.ctx.fillStyle = fillStyle; this.ctx.beginPath(); this.moverLine(points); this.ctx.closePath(); this.ctx.fill(); } fillRect(x, y, w, h, fillStyle) { this.ctx.fillStyle = fillStyle; this.ctx.fillRect(x, y, w, h); } fillText(text, x, y, font, fillStyle) { this.ctx.font = font; this.ctx.fillStyle = fillStyle; this.ctx.fillText(text, x, y); } superRect(x, y, w, h, fillStyle, lineWidth, strokeStyle) { this.fillRect(x, y, w, h, fillStyle); this.strokeRect(x, y, w, h, lineWidth, strokeStyle); } superPolygon(points, fillStyle, lineWidth, strokeStyle) { this.fillPolygon(points, fillStyle); this.strokePolygon(points, lineWidth, strokeStyle); } superCircle(x, y, r, fillStyle, lineWidth, strokeStyle) { this.fillCircle(x, y, r, fillStyle); this.strokeCircle(x, y, r, lineWidth, strokeStyle); } } let primitive = new Primitive(document.getElementById('imgCanvas').getContext('2d')); class CreateObj { template(type, color) { return { 'type': type, 'disable': false }; } polygon(points, internalCol, externalCol, lineWidth) { let template = this.template('polygon'); template.points = points; template.internalCol = internalCol; template.externalCol = externalCol; template.line = lineWidth; return template; } } let obj = new CreateObj; let p = obj.polygon('300,300 30,30 420,30', '#ff0000', '#000000', 1); console.log(JSON.stringify(p, '', ' ')); primitive.superPolygon(p.points, p.internalCol, p.line, p.externalCol); let figures = []; figures.push({ 'type': 'rect', 'x': 360, 'y': 270, 'width': 200, 'height': 100, 'disable': false, 'border': { 'width': 3, 'color': 'black', }, 'area': { 'color': 'blue', } }); function dr() { for (let fig of figures) { if (!fig.disable) { primitive.superRect(fig.x, fig.y, fig.width, fig.height, fig.area.color, fig.border.width, fig.border.color); } } } primitive.line('60,330 270,330', 3, 'green'); primitive.superCircle(165, 30, 15, '#ff0ff0', 3, '#000000'); primitive.superPolygon('135,90 165,300 195,90', 'red', 3, 'black'); primitive.superRect(60, 360, 210, 90, 'blue', 3, 'black'); primitive.fillText('Primitive test', 75, 415, '30px tahoma', 'black'); dr(); 
 <canvas id="imgCanvas" width="660" height="660" style="border: 2px solid black"></canvas> <script type="text/javascript" src="https://stacksnippets.net/js"></script> 

I work with canvas , which means its context is an object accessible by reference.

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

There are two functions for example:

 function r1(){ ctx.fillStyle = 'red'; //код рисования... } function r2(){ ctx.fillStyle = 'magenta'; //код рисования два... } 

Functions are called in a written order, that is:

 r1(); r2(); 

As mentioned, ctx - объект accessible by reference.

The interpreter begins to perform the first function, but we know that it will run further along the code, without waiting for the completion of the first function, to begin the execution of the second.

And we get - functions are executed in parallel.

They interact with the ctx object, with the same object, with the result that I get a tricky bug, so to speak.

The first function for its needs defines the property fillStyle of the ctx object as red , the second function for its needs as magenta . After that, the first function starts drawing using the ctx object, but as the second function randomly replaces the values, the first function draws not a red square, but a purple one.

And finally the question: how to solve this problem?

PS The most correct and elegant, but I will be glad to any decision.

  • five
    "we know that he will run further along the code, without waiting for the completion of the first function, will begin the execution of the second." - For example, I do not know. Who are we? - Igor
  • @Igor Read somewhere, about the fact that he will run; We are me and what I read; And when I turn off the second function, it works fine, I substitute any other very small function (not more than removed) that has the fillStyle change fillStyle result is the same; - Yevgeny Babiychuk
  • four
    You have become a victim of a phenomenon that I call "the reproduction of ignorance through the Internet." - Igor
  • @Igor is quite possible, I will not argue, but please explain why then it happens vedb color changed, even all the code left, so that you look (and yes this is nonsense and not a code) - Yevgeny Babiychuk
  • 3
    @ Yevgeny Babiychuk is an example wrong, he has nothing to do with the problem. You simply forgot to call beginPath() inside the line - andreymal method 8:23 pm

0