{"id":256698,"date":"2015-05-06T15:12:02","date_gmt":"2015-05-06T11:12:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=256698"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=256698","title":{"rendered":"\u0417\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 Fabric.js. \u0427\u0430\u0441\u0442\u044c 4-\u044f"},"content":{"rendered":"<p>     \t<i>\u042d\u0442\u043e \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043e\u0431 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 Javascript canvas \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Fabric.js.<\/i><\/p>\n<p>  \u041c\u044b \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e\u0435 \u0437\u043d\u0430\u0435\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0435\u0440\u0438\u0438: (<a href=\"http:\/\/habrahabr.ru\/post\/162367\/\">\u04271<\/a>, <a href=\"http:\/\/habrahabr.ru\/post\/167119\/\">\u04272<\/a>, <a href=\"http:\/\/habrahabr.ru\/post\/254763\/\">\u04273<\/a>) \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u0434\u043e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0439, \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0433\u0440\u0443\u043f\u043f \u0438 \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u041d\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u043e\u0438\u0442\u044c \u043e\u0441\u0432\u0435\u0442\u0438\u0442\u044c.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  \u0412 \u0447\u0435\u043c <code>&lt;canvas&gt;<\/code> \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u0443\u0441\u043f\u0435\u043b, \u0442\u0430\u043a \u044d\u0442\u043e \u0432 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f. Canvas \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 2D \u0431\u0438\u0442\u043c\u0430\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043b\u0438\u0446\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0431\u0443\u043c\u0430\u0433\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u2014 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0432 Fabric \u044d\u0442\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0443\u0447\u0442\u0435\u043d\u0430.<\/p>\n<p>  \u0420\u0435\u0436\u0438\u043c \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c, \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code> \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <code>isDrawingMode<\/code> \u043d\u0430 Fabric canvas. \u0421 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u0441\u0435 \u043a\u043b\u0438\u043a\u0438 \u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u0438 \u043d\u0430 canvas \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u0438\u0441\u0442\u0438\/\u043a\u0430\u0440\u0430\u043d\u0434\u0430\u0448\u0430.<\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0430 canvas \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0436\u0435\u043b\u0430\u0435\u0442\u0435, \u043f\u043e\u043a\u0430 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 <code>isDrawingMode<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u0442\u0435 \u043b\u044e\u0431\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u044b\u0448\u0438, \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u043c \u00abmouseup\u00bb, Fabric \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u00abpath:created\u00bb, \u0447\u0442\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 <code>fabric.Path<\/code> \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0432\u0435\u0440\u043d\u0435\u0442\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <code>isDrawingMode<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>, \u0442\u043e \u0432\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u043d\u0430 canvas. \u0422\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b <code>fabric.Path<\/code> \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e: \u0434\u0432\u0438\u0433\u0430\u0442\u044c, \u043a\u0440\u0443\u0442\u0438\u0442\u044c, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0442.\u0434. <\/p>\n<p>  \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f: <code>freeDrawingBrush.color<\/code> \u0438 <code>freeDrawingBrush.width<\/code>. \u041e\u0431\u0430 \u044d\u0442\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 <code>freeDrawingBrush<\/code>, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u043c\u0441\u044f \u043d\u0430 Fabric canvas. <code>freeDrawingBrush.color<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0446\u0432\u0435\u0442 \u043a\u0438\u0441\u0442\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c. <code>freeDrawingBrush.width<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043a\u0438\u0441\u0442\u0438.<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/50f\/50e\/0c1\/50f50e0c1fafe0d8f78fbfa68fdd8467.png\" alt=\"image\"\/><br \/>  \u0412 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \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 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0434\u043b\u044f \u043a\u0438\u0441\u0442\u0435\u0439, \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u0432. \u041d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438 \u0443 Fabric image.<\/p>\n<h2>\u041a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  \u0413\u043e\u0432\u043e\u0440\u044f \u043e Fabric, \u043d\u0435\u043b\u044c\u0437\u044f \u043d\u0435 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0435\u0435 \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u043f\u0446\u0438\u0439 \u043d\u0430 canvas, \u0438\u043b\u0438 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 canvas, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u044d\u0442\u0438\u0445 \u043e\u043f\u0446\u0438\u0439.<\/p>\n<h4>\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/h4>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 canvas \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438. \u00ablockMovementX\u00bb, \u00ablockMovementY\u00bb, \u00ablockRotation\u00bb, \u00ablockScalingX\u00bb \u0438 \u00ablockScalingY\u00bb \u2013 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <code>object.lockMovementX<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>, \u0442\u043e \u044d\u0442\u043e \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0436\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f. \u0422\u0430\u043a\u0438\u043c \u0436\u0435 \u043e\u0431\u0440\u0430\u0437\u043e\u043c <code>lockRotation<\/code> \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435, \u0430 <code>lockScalingX\/lockScalingY<\/code> \u2014 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430, \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435 \u0438\u043b\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.<\/p>\n<h4>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u043c\u043e\u043a, \u0443\u0433\u043e\u043b\u043a\u043e\u0432<\/h4>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0440\u0430\u043c\u043e\u043a \u0438 \u0443\u0433\u043e\u043b\u043a\u043e\u0432 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u00abhasControls\u00bb \u0438 \u00abhasBorders\u00bb. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>, \u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0442\u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u00ab\u0433\u043e\u043b\u044b\u043c\u00bb.  <\/p>\n<pre><code class=\"javascript\">object.hasBorders = false; <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/fb2\/f69\/46f\/fb2f6946fd7717a7828b4674ba005fe2.png\" alt=\"image\"\/>  <\/p>\n<pre><code class=\"javascript\">object.hasControls = false; <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/3c0\/9a1\/641\/3c09a16418bdd7a5d6f2d89ad7519c73.png\" alt=\"image\"\/><br \/>  \u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u00abborderColor\u00bb, \u00abcornerColor\u00bb, \u0438 \u00abcornerSize\u00bb.  <\/p>\n<pre><code class=\"javascript\">object.set({   borderColor: 'red',   cornerColor: 'green',   cornerSize: 6 }); <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/bf9\/8bd\/a32\/bf98bda329d6b715e5fb1d3516b7b8b6.png\" alt=\"image\"\/>  <\/p>\n<h4>\u041e\u0442\u043c\u0435\u043d\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0437\u0430\u0434\u0430\u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u00abselection\u00bb \u043d\u0430 canvas \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>. \u042d\u0442\u043e \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0441\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043d\u0430 canvas. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435, \u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c \u0432 \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u00abselectable\u00bb \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>. \u0422\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442 \u0441\u0432\u043e\u044e \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c.<\/p>\n<h4>\u041a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0410 \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435, \u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435? \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<br \/>  \u0415\u0441\u0442\u044c 4 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 canvas, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430 \u044d\u0442\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u2014 \u00abselectionColor\u00bb, \u00abselectionBorderColor\u00bb, \u00abselectionLikeWidth\u00bb, \u0438 \u00abselectionDashArray\u00bb. \u0418\u0445 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432 \u0446\u0435\u043b\u043e\u043c, \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e. \u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440:  <\/p>\n<pre><code class=\"javascript\">canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 }));  canvas.selectionColor = 'rgba(0,255,0,0.3)'; canvas.selectionBorderColor = 'red'; canvas.selectionLineWidth = 5; <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/6bf\/fa5\/5eb\/6bffa55eb762c74545b729b4dc82e96e.png\" alt=\"image\"\/><br \/>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u2014 \u00abselectionDashArray\u00bb \u2013 \u043d\u0435 \u0442\u0430\u043a\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435. \u041e\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0438\u043d\u0438\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u044b\u043c\u0438. \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u0430\u044f \u0447\u0435\u0440\u0442\u0430 \u0441\u043c\u0435\u043d\u044f\u0435\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e <code>[10, 5]<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u00abselectionDashArray\u00bb. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043b\u0438\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u043e\u0439 \u0432 10px, \u0437\u0430\u0442\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0441\u0442\u0443\u043f \u0432 5px, \u0441\u043d\u043e\u0432\u0430 \u043b\u0438\u043d\u0438\u044f, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 <code>[2, 4, 6]<\/code>, \u0442\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0442\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 2px, \u0437\u0430\u0442\u0435\u043c \u043e\u0442\u0441\u0442\u0443\u043f \u0432 4px, \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043d\u043e\u0432\u0430 \u0447\u0435\u0440\u0442\u0430, \u043d\u043e \u0443\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 6px \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c <code>[5, 10]<\/code>:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/574\/a6e\/b88\/574a6eb88e442a6cbd846f910c0dc045.png\" alt=\"image\"\/>  <\/p>\n<h4>\u041f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u0430\u044f \u043e\u0431\u0432\u043e\u0434\u043a\u0430<\/h4>\n<p>  \u0421\u0445\u043e\u0436\u0435 \u0441 \u00abselectionDashArray\u00bb \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043d\u0430 canvas, \u0432\u0441\u0435 Fabric \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043c\u0435\u044e\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u00abstrokeDashArray\u00bb, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0435 \u0437\u0430 \u043f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043d\u0430 \u043e\u0431\u0432\u043e\u0434\u043a\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430.  <\/p>\n<pre><code class=\"javascript\">var rect = new fabric.Rect({   fill: '#06538e',   width: 125,   height: 125,   stroke: 'red',   strokeDashArray: [5, 5] }); canvas.add(rect); <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/9a3\/2c8\/fca\/9a32c8fcaeaca4b7f54064c91bdf76fd.png\" alt=\"image\"\/>  <\/p>\n<h4>\u041a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u043e\u043d\u0430<\/h4>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u0442\u0435, \u0432\u0441\u0435 Fabric \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043c\u0435\u044e\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0440\u0430\u043c\u043a\u0438\/\u0443\u0433\u043e\u043b\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442. \u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u043d\u0430\u0436\u0438\u043c\u0430\u044f \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043f\u0443\u0441\u0442\u043e\u0435. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0438\u0436\u0435:<br \/>  <img decoding=\"async\" src=\"\/\/habrastorage.org\/files\/208\/95f\/1cc\/20895f1cce4d41498813ec19375e9daa.png\"\/><\/p>\n<p>  \u041f\u0440\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0432\u0441\u0435 Fabric \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430 canvas \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e: \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u00abperPixelTargetFind\u00bb \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>.<\/p>\n<h4>\u0412\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/h4>\n<p>  <b>\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.0<\/b> Fabric \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0435 UI. \u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0440\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445, \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0435 \u0437\u0430 \u044d\u0442\u043e\u0442 \u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u2014 \u00abhasRotatingPoint\u00bb. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u044d\u0442\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u00abrotatingPointOffset\u00bb.<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/7a9\/d57\/d24\/7a9d57d244c4f0f03348eb165b334c68.png\" alt=\"image\"\/>  <\/p>\n<h4>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/h4>\n<p>  \u0422\u0430\u043a\u0436\u0435, <b>\u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.0<\/b>, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u044f\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041e\u0434\u043d\u043e \u0438\u0437 \u043d\u0438\u0445 \u2014 \u00abuniScaleTransform\u00bb \u043d\u0430 canvas. \u041f\u0440\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445, \u0432 \u044d\u0442\u043e\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>. \u041e\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u0438, \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u044f \u0437\u0430 \u0443\u0433\u043e\u043b\u043a\u0438.<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/a86\/c0b\/27c\/a86c0b27c94b135745bdb92e22bddc0c.png\" alt=\"image\"\/><br \/>  \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u00abcenteredScaling\u00bb \u0438 \u00abcenteredRotation\u00bb (\u0414\u043e \u0432\u0435\u0440\u0441\u0438\u0438 1.3.4 \u0431\u044b\u043b\u043e \u043e\u0434\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u2014 \u00abcenterTransform\u00bb). \u041e\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u0434\u043e\u043b\u0436\u043d\u0430 \u043b\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0446\u0435\u043d\u0442\u0440\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041a\u043e\u0433\u0434\u0430 \u043e\u0431\u0430 \u043e\u043d\u0438 <code>true<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u044b\u043b\u043e \u0434\u043e \u0432\u0435\u0440\u0441\u0438\u0438 1.0, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c\/\u0432\u0440\u0430\u0449\u0430\u043b\u0438\u0441\u044c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0432\u043e\u0435\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.0. \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043b\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u0430\u0440\u0430 \u043d\u043e\u0432\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u044d\u0442\u043e \u00aboriginX\u00bb \u0438 \u00aboriginY\u00bb. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0432 \u043d\u0438\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u00ableft\u00bb \u0438 \u00abtop\u00bb. \u041e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0437\u0430 \u0443\u0433\u043e\u043b\u043a\u0438, \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u00ab\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c\u00bb.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u0436\u0435 \u043d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0430\u0431\u043e\u0442\u0430\u044f \u0441 \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0435 \u0442\u0435\u043a\u0441\u0442, \u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u00aboriginX\u00bb \u0438 \u00aboriginY\u00bb \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0443\u0434\u0430 \u0440\u0430\u0441\u0442\u0438 \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442, \u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 originX \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u00abcenter\u00bb. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0431\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u043a \u043f\u0440\u0430\u0432\u043e\u043c\u0443 \u043a\u0440\u0430\u044e \u2013 \u0441\u0442\u0430\u0432\u0438\u043c originX \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u00abright\u00bb \u0438 \u0442.\u0434. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u00abposition: absolute\u00bb \u0432 CSS.<\/p>\n<h4>\u0417\u0430\u0434\u043d\u0438\u0439 \u0444\u043e\u043d \u0438 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u0435 \u043d\u0430 canvas<\/h4>\n<p>  \u041a\u0430\u043a \u0432\u044b, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u0438\u0437 <a href=\"http:\/\/habrahabr.ru\/post\/162367\/\">1-\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438<\/a>, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0446\u0432\u0435\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u0437\u0430\u0434\u043d\u0435\u0433\u043e \u0444\u043e\u043d\u0430 canvas. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u00abbackgroundColor\u00bb.  <\/p>\n<pre><code class=\"javascript\">canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 })); canvas.backgroundColor = 'rgba(0,0,255,0.3)'; canvas.renderAll(); <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/4ac\/73c\/e38\/4ac73ce38109378aa465dc3d475d0e49.png\" alt=\"image\"\/><\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0439\u0442\u0438 \u0435\u0449\u0435 \u0434\u0430\u043b\u044c\u0448\u0435, \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u0434\u043d\u0438\u043c \u0444\u043e\u043d\u043e\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>setBackgroundImage<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 url \u0438 \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u043d\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.  <\/p>\n<pre><code class=\"javascript\">canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 })); canvas.setBackgroundImage('..\/assets\/pug.jpg', canvas.renderAll.bind(canvas)); <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/63d\/eaa\/f1a\/63deaaf1a85fd63ac0e57a697cf8e59b.png\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u044f. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 canvas. \u041f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>setOverlayImage<\/code>, \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 \u043e\u043f\u0446\u0438\u044f\u043c\u0438: url, \u0438 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u043e\u043c \u043d\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.  <\/p>\n<pre><code class=\"javascript\">canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 })); canvas.setOverlayImage('..\/assets\/jail_cell_bars.png', canvas.renderAll.bind(canvas)); <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/27c\/619\/d85\/27c619d85f94f92a9051cd46e4bc1488.png\" alt=\"image\"\/><\/p>\n<h2>Fabric \u043d\u0430 Node.js<\/h2>\n<p>  \u041e\u0434\u0438\u043d \u0438\u0437 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432 Fabric \u2013 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0441 \u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u043d\u043e \u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435! \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0418\u043b\u0438 \u0432\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Fabric API \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0436\u0435 \u043f\u043e \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 Node, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u043c Fabric. <br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c <a href=\"http:\/\/nodejs.org\/\">Node.js<\/a>, \u0435\u0441\u043b\u0438 \u043e\u043d \u0443 \u0432\u0430\u0441 \u0435\u0449\u0435 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043e\u043d\u0438 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/howtonode.org\/how-to-install-nodejs\">\u044d\u0442\u0438\u043c<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/joyent\/node\/wiki\/Installation\">\u044d\u0442\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c<\/a>. <\/p>\n<p>  \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 Node.js, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/LearnBoost\/node-canvas\">node-canvas<\/a>. \u042d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u2013 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f canvas \u0434\u043b\u044f NodeJS. \u041e\u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <a href=\"http:\/\/cairographics.org\/\">Cairo<\/a> \u2014 2D \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0439 \u043d\u0430 Mac, Linux, \u0438\u043b\u0438 Windows. node-canvas \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 <a href=\"https:\/\/github.com\/LearnBoost\/node-canvas\/wiki\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0442\u0438\u043f\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<p>  Fabric \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0430 Node \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 (NPM). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u2013 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c NPM. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 <a href=\"https:\/\/github.com\/isaacs\/npm\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 github<\/a>. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0448\u0430\u0433 \u2013 \u044d\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<a href=\"https:\/\/npmjs.org\/package\/fabric\"> Fabric package<\/a>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f NPM. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0432 <code>npm install fabric<\/code> (\u0438\u043b\u0438 <code>npm install -g fabric<\/code> \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438). \u041a \u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0443 \u043d\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 node-canvas \u0438 Fabric:  <\/p>\n<pre><code class=\"javascript\">&gt; node ... &gt; typeof require('canvas'); \/\/ &quot;function&quot; &gt; typeof require('fabric'); \/\/ &quot;object&quot; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u00abhello world\u00bb \u0442\u0435\u0441\u0442. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c helloworld.js \u0444\u0430\u0439\u043b.  <\/p>\n<pre><code class=\"javascript\">var fs = require('fs'),     fabric = require('fabric').fabric,     out = fs.createWriteStream(__dirname + '\/helloworld.png');  var canvas = fabric.createCanvasForNode(200, 200); var text = new fabric.Text('Hello world', {   left: 100,   top: 100,   fill: '#f55',   angle: 15 }); canvas.add(text);  var stream = canvas.createPNGStream(); stream.on('data', function(chunk) {   out.write(chunk); }); <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u044d\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>node helloworld.js<\/code>. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0435\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 helloworld.png \u0432\u044b\u0434\u0430\u0441\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/58c\/84e\/6b3\/58c84e6b30b220b784dcdbb667ed02ea.png\" alt=\"image\"\/><br \/>  \u0427\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434.<\/p>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0438 Fabric (<code>fabric = require('fabric').fabric<\/code>). \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439-\u0434\u043e\u0431\u0440\u044b\u0439 Fabric canvas, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432 <code>fabric.createCanvasForNode<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e <code>new fabric.Canvas()<\/code>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0448\u0438\u0440\u0438\u043d\u0443 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 canvas \u0441 \u044d\u0442\u0438\u043c\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u043c\u0438 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 200\u0445200). <\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 (<code>new fabric.Text()<\/code>) \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430 canvas (<code>canvas.add(text)<\/code>).<\/p>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0441\u0442 Fabric canvas, \u0438 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u0442 \u043d\u0430 \u043d\u0435\u043c \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442. \u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u0430\u043a \u043d\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e canvas? \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>createPNGStream<\/code> \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 canvas. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u0435\u0440\u043d\u0435\u0442 \u043d\u0430\u043c \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u0434\u043b\u044f Node <a href=\"http:\/\/nodejs.org\/api\/stream.html\">stream \u043e\u0431\u044a\u0435\u043a\u0442<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>on('data')<\/code>, \u0438 (<code>fs.createWriteStream()<\/code>), \u0447\u0442\u043e \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u0444\u0430\u0439\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  <code>fabric.createCanvasForNode<\/code> \u0438 <code>fabric.Canvas#createPNGStream<\/code> \u2013 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Node. \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443: \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438 \u0442.\u0434. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 canvas \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>createCanvasForNode<\/code>, canvas \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c <code>nodeCanvas<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 node-canvas \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<h4>Node \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 Fabric<\/h4>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Node \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 Fabric \u0432 JSON \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0438 \u043e\u0442\u0441\u044b\u043b\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0437\u0430\u0439\u043c\u0435\u0442 \u0432\u0441\u0435\u0433\u043e 25 \u0441\u0442\u0440\u043e\u043a!   <\/p>\n<pre><code class=\"javascript\">var fabric = require('fabric').fabric,     http = require('http'),     url = require('url'),     PORT = 8124;  var server = http.createServer(function (request, response) {   var params = url.parse(request.url, true);   var canvas = fabric.createCanvasForNode(200, 200);    response.writeHead(200, { 'Content-Type': 'image\/png' });    canvas.loadFromJSON(params.query.data, function() {     canvas.renderAll();      var stream = canvas.createPNGStream();     stream.on('data', function(chunk) {       response.write(chunk);     });     stream.on('end', function() {       response.end();     });   }); });  server.listen(PORT); <\/code><\/pre>\n<p>  \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0440\u044b\u0432\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u0439. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0443\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c Fabric canvas, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430 \u043d\u0435\u0433\u043e JSON \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0438 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<br \/>  \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0443\u0433\u043b\u043e\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430.  <\/p>\n<pre><code class=\"javascript\">{&quot;objects&quot;:[{&quot;type&quot;:&quot;rect&quot;,&quot;left&quot;:103.85,&quot;top&quot;:98.85,&quot;width&quot;:50,&quot;height&quot;:50,&quot;fill&quot;:&quot;#9ae759&quot;,&quot;overlayFill&quot;:null,&quot;stroke&quot;:null,&quot;strokeWidth&quot;:1,&quot;strokeDashArray&quot;:null,&quot;scaleX&quot;:1.39,&quot;scaleY&quot;:1.39,&quot;angle&quot;:30,&quot;flipX&quot;:false,&quot;flipY&quot;:false,&quot;opacity&quot;:0.8,&quot;selectable&quot;:true,&quot;hasControls&quot;:true,&quot;hasBorders&quot;:true,&quot;hasRotatingPoint&quot;:false,&quot;transparentCorners&quot;:true,&quot;perPixelTargetFind&quot;:false,&quot;rx&quot;:0,&quot;ry&quot;:0}],&quot;background&quot;:&quot;rgba(0, 0, 0, 0)&quot;} <\/code><\/pre>\n<p>  URI \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442 \u044d\u0442\u043e:  <\/p>\n<pre><code class=\"javascript\">%7B&quot;objects&quot;%3A%5B%7B&quot;type&quot;%3A&quot;rect&quot;%2C&quot;left&quot;%3A103.85%2C&quot;top&quot;%3A98.85%2C&quot;width&quot;%3A50%2C&quot;height&quot;%3A50%2C&quot;fill&quot;%3A&quot;%239ae759&quot;%2C&quot;overlayFill&quot;%3Anull%2C&quot;stroke&quot;%3Anull%2C&quot;strokeWidth&quot;%3A1%2C&quot;strokeDashArray&quot;%3Anull%2C&quot;scaleX&quot;%3A1.39%2C&quot;scaleY&quot;%3A1.39%2C&quot;angle&quot;%3A30%2C&quot;flipX&quot;%3Afalse%2C&quot;flipY&quot;%3Afalse%2C&quot;opacity&quot;%3A0.8%2C&quot;selectable&quot;%3Atrue%2C&quot;hasControls&quot;%3Atrue%2C&quot;hasBorders&quot;%3Atrue%2C&quot;hasRotatingPoint&quot;%3Afalse%2C&quot;transparentCorners&quot;%3Atrue%2C&quot;perPixelTargetFind&quot;%3Afalse%2C&quot;rx&quot;%3A0%2C&quot;ry&quot;%3A0%7D%5D%2C&quot;background&quot;%3A&quot;rgba(0%2C%200%2C%200%2C%200)&quot;%7D <\/code><\/pre>\n<p>  \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u00abdata\u00bb. \u041d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0441 \u0442\u0438\u043f\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u00abimage\/png\u00bb \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/c88\/0b4\/8f0\/c880b48f04a503a88383a991ee67ef2e.png\" alt=\"image\"\/><br \/>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 Fabric \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043f\u043e\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c, \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440\u044b canvas, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0438\u043b\u0438 \u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430.<\/p>\n<h4>\u0428\u0440\u0438\u0444\u0442\u044b \u0432 Fabric \u043d\u0430 Node<\/h4>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0440\u0438\u0444\u0442\u044b \u043d\u0430 Fabric, \u043d\u0443\u0436\u043d\u043e \u0438\u0445 \u0441\u043f\u0435\u0440\u0432\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c. \u0421\u0430\u043c\u044b\u0439 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0448\u0440\u0438\u0444\u0442\u044b \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (\u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430) \u2013 \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/www.w3.org\/TR\/css3-fonts\/#font-face-rule\">CSS3  @font-face rule<\/a>. \u0412 Fabric \u043d\u0430 Node (\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430) \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c node-canvas <b>Font API<\/b>, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0448\u0440\u0438\u0444\u0442\u044b \u0441 \u043d\u0435\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0439 \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e. <\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442, \u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0440\u0438\u0444\u0442\u044b. \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0435\u0433\u043e \u0432 \u0444\u0430\u0438\u043b customfont.js, \u0443\u0431\u0435\u0434\u0438\u0432\u0448\u0438\u0441\u044c, \u0447\u0442\u043e \u043f\u0443\u0442\u0438 \u0434\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0448\u0440\u0438\u0444\u0442\u043e\u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0448\u0440\u0438\u0444\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.google.com\/fonts\/specimen\/Ubuntu\">Ubuntu<\/a>.   <\/p>\n<pre><code class=\"javascript\">var fs = require('fs'),     fabric = require('fabric').fabric,     canvas = fabric.createCanvasForNode(300, 250);  var font = new canvas.Font('Ubuntu', __dirname + '\/fonts\/Ubuntu-Regular.ttf'); font.addFace(__dirname + '\/fonts\/Ubuntu-Bold.ttf', 'bold'); font.addFace(__dirname + '\/fonts\/Ubuntu-Italic.ttf', 'normal', 'italic'); font.addFace(__dirname + '\/fonts\/Ubuntu-BoldItalic.ttf', 'bold', 'italic');  canvas.contextContainer.addFont(font);  \/\/ \u0434\u043b\u044f createPNGStream \u0438\u043b\u0438 createJPEGStream \/\/canvas.contextTop.addFont(font);      \/\/ \u0434\u043b\u044f toDataURL \u0438\u043b\u0438 toDataURLWithMultiplier  var text = new fabric.Text('regular', {     left: 150,     top: 50,     fontFamily: 'Ubuntu' }); canvas.add(text);  text = new fabric.Text('bold', {     left: 150,     top: 100,     fontFamily: 'Ubuntu',     fontWeight: 'bold' }); canvas.add(text);  text = new fabric.Text('italic', {     left: 150,     top: 150,     fontFamily: 'Ubuntu',     fontStyle: 'italic' }); canvas.add(text);  text = new fabric.Text('bold italic', {     left: 150,     top: 200,     fontFamily: 'Ubuntu',     fontWeight: 'bold',     fontStyle: 'italic' }); canvas.add(text);  var out = fs.createWriteStream(__dirname + '\/customfont.png'); var stream = canvas.createPNGStream(); stream.on('data', function(chunk) {     out.write(chunk); }); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>node customfont.js<\/code>, \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (customfont.png) \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/getpro\/habr\/post_images\/54d\/3ed\/1be\/54d3ed1be1d502c22d19011a20da163c.png\" alt=\"image\"\/><\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u0448\u0440\u0438\u0444\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>new canvas.Font()<\/code>, \u0443\u043a\u0430\u0437\u0430\u0432 \u0438\u043c\u044f (<code>name<\/code>) \u0438 \u043f\u0443\u0442\u044c (<code>path<\/code>) \u043a \u0444\u0430\u0439\u043b\u0443 \u0441\u043e \u0448\u0440\u0438\u0444\u0442\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0417\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 font-faces, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 <code>font.addFace()<\/code>. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0443\u0442\u044c (<code>path<\/code>), \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u044c (<code>weight<\/code>) \u0438 \u0441\u0442\u0438\u043b\u044c (<code>style<\/code>). \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0448\u0440\u0438\u0444\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432 \u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e. \u041c\u044b \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>canvas.contextContainer.addFont()<\/code> (\u0434\u043b\u044f <b>createPNGStream<\/b> \u0438\u043b\u0438 <b>createJPEGStream<\/b>), \u0438\u043b\u0438 <code>canvas.contextTop.addFont()<\/code> (\u0434\u043b\u044f <b>toDataURL<\/b> \u0438\u043b\u0438 <b>toDataURLWithMultiplier<\/b>).<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0448\u0440\u0438\u0444\u0442, \u0437\u0430\u0434\u0430\u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <b>fontFamily<\/b> \u043d\u0430 <code>fabric.Text<\/code> \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0448\u0440\u0438\u0444\u0442\u0430. \u0412 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 <b>fontWeight<\/b> \u0438 <b>fontStyle<\/b> \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c font faces, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0432\u043e <a href=\"http:\/\/habrahabr.ru\/post\/167119\/\">2-\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438<\/a>. <\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0440\u0438\u0444\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043d\u043e\u0432\u044b\u0435 \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 JSON.<\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0438\u044f \u0438\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 Fabric. \u042f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u043d\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u043a\u0440\u0443\u0442\u043e\u0435, \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435, \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0435\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0435!<\/p>\n<p>  <a href=\"http:\/\/fabricjs.com\/fabric-intro-part-4\/\"><i>\u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438<\/i>.<br \/>  <\/a>     \t<\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/257401\/\"> http:\/\/habrahabr.ru\/post\/257401\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \t<i>\u042d\u0442\u043e \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043e\u0431 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 Javascript canvas \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Fabric.js.<\/i><\/p>\n<p>  \u041c\u044b \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e\u0435 \u0437\u043d\u0430\u0435\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0435\u0440\u0438\u0438: (<a href=\"http:\/\/habrahabr.ru\/post\/162367\/\">\u04271<\/a>, <a href=\"http:\/\/habrahabr.ru\/post\/167119\/\">\u04272<\/a>, <a href=\"http:\/\/habrahabr.ru\/post\/254763\/\">\u04273<\/a>) \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u0434\u043e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0439, \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0433\u0440\u0443\u043f\u043f \u0438 \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u041d\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u043e\u0438\u0442\u044c \u043e\u0441\u0432\u0435\u0442\u0438\u0442\u044c.  <\/p>\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-256698","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/256698","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=256698"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/256698\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=256698"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=256698"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=256698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}