{"id":328812,"date":"2022-01-30T21:00:14","date_gmt":"2022-01-30T21:00:14","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=328812"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=328812","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Art-pixel \u043d\u0430 Angular \u0438 Nest.js. \u0427\u0430\u0441\u0442\u044c 2<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438  \u043c\u044b \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0438\u0441\u0443\u043d\u043a\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0440\u0430\u0431\u043e\u0442, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0438\u043b\u0438 \u043b\u0443\u0447\u0448\u0435. \u041f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u043c\u043e\u0442\u0440\u0438\u043c  <a href=\"https:\/\/habr.com\/ru\/post\/647411\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>ng g i shared\/interfaces\/canvasPostnterface.interface.ts <\/strong>\u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043d\u0435\u0433\u043e:<\/p>\n<pre><code class=\"cs\">export interface CanvasPostInterface {   _id?: string,   name: string;   image: string;   canvas: string | []; } <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441,\u00a0 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 CRUD, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0448 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 <strong>ng g s shared\/services\/root <\/strong>\u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { Injectable } from '@angular\/core'; import { HttpClient } from '@angular\/common\/http'; import { environment } from 'src\/environments\/environment.dev';  @Injectable({   providedIn: 'root' }) export class RootService {    protected apiUrl = \u0441.apiUrl;    constructor(     protected http: HttpClient,   ) { }  } <\/code><\/pre>\n<p>\u041d\u0435 \u0417\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c environment, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 environment\/environment.dev.ts<\/p>\n<p><strong>apiUrl: &#8216;localhost\/api&#8217;<\/strong><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 <strong>shared\/abstract\/abstract-base-service.abstarct.ts<\/strong><\/p>\n<pre><code class=\"cs\">import { Observable } from 'rxjs';  export abstract class AbstractBaseService {  public abstract getData(): Observable&lt;any>;  public abstract getDataById(): Observable&lt;any>;  public abstract update(): Observable&lt;any>;  public abstract create(): Observable&lt;any>;  public abstract destroy(): Observable&lt;Response>; } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 <strong>canvas-post<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 <strong>ng g s shared\/services\/canvas-post, <\/strong>\u043f\u0438\u0448\u0435\u043c \u0432 canvas-post \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">import { HttpHeaders } from '@angular\/common\/http'; import { Injectable } from '@angular\/core'; import { Observable } from 'rxjs'; import { AbstractBaseService } from '..\/abstract\/abstract-base-service.abstarct'; import { CanvasPostInterface } from '..\/interfaces\/canvas-post.interface'; import { RootService } from '.\/root.service';  @Injectable({   providedIn: 'root' }) export class CanvasPostService extends RootService implements AbstractBaseService {   httpOptions = {     headers: new HttpHeaders({       'Content-Type': 'application\/json',     }),   };   protected componentUrl = `${this.apiUrl}\/Canvas`;    getData(): Observable&lt;CanvasPostInterface[]> {     return this.http.get&lt;CanvasPostInterface[]>(`${this.componentUrl}\/canvas`);   }    getDataById(id: string): Observable&lt;CanvasPostInterface> {     return this.http.get&lt;CanvasPostInterface>(`${this.componentUrl}\/${id}`);   }    update(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {     const body = { data };     return this.http.patch&lt;CanvasPostInterface>(`${this.componentUrl}\/${data._id}`, body);   }    create(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {     return this.http.post&lt;CanvasPostInterface>(`${this.componentUrl}\/create`, data,     this.httpOptions);   }      destroy(id: number): Observable&lt;Response> {     return this.http.delete&lt;any>(`${this.componentUrl}\/${id}`);   } } <\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"442\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/666\/660\/e63\/666660e63f843ed68daced5620c382fe.png\" data-width=\"330\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0448\u0438\u0445 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044e \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u201c\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e\u201d,\u00a0\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0432 <strong>main-canvas.component.html <\/strong>\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443:<\/p>\n<pre><code class=\"xml\">&lt;app-canvas     [uploadSuccess]=\"uploadSuccess\"      (pagesEventSave)=\"getSaveCanvas($event)\" > &lt;\/app-canvas> <\/code><\/pre>\n<p>\u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 <\/p>\n<pre><code class=\"xml\">(pagesEventSave)=\"getSaveCanvas($event)\" <\/code><\/pre>\n<p>\u0432 <strong>main-canvas.component.ts<\/strong> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>getSaveCanvas()<\/strong> \u0433\u0434\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 create \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 CanvasPostService \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0447\u0435\u0433\u043e \u0437\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u043a \u043d\u0435\u043c\u0443 \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f, \u0430 \u043f\u043e\u043a\u0430 \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">constructor(private canvasPostService: CanvasPostService) { }  \u00a0getSaveCanvas(data: {}) {  \u00a0\u00a0\u00a0this.canvasPostService.create(data as CanvasPostInterface)      .subscribe(respons=>{   \u00a0\u00a0\u00a0})  \u00a0}<\/code><\/pre>\n<p>\u0432 canvas.component.html \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u043d \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-card-4\"> \u00a0&lt;div class=\"w3-container w3-center\"> \u00a0\u00a0\u00a0&lt;label for=\"colorWell\">&lt;\/label>     \u00a0\u00a0\u00a0&lt;input list=\"\" id=\"colorWell\" type=\"color\" name=\"colorRect\"            [(ngModel)]=\"colorRect\">  \u00a0\u00a0\u00a0&lt;button (click)=\"create()\">\u0412\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043e\u043a&lt;\/button> \u00a0\u00a0\u00a0&lt;button (click)=\"clearPixel()\">\u0417\u0430\u0434\u0430\u0442\u044c \u043f\u0438\u043a\u0441\u0435\u043b\u044e \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430&lt;\/button> \u00a0\u00a0\u00a0&lt;button (click)=\"save()\">\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e&lt;\/button>  \u00a0&lt;\/div> &lt;\/div>  &lt;div class=\"w3-card-4 layer\"> \u00a0&lt;div class=\"w3-container w3-center\">     \u00a0\u00a0\u00a0&lt;canvas id=\"canvas\" #canvas>&lt;\/canvas>     \u00a0&lt;\/div> &lt;\/div><\/code><\/pre>\n<p><strong>\u0432 canvas.component.ts <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 save  \u0433\u0434\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 pagesEventSave \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434  <strong>getSaveCanvas()<\/strong> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <strong>main-canvas <\/strong>\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0430\u0437\u0443, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0435\u0433\u043e \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">@Output() pagesEventSave: EventEmitter&lt;{}>=new EventEmitter&lt;{}>(); \/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e name name: string; \/\/\u0432 \u043c\u0435\u0442\u043e\u0434 onResize() \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c this.name = data.name;   onResize(data: any) {     this.name = data.name;     this.innerWidth = data.innerWidth;     this.innerHeight = data.innerHeight;     this.widthRect = data.widthRect;     this.heightRect = data.heightRect;     this.numberOf = data.numberOf;     this.borderRow = data.borderRow;     this.numberRow = data.numberRow;     this.canvas.width = this.innerWidth;     this.canvas.height = this.innerHeight     this.colorfillStyle = data.colorfillStyle;     this.cleardraw()     this.draw()   } \/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u00a0save() { \u00a0\u00a0\u00a0const data = this.canvas?.toDataURL(); \u00a0\u00a0\u00a0this.pagesEventSave.emit({image: data, name: this.name,                               canvas: this.matr}); \u00a0}  <\/code><\/pre>\n<p>\u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 app.module.ts \u043c\u043e\u0434\u0443\u043b\u044c <strong>HttpClientModule<\/strong><\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c\u00a0 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0434\u043b\u044f \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043c\u0430\u0441\u0441\u0438\u0432 <strong>matr, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c JSON.stringify()<\/strong>\u00a0<\/p>\n<pre><code class=\"javascript\">this.pagesEventSave.emit({ image: data, name: this.name, canvas: JSON.stringify(this.matr) });<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p><strong>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0430\u0439\u0434\u0435\u0440.<\/strong><\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>ng g c canvas\/components\/slider<\/strong>\u00a0<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 assets \u043a\u0430\u0442\u0430\u043b\u043e\u0433 images, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"130\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d17\/81a\/d70\/d1781ad70531ce451b8010546b9d6f9a.png\" data-width=\"344\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <strong>slider.components.html<\/strong><\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-content w3-display-container\">  \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/1.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/2.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/3.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/4.webp\" style=\"width:400px\">   \u00a0&lt;button class=\"w3-button w3-black w3-display-left\" (click)=\"plusDivs(-1)\">    &amp;#10094;   &lt;\/button> \u00a0&lt;button class=\"w3-button w3-black w3-display-right\" (click)=\"plusDivs(1)\">    &amp;#10095;   &lt;\/button>  &lt;\/div><\/code><\/pre>\n<p>\u00a0\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <strong>slider.components.ts<\/strong><\/p>\n<p>\u00a0<\/p>\n<pre><code class=\"cs\">import { Component, AfterViewInit } from '@angular\/core';   @Component({  selector: 'app-slider',  templateUrl: '.\/slider.component.html',  styleUrls: ['.\/slider.component.scss'] }) export class SliderComponent implements AfterViewInit {    slideIndex = 1;  constructor(private elementRef: ElementRef) { }    ngAfterViewInit(): void {    this.showDivs(this.slideIndex);  }    plusDivs(n: number) {    this.showDivs(this.slideIndex += n);  }    showDivs(n: number) {    console.log(n)    let i;    let x = document.getElementsByClassName(\"mySlides\");    if (n > x.length) {      this.slideIndex = 1    }    if (n &lt; 1) { this.slideIndex = x.length }    for (i = 0; i &lt; x.length; i++) {      (x[i] as HTMLElement).style.display = \"none\";    }    (x[this.slideIndex - 1] as HTMLElement).style.display = \"block\";  } }   \/*\u043c\u0435\u0442\u043e\u0434 showDivs(n: number) \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e getElementsByClassName \u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e @ElementRef  \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 showDivsRef(n: number) \u0433\u0434\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c  ElementRef \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0432\u043d\u0435\u0434\u0440\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c  constructor(private elementRef: ElementRef) { }  *\/    showDivsRef(n: number) {     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c document.getElementsByClassName     let i;     let element = this.elementRef.nativeElement.getElementsByClassName(\"mySlides\");     console.log(n, element)     if (n > element.length) {       this.slideIndex = 1     }      if (n &lt; 1) { this.slideIndex = element.length }     if (element.length) {       for (i = 0; i &lt; element.length; i++) {         element[i].style.display = \"none\";       }       element[this.slideIndex - 1].style.display = \"block\";     }   }   <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 left-panel.component.html \u043f\u043e\u0441\u043b\u0435 &lt;div class=&#187;w3-third&#187;><\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-white w3-text-grey w3-card-4\">    &lt;div class=\"w3-container\">      &lt;p class=\"w3-large\">&lt;b>&lt;i class=\"fa fa-asterisk fa-fw w3-margin-right w3-text-teal\">&lt;\/i>\u0413\u0430\u043b\u0435\u0440\u0435\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432&lt;\/b>      &lt;\/p>      &lt;app-slider>&lt;\/app-slider>      &lt;hr>    &lt;\/div>  &lt;\/div>&lt;br> <\/code><\/pre>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"750\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/512\/7d7\/4eb\/5127d74eb1a31a6adf0889e224422dc7.png\" data-width=\"1408\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/strong><\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c Mock.service \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 canvas.modelMock.ts, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 <a href=\"https:\/\/github.com\/Gdymora\/pixel-art\" rel=\"noopener noreferrer nofollow\">git <\/a>, \u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0431\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">export class InMemoryCanvasModel {   get data() {    return this._data;  }  _data = [    {      _id: \u201d61f0f9ad70c1c74fafc641f0\u201d,      name: \"love\",      image: \"love\",      canvas: ['\u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u043c\u0435\u0441\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 git'], }]; } <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0448 <strong>canvas-post-mock.service.ts, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 <strong>main-canvas <\/strong>\u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441<strong> <\/strong>CanvasPostMockService<\/p>\n<pre><code class=\"cs\">import { InMemoryCanvasModel } from '..\/models\/mock\/canvas.modelMock';   @Injectable({  providedIn: 'root' }) export class CanvasPostMockService {  private readonly list;  private dataService: InMemoryCanvasModel;    constructor() {    this.dataService = new InMemoryCanvasModel();    this.list = this.dataService.data ;  }   getComponent(): Observable&lt;CanvasPostInterface[]> {    return of(this.list);  }   getData(): Observable&lt;CanvasPostInterface[]> {    return of();  }   getDataById(id: string): Observable&lt;CanvasPostInterface> {    return of();  }   update(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {    return of();  }   create(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {    return of();  }   destroy(id: number): Observable&lt;Response> {    return of();  } } <\/code><\/pre>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430\u0448 \u0441\u043b\u0430\u0439\u0434\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0448\u0438\u0445 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 <strong>slide.component.html, \u0447\u0442\u043e \u0431\u044b \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u0442\u0430\u043a:<\/strong><\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-content w3-display-container\">  &lt;div *ngFor=\"let image of images\">    &lt;img class=\"mySlides\" src=\"{{image}}\" style=\"width:400px\">  &lt;\/div>  &lt;button class=\"w3-button w3-black w3-display-left\"           (click)=\"plusDivs(-1)\">&amp;#10094;   &lt;\/button>  &lt;button class=\"w3-button w3-black w3-display-right\"           (click)=\"plusDivs(1)\">&amp;#10095;   &lt;\/button> &lt;\/div>  <\/code><\/pre>\n<p>\u041e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c<strong> slide.component.ts<\/strong><\/p>\n<pre><code class=\"cs\">\/\/\u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u0438 \u0437\u043d\u0430\u0447\u0438\u0442 \u0431\u0435\u0440\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435  images: CanvasPostInterface[] = [     { _id: '', canvas: [], name: \"\", image: \"assets\/images\/1.webp\" },     { _id: '', canvas: [], name: \"\", image: \"assets\/images\/2.webp\" },     { _id: '', canvas: [], name: \"\", image: \"assets\/images\/3.webp\" },     { _id: '', canvas: [], name: \"\", image: \"assets\/images\/4.webp\" }   ];    @Input() imageInput: any; \u2026\u2026.\/*\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0448\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448 \u043c\u0430\u0441\u0441\u0438\u0432*\/  ngOnInit(): void {    if (this.imageInput) {      this.images = this.imageInput.map((data: any) => data.image)    }  } <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u043b\u0430\u0439\u0434\u0435\u0440, \u0433\u0430\u043b\u0435\u0440\u0435\u044e \u043d\u0430\u0448\u0438\u0445 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <strong>main-canvas.component.html<\/strong><\/p>\n<pre><code class=\"xml\">&lt;!-- images slider--> &lt;div class=\"w3-container w3-card w3-white w3-margin-bottom\">     &lt;h2 class=\"w3-text-grey w3-padding-16\">       &lt;i class=\"fa fa-paint-brush fa-fw w3-margin-right w3-xxlarge          w3-text-teal\">&lt;\/i>       \u041f\u043e\u043b\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f     &lt;\/h2>    &lt;div class=\"w3-container\">      \/\/\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c pip async      &lt;app-slider [imageInput]=\"canvasImg | async\">&lt;\/app-slider>             &lt;hr>    &lt;\/div>  &lt;\/div> &lt;!-- End images slider--> <\/code><\/pre>\n<p>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c <strong>main.canvas.component.ts <\/strong>\u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0441\u044e\u0434\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b, \u0430 \u043f\u043e\u043a\u0430 \u0431\u0443\u0434\u0435\u043c \u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0444\u0435\u0439\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<pre><code class=\"cs\">\/\/main.canvas.component.ts canvasImg:  Observable&lt;CanvasPostInterface[]>|undefined;  constructor(private canvasPostService: CanvasPostService) { }  ngOnInit(): void {    this.canvasImg = this.canvasPostService.getComponent(); } <\/code><\/pre>\n<p>\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0440\u0438\u0441\u0443\u043d\u043e\u043a \u0432 slider, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 <strong>slider.component.css \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0438\u043b\u0435\u0439:<\/strong><\/p>\n<pre><code class=\"css\">.mySlides {  display:none; }  img.center-block {  margin-left: auto;  margin-right: auto; } <\/code><\/pre>\n<p>\u0412\u043e\u0442, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"811\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d7d\/df4\/187\/d7ddf4187b0f9f038b5c936cbb920bd9.png\" data-width=\"939\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f.<\/strong> <\/p>\n<p>\u041a\u0430\u043a \u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0438\u043a\u0430\u043c\u0438, \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c <strong>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u043f\u0440\u043e\u0432\u043e\u0434\u044f \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c<\/strong>, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0437\u0430\u0436\u0430\u0442\u043e\u0439 \u043b\u0435\u0432\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0435\u0439 \u043c\u044b\u0448\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <strong>mousemove<\/strong>, \u0430 \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 <strong>event.which<\/strong> \u0440\u0430\u0432\u043d\u043e \u0435\u0434\u0438\u043d\u0438\u0446\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u0436\u0430\u0442\u0430 \u043b\u0435\u0432\u0430\u044f \u043a\u043b\u0430\u0432\u0438\u0448\u0430. \u0410 \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u043c\u043b\u044f\u0442\u044c \u043a\u043e\u0434 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0435, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u043d\u0435 \u043d\u0430\u0436\u0430\u0442\u0430, \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u043c.\u00a0<\/p>\n<pre><code class=\"cs\">\/\/\u0435\u0441\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u043d\u0435 \u0437\u0430\u0436\u0430\u0442\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u043c if (event.which !== 1) { \u00a0\u00a0return; }<\/code><\/pre>\n<p>\u0412\u043e\u0442, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<pre><code class=\"cs\">this.rendererRef = this.renderer.listen(this.canvasRef.nativeElement,                                         'mousemove', (event) => {\u00a0        \/\/\u0435\u0441\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u043d\u0435 \u0437\u0430\u0436\u0430\u0442\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u00a0\u00a0\u00a0\u00a0\u00a0if (event.which !== 1) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0let cX = event.offsetX; \u00a0\u00a0\u00a0\u00a0\u00a0let cY = event.offsetY; \u00a0\u00a0\u00a0\u00a0\u00a0const offsetLeft = this.canvasRef.nativeElement.offsetLeft; \u00a0\u00a0\u00a0\u00a0\u00a0const offsetTop = this.canvasRef.nativeElement.offsetTop; \u00a0\u00a0\u00a0\u00a0\u00a0this.canvasX = cX - offsetLeft; \u00a0\u00a0\u00a0\u00a0\u00a0this.canvasY = cY - offsetTop;  \u00a0\u00a0\u00a0\u00a0\u00a0this.matr.data.map(data => { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (cX >= data.x &amp;&amp; cX &lt; data.x + this.numberOf &amp;&amp; cY >= data.y             &amp;&amp; cY &lt; data.y + this.numberOf) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.ctx.fillStyle = this.colorRect; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.ctx.fillRect(data.x, data.y, this.numberOf, this.numberOf); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data.color = this.colorRect; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0\u00a0}) \u00a0\u00a0\u00a0\u00a0\u00a0this.canvasRef.nativeElement.getBoundingClientRect() \u00a0\u00a0\u00a0\u00a0\u00a0localStorage.setItem('matr', JSON.stringify(this.matr)); \u00a0\u00a0\u00a0\u00a0\u00a0const data = this.canvas?.toDataURL(); \u00a0\u00a0\u00a0});<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0432 \u0434\u0432\u0443\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0439\u00a0 \u043a\u043e\u0434, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434<strong> eventOfset(event: MouseEvent)<\/strong> \u0438 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0442\u0443\u0434\u0430.<\/p>\n<pre><code class=\"cs\">eventOfset(event: MouseEvent) { \u00a0\u00a0\u00a0let cX = event.offsetX; \u00a0\u00a0\u00a0let cY = event.offsetY;     \u00a0\u00a0\u00a0const offsetLeft = this.canvasRef.nativeElement.offsetLeft; \u00a0\u00a0\u00a0const offsetTop = this.canvasRef.nativeElement.offsetTop; \u00a0\u00a0\u00a0this.canvasX = cX - offsetLeft; \u00a0\u00a0\u00a0this.canvasY = cY - offsetTop;  \u00a0\u00a0\u00a0this.matr.data.map(data => { \u00a0\u00a0\u00a0\u00a0\u00a0if (cX >= data.x &amp;&amp; cX &lt; data.x + this.numberOf &amp;&amp; cY >=       data.y &amp;&amp; cY &lt; data.y + this.numberOf) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.ctx.fillStyle = this.colorRect; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.ctx.fillRect(data.x, data.y, this.numberOf, this.numberOf); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data.color = this.colorRect; \u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0}) \u00a0\u00a0\u00a0this.canvasRef.nativeElement.getBoundingClientRect(); \u00a0\u00a0\u00a0localStorage.setItem('matr', JSON.stringify(this.matr)); \u00a0\u00a0\u00a0const data = this.canvas?.toDataURL(); \u00a0}<\/code><\/pre>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043d\u0435\u0441\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432  <strong>ngAfterViewInit():<\/strong><\/p>\n<pre><code class=\"cs\">  ngAfterViewInit() {    ....     this.rendererRef = this.renderer.listen(this.canvasRef.nativeElement, 'click', (event: MouseEvent) => {      \/\/\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434       this.eventOfset(event)     });     this.rendererRef = this.renderer.listen(this.canvasRef.nativeElement, 'mousemove', (event) => {       if (event.which !== 1) {         return;       }        \/\/\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434       this.eventOfset(event);     });    }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u043e\u0432, \u0432\u043d\u0435\u0441\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\u00a0 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432 <strong>slider.component.ts <\/strong>\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <strong>thereIsData = false<\/strong>, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0448\u043b\u0438, \u0442\u043e \u043c\u0435\u043d\u044f\u0435\u043c \u0432 ngOnInit() \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 <strong>true<\/strong>. \u0421\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <strong>transferTo\u0421anvas()<\/strong> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0438\u0441\u0443\u043d\u043a\u0430 <strong>main-canvas<\/strong>, \u0430 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430 \u043d\u0430\u0448 \u0445\u043e\u043b\u0441\u0442.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e\u00a0\u0432 main-canvas.component.html \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 app-slider\u00a0 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043c (pagesEventSlider)=&#187;dataSlider($event)&#187;, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">&lt;app-slider (pagesEventSlider)=\"dataSlider($event)\"    [imageInput]=\"canvasImg | async\"> &lt;\/app-slider><\/code><\/pre>\n<p>\u00a0main-canvas.component.ts \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 dataSlider($event: {}) {\u00a0\u00a0\u00a0\/\/TODO\u00a0}<\/p>\n<p>\u0432 slider.component.ts \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c <\/p>\n<pre><code class=\"cs\">@Output() pagesEventSlider: EventEmitter&lt;{}> = new EventEmitter&lt;{}>();<\/code><\/pre>\n<p>\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 transferToCanvas:<\/p>\n<pre><code class=\"cs\">transferToCanvas(canvas: any) { \u00a0\u00a0\u00a0if (!this.thereIsData) {\u00a0\u00a0\u00a0\u00a0\u00a0    return; \u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0this.pagesEventSlider.emit(canvas); \u00a0}<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0434\u043b\u044f \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u0430 \u0438 \u0445\u043e\u043b\u0441\u0442\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>main-canvas.<\/strong><\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 canvas.component.ts \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434<strong> createTtransferToDataCanvas.<\/strong><\/p>\n<pre><code class=\"cs\">\/* \u041c\u0435\u0442\u043e\u0434 \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0438\u0441\u0443\u043d\u043e\u043a\u043e\u0432 \u0438\u0437 \u0431\u0430\u0437\u044b *\/   createTtransferToDataCanvas(data: any) {     this.cleardraw()     this.matr = JSON.parse(data);     const matr = JSON.parse(data);     this.canvas.width = matr.innerWidth;     this.canvas.height = matr.innerHeight;     this.innerWidth = matr.innerWidth;     this.innerHeight = matr.innerHeight;     JSON.parse(data).data.map((data: any) => {       this.ctx.fillStyle = data.color;       this.ctx.fillRect(data.x, data.y, this.matr.numberOf,                         this.matr.numberOf);     })   }<\/code><\/pre>\n<p>\u00a0\u0412 \u044d\u0442\u043e\u043c \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c:<\/p>\n<pre><code class=\"cs\">  @Input() transferToDataCanvas: EventEmitter&lt;{}>; \/*\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u043d\u0430\u0448 transferToDataCanvas: EventEmitter  \u0432 ngOnInit()*\/  ngOnInit(): void {     this.uploadSuccess.subscribe(data => {       this.onResize(data);     });       this.transferToDataCanvas.subscribe(data => {       this.createTtransferToDataCanvas(data);     });   } <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 main-canvas.component.html \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c:<\/p>\n<pre><code class=\"cs\">&lt;app-canvas    [transferToDataCanvas]=\"transferToDataCanvas\"\u00a0    [uploadSuccess]=\"uploadSuccess\"    (pagesEventSave)=\"getSaveCanvas($event)\" >&lt;\/app-canvas><\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 <strong>main-canvas.component.ts<\/strong> \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043c\u0438\u0442\u0442\u0435\u0440:<\/p>\n<pre><code class=\"cs\">import { Component, EventEmitter, OnInit } from '@angular\/core'; import { FormGroup } from '@angular\/forms'; import { Observable } from 'rxjs'; import { CanvasPostInterface } from 'src\/app\/shared\/interfaces\/canvas-post.interface'; import { CanvasPostMockService as CanvasPostService } from 'src\/app\/shared\/services\/canvas-post-mock.service'; \/\/import { CanvasPostService   } from 'src\/app\/shared\/services\/canvas-post.service';  @Component({   selector: 'app-main-canvas',   templateUrl: '.\/main-canvas.component.html',   styleUrls: ['.\/main-canvas.component.scss'] }) export class MainCanvasComponent implements OnInit {    uploadSuccess: EventEmitter&lt;any> = new EventEmitter();   canvasImgSuccess: EventEmitter&lt;any> = new EventEmitter();   \/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043c\u0438\u0442\u0442\u0435\u0440 transferToDataCanvas   transferToDataCanvas: EventEmitter&lt;any> = new EventEmitter();   canvasImg: Observable&lt;CanvasPostInterface[]> | undefined;      constructor(private canvasPostService: CanvasPostService) { }    ngOnInit(): void {     this.canvasImg = this.canvasPostService.getComponent();     this.canvasPostService.getComponent().subscribe(respons => {       console.log(respons[0].image)     });      }    \/* \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0444\u043e\u0440\u043c\u044b \u0432 \u043a\u0430\u043d\u0432\u0430\u0441*\/   getDataPanel($event: FormGroup) {     const data = {       widthRect: Number($event.value.widthCanvas),       heightRect: Number($event.value.heightCanvas),       numberOf: Number($event.value.hwPixel),       borderRow: $event.value.meshThickness,       numberRow: Number($event.value.hwPixel) + Number($event.value.meshThickness),       innerWidth: Number($event.value.heightCanvas) * (Number($event.value.hwPixel) + Number($event.value.meshThickness)),       innerHeight: Number($event.value.widthCanvas) * (Number($event.value.hwPixel) + Number($event.value.meshThickness)),       colorfillStyle: $event.value.colorFone     }     this.uploadSuccess.emit(data);\/\/\u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438   }      \/* \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u0430 \u0438 \u043f\u0435\u0440\u0430\u0434\u0435\u0442 \u0432 \u043a\u0430\u043d\u0432\u0430\u0441*\/   dataSlider(data: {}) {     console.log(data)     this.transferToDataCanvas.emit(data);\/\/\u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438   }    \/* \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0430\u043d\u0435\u043b\u0438 \u0438 \u043f\u0435\u0440\u0430\u0434\u0435\u0442 \u0432 \u043a\u0430\u043d\u0432\u0430\u0441*\/   pagesEventInMain(data: {}) {     this.transferToDataCanvas.emit(data);\/\/\u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438   } } <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0430\u0448 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0440\u0438\u0441\u0443\u043d\u043e\u043a \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043e\u043a, \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u041c\u043e\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0445\u043e\u043b\u0441\u0442. \u041e\u0442\u043b\u0438\u0447\u043d\u043e.<\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u0435\u043c TAB \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/strong><\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435 \u044d\u0441\u0442\u0435\u0442\u0438\u0447\u043d\u043e.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"811\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/074\/f5f\/f69\/074f5ff69975d4bbbcbe810e1aef6974.png\" data-width=\"939\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0440\u044f\u0442\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c Tab \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043c \u0424\u043e\u0440\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u043e\u043b\u0441\u0442\u0430, \u0413\u0430\u043b\u0435\u0440\u0435\u044e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438 \u041c\u043e\u0438 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"811\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cd6\/416\/daa\/cd6416daafa996374c847a8049da00be.png\" data-width=\"628\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c left-panel.component.html, \u0447\u0442\u043e \u0431\u044b \u043a\u043e\u0434 \u0432 \u043d\u0435\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-third\" style=\"max-width: 600px;\">    &lt;!--TAB-->   &lt;div class=\"w3-bar w3-black\">     &lt;button class=\"w3-bar-item w3-button\" (click)=\"openTab('one')\">       \u0424\u043e\u0440\u043c\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u043e\u043b\u0441\u0442\u0430     &lt;\/button>     &lt;button class=\"w3-bar-item w3-button\" (click)=\"openTab('two')\">       \u041c\u043e\u0438 \u0440\u0430\u0431\u043e\u0442\u044b     &lt;\/button>     &lt;button class=\"w3-bar-item w3-button\" (click)=\"openTab('three')\">       \u0413\u0430\u043b\u0435\u0440\u0435\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432     &lt;\/button>   &lt;\/div>    &lt;div id=\"one\" class=\"tab\" >     &lt;div class=\"w3-white w3-text-grey w3-card-4\">       &lt;div class=\"w3-container\">         &lt;p class=\"w3-large\">&lt;b>&lt;i class=\"fa fa-asterisk fa-fw w3-margin-right w3-text-teal\">&lt;\/i>\u0424\u043e\u0440\u043c\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f             \u0445\u043e\u043b\u0441\u0442\u0430&lt;\/b>         &lt;\/p>         &lt;div class=\"w3-light-grey w3-round-xlarge w3-small\">           &lt;app-form (pagesEvent)=\"getData($event)\">&lt;\/app-form>         &lt;\/div>         &lt;hr>       &lt;\/div>     &lt;\/div>&lt;br>   &lt;\/div>    &lt;div id=\"two\" class=\"tab\" style=\"display:none\">     &lt;div class=\"w3-white w3-text-grey w3-card-4\">       &lt;div class=\"w3-container\">         &lt;p class=\"w3-large\">&lt;b>&lt;i class=\"fa fa-asterisk fa-fw w3-margin-right w3-text-teal\">&lt;\/i>\u041c\u043e\u0438 \u0440\u0430\u0431\u043e\u0442\u044b&lt;\/b>         &lt;\/p>         &lt;app-slider            (pagesEventSlider)=\"dataSlider($event)\"            [imageInput]=\"canvasImg\">         &lt;\/app-slider>         &lt;hr>         &lt;hr>       &lt;\/div>     &lt;\/div>&lt;br>   &lt;\/div>    &lt;div id=\"three\" class=\"tab\" style=\"display:none\">     &lt;div class=\"w3-white w3-text-grey w3-card-4\">       &lt;div class=\"w3-container\">         &lt;div class=\"w3-white w3-text-grey w3-card-4\">           &lt;div class=\"w3-container\">             &lt;p class=\"w3-large\">&lt;b>&lt;i class=\"fa fa-asterisk fa-fw w3-margin-right w3-text-teal\">&lt;\/i>\u0413\u0430\u043b\u0435\u0440\u0435\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432&lt;\/b>             &lt;\/p>             &lt;app-slider>&lt;\/app-slider>             &lt;hr>           &lt;\/div>         &lt;\/div>&lt;br>       &lt;\/div>     &lt;\/div>&lt;br>   &lt;\/div>    &lt;!--  --> &lt;\/div> <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043a\u043b\u0430\u0434\u043a\u0430\u043c\u0438 openTab() <strong>\u0432 left-panel.component.ts<\/strong><\/p>\n<pre><code class=\"cs\">import { Component, ElementRef, EventEmitter, Input, OnInit, Output }  from '@angular\/core'; import { FormGroup } from '@angular\/forms'; import { Observable } from 'rxjs'; import { CanvasPostInterface }  from 'src\/app\/shared\/interfaces\/canvas-post.interface';  @Component({   selector: 'app-left-panel',   templateUrl: '.\/left-panel.component.html',   styleUrls: ['.\/left-panel.component.scss'] }) export class LeftPanelComponent implements OnInit {    @Output() pagesEvent: EventEmitter&lt;FormGroup> =     new EventEmitter&lt;FormGroup>();    @Output() pagesEventLeftPanel: EventEmitter&lt;{}> =     new EventEmitter&lt;{}>();    @Input() imageInput: any;   canvasImg: any;    constructor(private elementRef: ElementRef) { }    ngOnInit(): void {     this.canvasImg = this.imageInput;\/\/\u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441\u043b\u0430\u0439\u0434\u0435\u0440   }    getData($event: FormGroup) {     this.pagesEvent.emit($event);   }    dataSlider(data: {}) {     this.pagesEventLeftPanel.emit(data);    \/\/\u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 main   } \/*\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043a\u043b\u0430\u0434\u043a\u0430\u043c\u0438*\/   openTab(tabId: string) {     let i;     let element = this.elementRef.nativeElement       .getElementsByClassName(\"tab\");     for (i = 0; i &lt; element.length; i++) {       element[i].style.display = \"none\";     }     document.getElementById(tabId).style.display = \"block\";   }  } <\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0438 \u0432\u0441\u0435. \u0425\u043e\u0442\u044f, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0435\u0449\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435 \u0434\u0430\u044e\u0449\u0435\u0435 \u043d\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0435\u0442\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 resizePixel() \u0432 <strong>canvas.component.ts <\/strong>\u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0448 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043c\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<pre><code class=\"cs\">import { AfterViewInit, Component, ElementRef,          EventEmitter, Input, OnInit, Output, Renderer2, ViewChild }  from '@angular\/core'; import { FormGroup } from '@angular\/forms';  @Component({   selector: 'app-canvas',   templateUrl: '.\/canvas.component.html',   styleUrls: ['.\/canvas.component.scss'] }) export class CanvasComponent implements AfterViewInit, OnInit {    @Output() pagesEventSave: EventEmitter&lt;{}> =     new EventEmitter&lt;{}>();    canvas: HTMLCanvasElement;   innerWidth: number;   innerHeight: number;   rendererRef: any;   numberRow: number;   numberOf = 10; \/\/\u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0438\u043a\u0441\u0435\u043b\u044f   borderRow = 1;   widthRect = 50;   heightRect = 50;   x = 0;   y = 0   canvasX: number \/\/ X click cordinates   canvasY: number \/\/ Y click cordinates   colorRect = '#242323';\/\/\u0446\u0432\u0435\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043b\u043a\u0438   colorfillStyle = '#19a923';\/\/\u0446\u0432\u0435\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u044f \u0445\u043e\u043b\u0441\u0442\u0430   matr = { innerWidth: 0, innerHeight: 0, numberOf: 10, backgroundColor: '#19a923', data: [{ x: 0, y: 0, color: '' }] }   name: string;   private ctx: CanvasRenderingContext2D | null;   @ViewChild('canvas') canvasRef: ElementRef;   @Input() uploadSuccess: EventEmitter&lt;FormGroup>;   @Input() transferToDataCanvas: EventEmitter&lt;{}>;    constructor(private el: ElementRef,     private renderer: Renderer2,   ) {     this.numberRow = this.numberOf + this.borderRow;     this.innerWidth = this.heightRect * this.numberRow;     this.innerHeight = this.widthRect * this.numberRow;   }    onResize(data: any) {     this.name = data.name;     this.innerWidth = data.innerWidth;     this.innerHeight = data.innerHeight;     this.widthRect = data.widthRect;     this.heightRect = data.heightRect;     this.numberOf = data.numberOf;     this.borderRow = data.borderRow;     this.numberRow = data.numberRow;     this.canvas.width = this.innerWidth;     this.canvas.height = this.innerHeight     this.colorfillStyle = data.colorfillStyle;     this.cleardraw()     this.draw()   }       ngOnInit(): void {     this.uploadSuccess.subscribe(data => {       this.onResize(data);     });     this.transferToDataCanvas.subscribe(data => {       this.createTtransferToDataCanvas(data);     });   }    ngAfterViewInit() {     this.canvas = this.canvasRef.nativeElement;     this.canvas.width = this.innerWidth;     this.canvas.height = this.innerHeight;     this.cleardraw()     this.draw();     const data = this.canvas?.toDataURL();      if (this.rendererRef != null) {       this.rendererRef();     }      this.rendererRef = this.renderer       .listen(this.canvasRef.nativeElement,                'click', (event: MouseEvent) => {       this.eventOfset(event)     });      this.rendererRef = this.renderer       .listen(this.canvasRef.nativeElement,                'mousemove', (event) => {       if (event.which !== 1) {         return;       }       this.eventOfset(event);     });    }    draw(): void {     this.matr.innerWidth = this.innerWidth;     this.matr.innerHeight = this.innerHeight;     this.matr.backgroundColor = this.colorfillStyle;     this.matr.numberOf = this.numberOf;     for (let i = 0; i &lt; this.heightRect; i++) {       for (let j = 0; j &lt; this.widthRect; j++) {         this.ctx.fillStyle = this.colorfillStyle;         this.ctx.fillRect(j * this.numberRow, i * this.numberRow,                            this.numberOf, this.numberOf);         this.matr.data.push({ x: j * this.numberRow,                               y: i * this.numberRow,                               color: this.colorfillStyle })       }     }    }    cleardraw(): void {     this.ctx = this.canvas.getContext('2d');     this.ctx.clearRect(0, 0, this.widthRect, this.heightRect);     this.matr.data = [];   }    createFromLocalStorage(): void {     const retrievedObject = localStorage.getItem('matr');     this.matr = JSON.parse(retrievedObject);     this.matr.data.map(data => {       this.ctx.fillStyle = data.color;       this.ctx.fillRect(data.x, data.y, this.matr.numberOf,                          this.matr.numberOf);     })   }    \/* \u041c\u0435\u0442\u043e\u0434 \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0438\u0441\u0443\u043d\u043e\u043a\u043e\u0432 \u0438\u0437 \u0431\u0430\u0437\u044b *\/   createTtransferToDataCanvas(data: any): void {     this.cleardraw()     this.matr = JSON.parse(data);     const matr = JSON.parse(data);     this.canvas.width = matr.innerWidth;     this.canvas.height = matr.innerHeight;     this.innerWidth = matr.innerWidth;     this.innerHeight = matr.innerHeight;     JSON.parse(data).data.map((data: any) => {       this.ctx.fillStyle = data.color;       this.ctx.fillRect(data.x, data.y, this.matr.numberOf,                          this.matr.numberOf);     })   }      \/* \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0438\u043a\u0441\u0435\u043b\u044f *\/   resizePixel(): void {     this.matr.data.map(data => {       this.ctx.fillStyle = data.color;       this.ctx.fillRect(data.x, data.y, this.matr.numberOf + 1,                          this.matr.numberOf + 1);     })   }    \/* \u0437\u0430\u0434\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0443 *\/   clearPixel(): void {     this.colorRect = this.matr.backgroundColor   }   \/* \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c *\/   save(): void {     const data = this.canvas?.toDataURL();     this.pagesEventSave.emit({ image: data, name: this.name,                                canvas: JSON.stringify(this.matr) });   }    \/* \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f *\/   eventOfset(event: MouseEvent): void {     let cX = event.offsetX;     let cY = event.offsetY;     const offsetLeft = this.canvasRef.nativeElement.offsetLeft;     const offsetTop = this.canvasRef.nativeElement.offsetTop;     this.canvasX = cX - offsetLeft;     this.canvasY = cY - offsetTop;      this.matr.data.map(data => {       if (cX >= data.x &amp;&amp; cX &lt; data.x + this.numberOf &amp;&amp; cY >= data.y            &amp;&amp; cY &lt; data.y + this.numberOf) {         this.ctx.fillStyle = this.colorRect;         this.ctx.fillRect(data.x, data.y, this.numberOf, this.numberOf);         data.color = this.colorRect;       }     })     this.canvasRef.nativeElement.getBoundingClientRect()     localStorage.setItem('matr', JSON.stringify(this.matr));     const data = this.canvas?.toDataURL();   } }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044e \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u0442 \u0443\u0431\u0438\u0440\u0430\u0442\u0441\u044f \u0441\u0435\u0442\u043a\u0430 \u0432 <strong>canvas.component.html <\/strong>\u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0435\u0433\u043e \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-card-4\">   &lt;div class=\"w3-container w3-center\">     &lt;label for=\"colorWell\">&lt;\/label>     &lt;input list=\"\" id=\"colorWell\" type=\"color\" name=\"colorRect\" [(ngModel)]=\"colorRect\">     &lt;button (click)=\"createFromLocalStorage()\">\u0412\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043e\u043a&lt;\/button>     &lt;button (click)=\"clearPixel()\">\u0417\u0430\u0434\u0430\u0442\u044c \u043f\u0438\u043a\u0441\u0435\u043b\u044e \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430&lt;\/button>     &lt;button (click)=\"save()\">\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e&lt;\/button>     &lt;button (click)=\"resizePixel()\">\u0423\u0431\u0440\u0430\u0442\u044c \u0441\u0435\u0442\u043a\u0443&lt;\/button>   &lt;\/div> &lt;\/div> &lt;div class=\"w3-card-4 layer\">   &lt;div class=\"w3-container w3-center\"  style=\"padding: 30px;\">     &lt;canvas id=\"canvas\" #canvas>&lt;\/canvas>   &lt;\/div> &lt;\/div><\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u0423\u0431\u0440\u0430\u0442\u044c \u0441\u0435\u0442\u043a\u0443<\/strong><\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"786\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b56\/e8d\/7b6\/b56e8d7b6253137be7840b6e0c087736.png\" data-width=\"1668\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0441\u0435\u0442\u043a\u0430 \u043f\u0440\u043e\u043f\u0430\u043b\u0430, \u0438 \u043d\u0430\u0448 \u0441\u043b\u043e\u043d\u0438\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u043c\u0443,<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"855\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/76f\/67f\/4a0\/76f67f4a060bef5aa56517f349d97a45.png\" data-width=\"1745\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043d\u0435\u0441\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0435 4300, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 <strong>angular.json<\/strong> \u0432\u043d\u0435\u0441\u0435\u043c \u0442\u0430\u043a\u0438\u0435 \u0432\u043e\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"json\">    \"defaultConfiguration\": \"production\"         },         \"serve\": {           \"options\": {             \"port\": 4300           },           \"builder\": \"@angular-devkit\/build-angular:dev-server\",<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435, \u043f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0430 4300 \u043f\u043e\u0440\u0442\u0443.  \u041d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u0441\u0435. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442.<\/p>\n<p><a href=\"https:\/\/art-pixel.jdymora.com\/\" rel=\"noopener noreferrer nofollow\">\u0414\u0435\u043c\u043e<\/a>, <a href=\"https:\/\/github.com\/Gdymora\/pixel-art\" rel=\"noopener noreferrer nofollow\">git<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/648619\/\"> https:\/\/habr.com\/ru\/post\/648619\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438  \u043c\u044b \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0438\u0441\u0443\u043d\u043a\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0440\u0430\u0431\u043e\u0442, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0438\u043b\u0438 \u043b\u0443\u0447\u0448\u0435. \u041f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u043c\u043e\u0442\u0440\u0438\u043c  <a href=\"https:\/\/habr.com\/ru\/post\/647411\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>ng g i shared\/interfaces\/canvasPostnterface.interface.ts <\/strong>\u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043d\u0435\u0433\u043e:<\/p>\n<pre><code class=\"cs\">export interface CanvasPostInterface {   _id?: string,   name: string;   image: string;   canvas: string | []; } <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441,\u00a0 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 CRUD, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0448 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 <strong>ng g s shared\/services\/root <\/strong>\u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { Injectable } from '@angular\/core'; import { HttpClient } from '@angular\/common\/http'; import { environment } from 'src\/environments\/environment.dev';  @Injectable({   providedIn: 'root' }) export class RootService {    protected apiUrl = \u0441.apiUrl;    constructor(     protected http: HttpClient,   ) { }  } <\/code><\/pre>\n<p>\u041d\u0435 \u0417\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c environment, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 environment\/environment.dev.ts<\/p>\n<p><strong>apiUrl: &#8216;localhost\/api&#8217;<\/strong><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 <strong>shared\/abstract\/abstract-base-service.abstarct.ts<\/strong><\/p>\n<pre><code class=\"cs\">import { Observable } from 'rxjs';  export abstract class AbstractBaseService {  public abstract getData(): Observable&lt;any>;  public abstract getDataById(): Observable&lt;any>;  public abstract update(): Observable&lt;any>;  public abstract create(): Observable&lt;any>;  public abstract destroy(): Observable&lt;Response>; } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 <strong>canvas-post<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 <strong>ng g s shared\/services\/canvas-post, <\/strong>\u043f\u0438\u0448\u0435\u043c \u0432 canvas-post \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">import { HttpHeaders } from '@angular\/common\/http'; import { Injectable } from '@angular\/core'; import { Observable } from 'rxjs'; import { AbstractBaseService } from '..\/abstract\/abstract-base-service.abstarct'; import { CanvasPostInterface } from '..\/interfaces\/canvas-post.interface'; import { RootService } from '.\/root.service';  @Injectable({   providedIn: 'root' }) export class CanvasPostService extends RootService implements AbstractBaseService {   httpOptions = {     headers: new HttpHeaders({       'Content-Type': 'application\/json',     }),   };   protected componentUrl = `${this.apiUrl}\/Canvas`;    getData(): Observable&lt;CanvasPostInterface[]> {     return this.http.get&lt;CanvasPostInterface[]>(`${this.componentUrl}\/canvas`);   }    getDataById(id: string): Observable&lt;CanvasPostInterface> {     return this.http.get&lt;CanvasPostInterface>(`${this.componentUrl}\/${id}`);   }    update(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {     const body = { data };     return this.http.patch&lt;CanvasPostInterface>(`${this.componentUrl}\/${data._id}`, body);   }    create(data: CanvasPostInterface): Observable&lt;CanvasPostInterface> {     return this.http.post&lt;CanvasPostInterface>(`${this.componentUrl}\/create`, data,     this.httpOptions);   }      destroy(id: number): Observable&lt;Response> {     return this.http.delete&lt;any>(`${this.componentUrl}\/${id}`);   } } <\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0448\u0438\u0445 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044e \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u201c\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e\u201d,\u00a0\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0432 <strong>main-canvas.component.html <\/strong>\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443:<\/p>\n<pre><code class=\"xml\">&lt;app-canvas     [uploadSuccess]=\"uploadSuccess\"      (pagesEventSave)=\"getSaveCanvas($event)\" > &lt;\/app-canvas> <\/code><\/pre>\n<p>\u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 <\/p>\n<pre><code class=\"xml\">(pagesEventSave)=\"getSaveCanvas($event)\" <\/code><\/pre>\n<p>\u0432 <strong>main-canvas.component.ts<\/strong> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>getSaveCanvas()<\/strong> \u0433\u0434\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 create \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 CanvasPostService \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0447\u0435\u0433\u043e \u0437\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u043a \u043d\u0435\u043c\u0443 \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f, \u0430 \u043f\u043e\u043a\u0430 \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">constructor(private canvasPostService: CanvasPostService) { }  \u00a0getSaveCanvas(data: {}) {  \u00a0\u00a0\u00a0this.canvasPostService.create(data as CanvasPostInterface)      .subscribe(respons=>{   \u00a0\u00a0\u00a0})  \u00a0}<\/code><\/pre>\n<p>\u0432 canvas.component.html \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u043d \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-card-4\"> \u00a0&lt;div class=\"w3-container w3-center\"> \u00a0\u00a0\u00a0&lt;label for=\"colorWell\">&lt;\/label>     \u00a0\u00a0\u00a0&lt;input list=\"\" id=\"colorWell\" type=\"color\" name=\"colorRect\"            [(ngModel)]=\"colorRect\">  \u00a0\u00a0\u00a0&lt;button (click)=\"create()\">\u0412\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043e\u043a&lt;\/button> \u00a0\u00a0\u00a0&lt;button (click)=\"clearPixel()\">\u0417\u0430\u0434\u0430\u0442\u044c \u043f\u0438\u043a\u0441\u0435\u043b\u044e \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430&lt;\/button> \u00a0\u00a0\u00a0&lt;button (click)=\"save()\">\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e&lt;\/button>  \u00a0&lt;\/div> &lt;\/div>  &lt;div class=\"w3-card-4 layer\"> \u00a0&lt;div class=\"w3-container w3-center\">     \u00a0\u00a0\u00a0&lt;canvas id=\"canvas\" #canvas>&lt;\/canvas>     \u00a0&lt;\/div> &lt;\/div><\/code><\/pre>\n<p><strong>\u0432 canvas.component.ts <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 save  \u0433\u0434\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 pagesEventSave \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434  <strong>getSaveCanvas()<\/strong> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <strong>main-canvas <\/strong>\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0430\u0437\u0443, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0435\u0433\u043e \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">@Output() pagesEventSave: EventEmitter&lt;{}>=new EventEmitter&lt;{}>(); \/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e name name: string; \/\/\u0432 \u043c\u0435\u0442\u043e\u0434 onResize() \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c this.name = data.name;   onResize(data: any) {     this.name = data.name;     this.innerWidth = data.innerWidth;     this.innerHeight = data.innerHeight;     this.widthRect = data.widthRect;     this.heightRect = data.heightRect;     this.numberOf = data.numberOf;     this.borderRow = data.borderRow;     this.numberRow = data.numberRow;     this.canvas.width = this.innerWidth;     this.canvas.height = this.innerHeight     this.colorfillStyle = data.colorfillStyle;     this.cleardraw()     this.draw()   } \/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u00a0save() { \u00a0\u00a0\u00a0const data = this.canvas?.toDataURL(); \u00a0\u00a0\u00a0this.pagesEventSave.emit({image: data, name: this.name,                               canvas: this.matr}); \u00a0}  <\/code><\/pre>\n<p>\u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 app.module.ts \u043c\u043e\u0434\u0443\u043b\u044c <strong>HttpClientModule<\/strong><\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c\u00a0 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0434\u043b\u044f \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043c\u0430\u0441\u0441\u0438\u0432 <strong>matr, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c JSON.stringify()<\/strong>\u00a0<\/p>\n<pre><code class=\"javascript\">this.pagesEventSave.emit({ image: data, name: this.name, canvas: JSON.stringify(this.matr) });<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p><strong>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0430\u0439\u0434\u0435\u0440.<\/strong><\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>ng g c canvas\/components\/slider<\/strong>\u00a0<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 assets \u043a\u0430\u0442\u0430\u043b\u043e\u0433 images, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <strong>slider.components.html<\/strong><\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-content w3-display-container\">  \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/1.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/2.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/3.webp\" style=\"width:400px\"> \u00a0&lt;img class=\"mySlides\" src=\"assets\/images\/4.webp\" style=\"width:400px\">   \u00a0&lt;button class=\"w3-button w3-black w3-display-left\" (click)=\"plusDivs(-1)\">    &amp;#10094;   &lt;\/button> \u00a0&lt;button class=\"w3-button w3-black w3-display-right\" (click)=\"plusDivs(1)\">    &amp;#10095;   &lt;\/button>  &lt;\/div><\/code><\/pre>\n<p>\u00a0\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <strong>slider.components.ts<\/strong><\/p>\n<p>\u00a0<\/p>\n<pre><code class=\"cs\">import { Component, AfterViewInit } from '@angular\/core';   @Component({  selector: 'app-slider',  templateUrl: '.\/slider.component.html',  styleUrls: ['.\/slider.component.scss'] }) export class SliderComponent implements AfterViewInit {    slideIndex = 1;  constructor(private elementRef: ElementRef) { }    ngAfterViewInit(): void {    this.showDivs(this.slideIndex);  }    plusDivs(n: number) {    this.showDivs(this.slideIndex += n);  }    showDivs(n: number) {    console.log(n)    let i;    let x = document.getElementsByClassName(\"mySlides\");    if (n > x.length) {      this.slideIndex = 1    }    if (n &lt; 1) { this.slideIndex = x.length }    for (i = 0; i &lt; x.length; i++) {      (x[i] as HTMLElement).style.display = \"none\";    }    (x[this.slideIndex - 1] as HTMLElement).style.display = \"block\";  } }   \/*\u043c\u0435\u0442\u043e\u0434 showDivs(n: number) \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e getElementsByClassName \u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e @ElementRef  \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 showDivsRef(n: number) \u0433\u0434\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c  ElementRef \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0432\u043d\u0435\u0434\u0440\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c  constructor(private elementRef: ElementRef) { }  *\/    showDivsRef(n: number) {     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c document.getElementsByClassName     let i;     let element = this.elementRef.nativeElement.getElementsByClassName(\"mySlides\");     console.log(n, element)     if (n > element.length) {       this.slideIndex = 1     }      if (n &lt; 1) { this.slideIndex = element.length }     if (element.length) {       for (i = 0; i &lt; element.length; i++) {         element[i].style.display = \"none\";       }       element[this.slideIndex - 1].style.display = \"block\";     }   }   <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 left-panel.component.html \u043f\u043e\u0441\u043b\u0435 &lt;div class=&#187;w3-third&#187;><\/p>\n<pre><code class=\"xml\">&lt;div class=\"w3-white w3-text-grey w3-card-4\">    &lt;div class=\"w3-container\">      &lt;p class=\"w3-large\">&lt;b>&lt;i class=\"fa fa-asterisk fa-fw w3-margin-right w3-text-teal\">&lt;\/i>\u0413\u0430\u043b\u0435\u0440\u0435\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432&lt;\/b>      &lt;\/p>      &lt;app-slider>&lt;\/app-slider>      &lt;hr>    &lt;\/div>  &lt;\/div>&lt;br> <\/code><\/pre>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/strong><\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c Mock.service \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 canvas.modelMock.ts, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 <a href=\"https:\/\/github.com\/Gdymora\/pixel-art\" rel=\"noopener noreferrer nofollow\">git <\/a>, \u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0431\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">export class InMemoryCanvasModel {   get data() {    return this._data;  }  _data = [    {      _id: \u201d61f0f9ad70c1c74fafc641f0\u201d,      name: \"love\",      image: \"love\",      canvas: ['\u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u043c\u0435\u0441\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 git'], }]; } <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0448 <strong>canvas-post-mock.service.ts, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 <strong>main-canvas <\/strong>\u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441<strong> <\/strong>CanvasPostMockService<\/p>\n<pre><code class=\"cs\">import { InMemoryCanvasModel } from '..\/models\/mock\/canvas.modelMock';   @Injectable({  providedIn: 'root' }) export class CanvasPostMockService {  private readonly list;  private dataService: InMemoryCanvasModel;    constructor() {    this.dataService = new InMemoryCanvasModel();<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-328812","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/328812","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=328812"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/328812\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=328812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=328812"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=328812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}