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.
fillStyle
changefillStyle
result is the same; - Yevgeny BabiychukbeginPath()
inside theline
- andreymal method 8:23 pm