{"id":470067,"date":"2025-08-08T15:01:22","date_gmt":"2025-08-08T15:01:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=470067"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=470067","title":{"rendered":"<span>Flutter: \u0418\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0443 Canvas\u2019\u0430 \u2014 \u0427\u0430\u0441\u0442\u044c 1<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Canvas\u00bb\u0430 Flutter, \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u00a0GPU \u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u0442\u043b\u0430\u0434\u043a\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u0432\u043e\u00a0Flutter \u0438\u043c\u0435\u0435\u0442 \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u044e \u043e\u0447\u0435\u043d\u044c\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0425\u043e\u0442\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432\u00a0Flutter Canvas API \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0432\u00a0\u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0437\u043d\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<p>\u0412\u00a0\u044d\u0442\u043e\u043c \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435, \u043d\u043e\u00a0\u0432\u00a0\u0442\u043e\u00a0\u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 Flutter\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 Canvas. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0443\u043c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f GPU, \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0432\u043d\u044b\u0435,\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b\u00a0\u2014 \u0434\u0430\u0436\u0435 \u0432\u00a0\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0445.<\/p>\n<h3>\u0427\u0435\u043c\u0443 \u0432\u044b \u043d\u0430\u0443\u0447\u0438\u0442\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435<\/h3>\n<ul>\n<li>\n<p><strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 Canvas:<br \/><\/strong>\u041a\u0430\u043a\u00a0\u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 (<code>CustomPaint<\/code>, \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 <code>RenderObject<\/code> \u0438\u043b\u0438 <code>LeafRenderObjectWidget<\/code>) \u0434\u043b\u044f\u00a0\u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430:<br \/><\/strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0433\u0438\u0431\u043a\u043e\u0439 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u0430\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u043c\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0430\u043a\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 GPU \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u043e\u0432 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438:<br \/><\/strong>\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0446\u0438\u043a\u043b\u043e\u0432 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 Flutter (<code>drawRawAtlas<\/code>, <code>drawRawPoints<\/code>, <code>drawVertices<\/code>) \u0434\u043b\u044f\u00a0\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e QuadTrees:<br \/><\/strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439, \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u043e\u0432 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 QuadTree \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u044e\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0441\u0446\u0435\u043d\u044b \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>GPU\u2011\u0448\u0435\u0439\u0434\u0435\u0440\u044b \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f Paint:<br \/><\/strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 \u0441\u00a0GPU\u2011\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435\u043c, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Paint\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430, \u0442\u0430\u043a \u0438 \u043c\u043e\u043b\u043d\u0438\u0435\u043d\u043e\u0441\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Picture \u0438 \u0440\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438:<br \/><\/strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>PictureRecorder<\/code> Flutter \u0434\u043b\u044f\u00a0\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u0438\u043b\u0438\u00a0\u0440\u0435\u0434\u043a\u043e \u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432 \u0432\u0430\u0448\u0435\u0439 \u0441\u0446\u0435\u043d\u044b, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430\u00a0\u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0434\u0435\u0436\u043d\u0430\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<br \/><\/strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043b\u043e\u044f \u0441\u00a0\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u043c \u043e\u0432\u0435\u0440\u043b\u0435\u0435\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u043e\u0440\u044f\u0447\u0438\u0445 \u043a\u043b\u0430\u0432\u0438\u0448 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <strong>F2<\/strong>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (FPS, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u00a0\u043a\u0430\u043c\u0435\u0440\u0435, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f QuadTree, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445). \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u043e\u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0438 \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435\u00a0\u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e\u00a0\u0432\u0430\u0448\u0435 Flutter\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 Canvas \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u043c, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u043c. \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u0442\u043e\u0433\u043e, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435\u00a0\u043b\u0438 \u0432\u044b \u0438\u0433\u0440\u044b, \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043b\u0438\u00a0\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u0432\u00a0\u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Flutter \u0434\u043b\u044f\u00a0\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>\u042d\u0442\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e \u0434\u043b\u044f\u00a0Flutter\u2011\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0438 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0440\u0435\u043c\u044f\u0442\u0441\u044f \u043a\u00a0\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 Canvas. \u041f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u0435\u043c \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0432\u0430\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u00a0\u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 Flutter, \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0441\u00a0Canvas\u00a0\u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442 \u0432\u0430\u0448\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c.<\/p>\n<hr\/>\n<h3>\u0412\u044b\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0430<\/h3>\n<p>\u041f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u0438\u043b\u0438\u00a0\u0432\u044b\u0441\u043e\u043a\u043e\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u043c\u0438 \u0432\u043e\u00a0Flutter \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u043c\u0435\u0435\u0442 \u0440\u0435\u0448\u0430\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0\u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u00a0\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a\u00a0\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430 CustomPaint \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f\u00a0\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u2011\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0438\u043b\u0438\u00a0\u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0447\u0430\u0441\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u0438 \u0441\u043e\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 Canvas\u00bb\u0430 \u0432\u043e\u00a0Flutter.<\/p>\n<p>Flutter \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0434\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439 \u043d\u0430\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u0435 (\u0445\u043e\u043b\u0441\u0442\u0435). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\"><strong>\u0412\u0438\u0434\u0436\u0435\u0442 \/ \u041f\u043e\u0434\u0445\u043e\u0434<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\"><strong>\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\"><strong>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">CustomPaint<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u041f\u0440\u043e\u0441\u0442\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0425\u043e\u0440\u043e\u0448\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u00a0\u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">LeafRenderObjectWidget<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 RePaint<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 CustomPaint<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u00a0\u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430 <code>CustomPaint<\/code>:<\/p>\n<pre><code class=\"dart\">dartCopyEditCustomPaint(   painter: MyCanvasPainter(), );<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u0448\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0438\u043b\u0438\u00a0\u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0438\u0437\u2011\u0437\u0430 \u0438\u0437\u043b\u0438\u0448\u043d\u0438\u0445 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d79d3ee88c0a9285d36d\" data-style=\"\" id=\"6895d79d3ee88c0a9285d36d\" width=\"\"><\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e LeafRenderObjectWidget<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u00a0\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438\u00a0\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u044e\u0442, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u0430 (render object), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>LeafRenderObjectWidget<\/code>. \u042d\u0442\u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439, \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u043e\u0439 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c:<\/p>\n<pre><code class=\"dart\">class CustomRenderBoxWidget extends LeafRenderObjectWidget {   \/\/ ...      @override   RenderObject createRenderObject(BuildContext context) {     final box = CustomRenderBox();     \/\/ ...     return box;   } }  class CustomRenderBox extends RenderBox with WidgetsBindingObserver {    \/\/ ...    \/\/\/ \u0442\u0438\u043a\u0435\u0440 \u0446\u0438\u043a\u043b\u0430 Vsync.   Ticker? _ticker;      @override   bool get isRepaintBoundary =&gt; true;    @override   bool get alwaysNeedsCompositing =&gt; false;    @override   bool get sizedByParent =&gt; true;      @override   Size computeDryLayout(BoxConstraints constraints) =&gt; constraints.biggest;      void _onTick(Duration elapsed) {     \/\/ ...     markNeedsPaint();   }      @override   void attach(PipelineOwner owner) {     super.attach(owner);     WidgetsBinding.instance.addObserver(this);     _ticker = Ticker(_onTick, debugLabel: 'CustomRenderBox')..start();     \/\/ ...   }      @override   void detach() {     _ticker?.dispose();     WidgetsBinding.instance.removeObserver(this);     super.detach();     \/\/ ...   }      @override   void paint(PaintingContext context, Offset offset) {     \/\/ ...   } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u00a0\u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0447\u0442\u043e\u00a0\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f\u00a0\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0445 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d825d5124fabc4a7ac51\" data-style=\"\" id=\"6895d825d5124fabc4a7ac51\" width=\"\"><\/div>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d833d5124fabc4a7ac61\" data-style=\"\" id=\"6895d833d5124fabc4a7ac61\" width=\"\"><\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 RePaint<\/h3>\n<p>\u0412\u00a0\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u0439 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pub.dev\/packages\/repaint?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">repaint<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f\u00a0\u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/RePaint-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0430\u0441\u0441 RePaint\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 repaint\u00a0\u2014 Dart API <\/a><\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/RePaint-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f API \u0434\u043b\u044f\u00a0\u043a\u043b\u0430\u0441\u0441\u0430 RePaint \u0438\u0437\u00a0\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 repaint \u0434\u043b\u044f\u00a0\u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Dart.<\/a><\/p>\n<pre><code class=\"dart\">final _painter = MyGamePainter();  @override Widget build(BuildContext context) =&gt; RePaint(     painter: _painter,   );    \/\/ ...  class MyGamePainter extends RePainterBase {   \/\/ ... }<\/code><\/pre>\n<h3>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u0440\u0430\u043d\u0438\u0446<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448 \u043a\u0430\u043d\u0432\u0430\u0441 \u0447\u0430\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442\u00a0\u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0433\u043e \u0435\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0432 \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u0435\u0440\u043d\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 <code>CustomPaint<\/code> \u0432 <code>RepaintBoundary<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043b\u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 <code>RenderObject<\/code>, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0434\u043b\u044f\u00a0\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>isRepaintBoundary <\/code>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"dart\">RepaintBoundary(   child: CustomPaint(     painter: MyFrequentlyUpdatedPainter(),   ), )<\/code><\/pre>\n<p>\u0425\u043e\u0442\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u00a0\u0441\u0447\u0435\u0442 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u0438 \u043f\u043b\u043e\u0449\u0430\u0434\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a, \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0432\u043b\u0435\u0447\u0435\u0442 \u0437\u0430\u00a0\u0441\u043e\u0431\u043e\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u0438\u0437\u2011\u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 GPU. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0430\u0436\u043d\u043e \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u00a0\u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d.<\/p>\n<h3>\u26a0\ufe0f \u041d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0439\u0442\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438\u043b\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u043e\u043c Flutter \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 (<code>CustomPaint<\/code>) \u0432\u043d\u0443\u0442\u0440\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438\u043b\u0438\u00a0\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>setState()<\/code>. \u0425\u043e\u0442\u044f \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u0438\u043b\u0438\u00a0\u0434\u0430\u0436\u0435 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u043c, \u043e\u043d \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a\u00a0\u043d\u0435\u043d\u0443\u0436\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0447\u0442\u043e\u00a0\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0434\u043b\u044f\u00a0\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u0445 \u0438\u043b\u0438\u00a0\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0446\u0435\u043d.<\/p>\n<p>\u0412\u043e\u0442 \u0447\u0435\u0433\u043e \ud83d\udeab <strong>\u043d\u0435\u00a0\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c <\/strong>\ud83d\udeab:<\/p>\n<pre><code class=\"dart\">AnimatedBuilder(   animation: animationController,   builder: (context, _) =&gt;       CustomPaint(painter: MyPainter()), );<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code class=\"dart\">BlocBuilder(   bloc: bloc,   builder: (context, state) =&gt;       CustomPaint(painter: MyPainter()), );<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code class=\"dart\">context.watch&lt;T&gt;(); return CustomPaint(painter: MyPainter());<\/code><\/pre>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0443\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e Flutter, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f <code>Listenable <\/code>(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>AnimationController<\/code>, <code>ChangeNotifier<\/code>) \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 repaint \u0432\u0430\u0448\u0435\u0433\u043e <code>CustomPainter<\/code>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"dart\">final animationController = AnimationController(   vsync: this,   duration: const Duration(seconds: 1), )..repeat();  CustomPaint(   \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 repaint   painter: MyPainter(repaint: animationController),  );<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430:<\/p>\n<pre><code class=\"dart\">class MyPainter extends CustomPainter {   MyPainter({required super.repaint});    @override   void paint(Canvas canvas, Size size) {     \/\/ \u0417\u0434\u0435\u0441\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438   }    @override   bool shouldRepaint(covariant MyPainter oldDelegate) =&gt; false; }<\/code><\/pre>\n<ul>\n<li>\n<p>Flutter \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443, \u0438\u0437\u0431\u0435\u0433\u0430\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0435\u043a \u0432\u0438\u0434\u0436\u0435\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u00a0setState() \u0438 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u0430\u043c\u0438 \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>RenderObject<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>CustomPainter<\/code>, \u0441\u0442\u0430\u0440\u0430\u0439\u0442\u0435\u0441\u044c \u043d\u0435\u00a0\u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>setState()<\/code> \u0438 \u043d\u0435\u00a0\u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u0431\u0435\u0437\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u044f\u0432\u043d\u043e \u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435<\/p>\n<pre><code class=\"dart\">RenderObject.markNeedsPaint();<\/code><\/pre>\n<p>\u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a\u00a0\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0438\u043b\u0438\u00a0\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u043d\u0430\u00a0\u0443\u0440\u043e\u0432\u043d\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0435\u00a0\u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 Flutter.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\ud83d\udeab \u0418\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435 \u044d\u0442\u043e\u0433\u043e&#8230;<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u2705 \u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u044d\u0442\u043e&#8230;<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0427\u0430\u0441\u0442\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>setState()<\/code> \u0434\u043b\u044f\u00a0\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 canvas\u00bb\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>repaint Listenable<\/code>.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 canvas\u00bb\u0430 \u0432 <code>AnimatedBuilder<\/code> \u0438\u043b\u0438\u00a0\u0431\u0438\u043b\u0434\u0435\u0440\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0439\u0442\u0435 <code>markNeedsPaint()<\/code> \u0438\u043b\u0438\u00a0repaint.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u0437\u043b\u0438\u0448\u043d\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0439\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0444\u0438\u0433\u0443\u0440 \u043d\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0435<\/h3>\n<p>\u041a\u0430\u043a\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u00a0\u0432\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u00a0Canvas \u0438 \u0432\u044b \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u044b, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a\u00a0\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0443 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a\u00a0\u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0444\u0438\u0433\u0443\u0440 \u0438 \u043e\u0431\u0440\u0435\u0437\u043a\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443\u00a0\u2014 \u044d\u0442\u043e \u0437\u0430\u043b\u0438\u0442\u044c \u043a\u0430\u043d\u0432\u0430\u0441 \u043a\u0430\u043a\u0438\u043c\u2011\u043d\u0438\u0431\u0443\u0434\u044c \u0444\u043e\u043d\u043e\u0432\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c, \u0430\u00a0\u0437\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0438\u0433\u0443\u0440\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a\u00a0\u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0438 \u043a\u0440\u0443\u0433\u0438.<\/p>\n<p>\u0412\u043e\u0442 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u043e \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442:<\/p>\n<pre><code class=\"dart\">final localBounds = Offset.zero &amp; size; final paint = Paint()..style = PaintingStyle.fill;  canvas   \/\/ \u0426\u0432\u0435\u0442 \u0444\u043e\u043d\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430   ..drawPaint(paint..color = const ui.Color(0xFF00AAFF))   \/\/ \u041f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a   ..drawRect(     localBounds.deflate(16),      paint..color = const ui.Color(0xFF00FF1A),   )   \/\/ \u041a\u0440\u0443\u0433   ..drawCircle(     localBounds.center,      localBounds.longestSide \/ 4,      paint..color = const ui.Color(0xFFFF0000),   );<\/code><\/pre>\n<p><strong>\u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p><code>drawPaint<\/code> \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code>drawRect<\/code> \u0440\u0438\u0441\u0443\u0435\u0442 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0441\u00a0\u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435\u043c <code>(deflate(16)<\/code> \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u043e\u0440\u043e\u043d).<\/p>\n<\/li>\n<li>\n<p><code>drawCircle<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u00a0\u0446\u0435\u043d\u0442\u0440\u0435 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 (<a href=\"http:\/\/localBounds.center\" rel=\"noopener noreferrer nofollow\"><code>localBounds.center<\/code><\/a>) \u0441\u00a0\u0440\u0430\u0434\u0438\u0443\u0441\u043e\u043c, \u0440\u0430\u0432\u043d\u044b\u043c \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0438 \u0441\u0430\u043c\u043e\u0439 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u0430\u043d\u0432\u0430\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u0431\u0440\u0435\u0437\u043a\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0437\u0430 \u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438<\/h3>\n<p>\u041d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u043d\u043e\u0433\u0434\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u044b \u043a\u0430\u043d\u0432\u0430\u0441\u0430, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a\u00a0\u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c. \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044f\u0432\u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u0440\u0435\u0437\u043a\u0438\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code class=\"dart\">context.canvas   ..save() \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435   ..clipRect(Offset.zero &amp; size); \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u0440\u0435\u0437\u043a\u0438  \/\/ \u0412\u0430\u0448\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438  context.canvas.restore(); \/\/ \u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/code><\/pre>\n<ul>\n<li>\n<p><strong>\u0412\u0430\u0436\u043d\u043e<\/strong>: \u0412\u0441\u0435\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>canvas.save()<\/code> \u0438 <code>canvas.restore()<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0435\u0437\u043a\u0430 \u0432\u043b\u0438\u044f\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u044b \u043d\u0435\u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u0440\u0435\u0437\u0430\u043d\u0438\u0435\u043c\u00a0\u2014 Flutter \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0443\u0440\u044b \u043e\u0431\u0440\u0435\u0437\u043a\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043a\u0440\u0443\u0433\u0430\u043c\u0438, \u043e\u0432\u0430\u043b\u0430\u043c\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u0444\u0438\u0433\u0443\u0440\u0430\u043c\u0438.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u043a\u0430\u043a\u00a0\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u043a\u0430\u043d\u0432\u0430\u0441 \u043e\u0432\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0438\u0433\u0443\u0440\u043e\u0439:<\/p>\n<pre><code class=\"dart\">final localBounds = Offset.zero &amp; size;  canvas   ..save()   ..clipPath(Path()..addOval(localBounds)); \/\/ \u041e\u0431\u0440\u0435\u0437\u043a\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0432\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430  \/\/ \u0412\u0430\u0448\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438  canvas.restore();<\/code><\/pre>\n<h3>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u044b \u0434\u043b\u044f Canvas<\/h3>\n<p>\u041f\u0440\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, \u0438\u0433\u0440 \u0438\u043b\u0438\u00a0\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u043d\u0430\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u0435 \u0432\u00a0Flutter \u0432\u044b \u0447\u0430\u0441\u0442\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\u0435\u0441\u044c \u0441\u00a0\u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0446\u0435\u043d\u044b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u044c\u044e\u043f\u043e\u0440\u0442 (\u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430\u00a0\u2014 \u043f\u043e\u00a0\u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0430). \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u044f\u0449\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0435\u0439 \u043f\u043e\u00a0\u0432\u0430\u0448\u0435\u0439 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0446\u0435\u043d\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0433\u043e \u0438 \u0433\u0438\u0431\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u2011\u043a\u0430\u043c\u0435\u0440\u044b \u0432\u00a0\u0432\u0430\u0448\u0435\u043c Flutter\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f\u00a0\u043d\u0430\u0448\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u2011\u043a\u0430\u043c\u0435\u0440\u044b. \u0421\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>ChangeNotifier<\/code> Flutter \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043e\u0431\u00a0\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u043f\u043b\u0430\u0432\u043d\u0443\u044e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (<code>CameraView<\/code>):<\/p>\n<pre><code class=\"dart\">\/\/\/ \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u0430\u043c\u0435\u0440\u044b. abstract interface class CameraView implements Listenable {   \/\/\/ \u0426\u0435\u043d\u0442\u0440 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b.   ui.Offset get position;    \/\/\/ \u0420\u0430\u0437\u043c\u0435\u0440 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.   ui.Size get viewportSize;    \/\/\/ \u0420\u0430\u0437\u043c\u0435\u0440 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.   ui.Rect get bound;    \/\/\/ \u0417\u0443\u043c (\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435) \u043a\u0430\u043c\u0435\u0440\u044b.   \/\/\/ \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 0.1 \u0434\u043e 1.   double get zoomDouble;    \/\/\/ \u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.   \/\/\/ \u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 1 \u0434\u043e 10.   int get zoomLevel;    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e.   ui.Offset globalToLocal(double x, double y);    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435.   ui.Offset globalToLocalOffset(ui.Offset offset);    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435.   ui.Rect globalToLocalRect(ui.Rect rect);    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e.   ui.Offset localToGlobal(double x, double y);    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435.   ui.Offset localToGlobalOffset(ui.Offset offset);    \/\/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435.   ui.Rect localToGlobalRect(ui.Rect rect); } <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u0432\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043a\u0430\u043c\u0435\u0440\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"dart\">\/\/\/ \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b. class Camera with ChangeNotifier implements CameraView {   \/\/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043a\u0430\u043c\u0435\u0440\u0443 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438.   Camera({ui.Size viewportSize = ui.Size.zero, ui.Offset position = ui.Offset.zero, int zoom = 5, ui.Rect? boundary})     : _position = position,       _viewportSize = viewportSize,       _halfViewportSize = viewportSize \/ 2,       _bound = ui.Rect.zero,       _zoomLevel = zoom.clamp(1, 10),       _zoom = zoom.clamp(1, 10) \/ 10,       _boundary = boundary {     _calculateBound();   }    @override   ui.Size get viewportSize =&gt; _viewportSize;   ui.Size _viewportSize;   ui.Size _halfViewportSize;    @override   ui.Offset get position =&gt; _position;   ui.Offset _position;    @override   ui.Rect get bound =&gt; _bound;   ui.Rect _bound;    @override   double get zoomDouble =&gt; _zoom;   double _zoom;    @override   int get zoomLevel =&gt; _zoomLevel;   int _zoomLevel = 5; \/\/ 1..10    \/\/\/ \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439.   final ui.Rect? _boundary;    @override   @pragma('vm:prefer-inline')   ui.Offset globalToLocal(double x, double y) =&gt;       _zoom == 1           ? ui.Offset(x - _bound.left, y - _bound.top)           : ui.Offset((x - _bound.left) * _zoom, (y - _bound.top) * _zoom);    @override   @pragma('vm:prefer-inline')   ui.Offset localToGlobal(double x, double y) =&gt;       _zoom == 1           ? ui.Offset(x + _bound.left, y + _bound.top)           : ui.Offset(x \/ _zoom + _bound.left, y \/ _zoom + _bound.top);    @override   @pragma('vm:prefer-inline')   ui.Offset globalToLocalOffset(ui.Offset offset) =&gt;       ui.Offset((offset.dx - _bound.left) * _zoom, (offset.dy - _bound.top) * _zoom);    @override   @pragma('vm:prefer-inline')   ui.Offset localToGlobalOffset(ui.Offset offset) =&gt;       ui.Offset(offset.dx \/ _zoom + _bound.left, offset.dy \/ _zoom + _bound.top);    @override   @pragma('vm:prefer-inline')   ui.Rect globalToLocalRect(ui.Rect rect) =&gt; ui.Rect.fromLTRB(     (rect.left - _bound.left) * _zoom,     (rect.top - _bound.top) * _zoom,     (rect.right - _bound.left) * _zoom,     (rect.bottom - _bound.top) * _zoom,   );    @override   @pragma('vm:prefer-inline')   ui.Rect localToGlobalRect(ui.Rect rect) =&gt; ui.Rect.fromLTRB(     rect.left \/ _zoom + _bound.left,     rect.top \/ _zoom + _bound.top,     rect.right \/ _zoom + _bound.left,     rect.bottom \/ _zoom + _bound.top,   );    \/\/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e.   bool moveTo(ui.Offset position) {     if (_position == position) return false;     _position = position;     _calculateBound();     notifyListeners();     return true;   }    \/\/\/ \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.   bool changeSize(ui.Size size) {     if (_viewportSize == size) return false;     _viewportSize = size;     _halfViewportSize = size \/ 2;     _calculateBound();     notifyListeners();     return true;   }    \/\/\/ \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 (\u0437\u0443\u043c\u0430) \u043a\u0430\u043c\u0435\u0440\u044b.   \/\/\/ \u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0437\u0443\u043c\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 1 \u0434\u043e 10.   bool changeZoom(int level) {     final lvl = level.clamp(1, 10);     if (_zoomLevel == lvl) return false;     _zoomLevel = lvl;     _zoom = lvl \/ 10;     _calculateBound();     notifyListeners();     return true;   }    \/\/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u0443\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u044b.   void zoomIn() {     changeZoom(_zoomLevel + 1);   }    \/\/\/ \u0423\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u0443\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u044b.   void zoomOut() {     changeZoom(_zoomLevel - 1);   }    \/\/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u0437\u0443\u043c\u0430 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.   void zoomReset() {     changeZoom(5);   }    @pragma('vm:prefer-inline')   void _calculateBound() {     if (_boundary != null) {       if (!_boundary.contains(_position)) {         \/\/ \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439.         _position = ui.Offset(           _position.dx.clamp(_boundary.left, _boundary.right),           _position.dy.clamp(_boundary.top, _boundary.bottom),         );       }     }     if (_zoomLevel == 10) {       _bound = ui.Rect.fromLTRB(         _position.dx - _halfViewportSize.width,         _position.dy - _halfViewportSize.height,         _position.dx + _halfViewportSize.width,         _position.dy + _halfViewportSize.height,       );     } else {       _bound = ui.Rect.fromLTRB(         _position.dx - _halfViewportSize.width \/ _zoom,         _position.dy - _halfViewportSize.height \/ _zoom,         _position.dx + _halfViewportSize.width \/ _zoom,         _position.dy + _halfViewportSize.height \/ _zoom,       );     }   } } <\/code><\/pre>\n<ul>\n<li>\n<p>\u0414\u043b\u044f\u00a0\u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u044c\u0442\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (<code>position<\/code> ) \u0432\u0430\u0448\u0435\u0439 \u043a\u0430\u043c\u0435\u0440\u044b \u043a\u0430\u043a\u00a0\u0446\u0435\u043d\u0442\u0440 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u00a0\u0431\u044b\u043b\u0438 \u043f\u043b\u0430\u0432\u043d\u044b\u043c\u0438, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430 \u0441\u00a0\u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u043a\u0430\u043d\u0432\u0430\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u00a0\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b<\/strong>: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f\u00a0\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430\u00a0\u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0435 \u043a\u0430\u043d\u0432\u0430\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u00a0\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b<\/strong>: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f\u00a0\u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u00a0\u0442\u0430\u043f\u0430\u0445 \u0438\u043b\u0438\u00a0\u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438) \u0432\u043e\u00a0\u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0435, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432\u00a0\u0441\u0446\u0435\u043d\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443 \u0432\u00a0\u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"dart\">@override void paint(ui.Canvas canvas, ui.Size size) {   camera.changeSize(size);    canvas.save();   \/\/ \u041e\u0431\u0440\u0435\u0437\u043a\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u043f\u043e \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0443.   canvas.clipRect(Offset.zero &amp; size);    \/\/ \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.   final globalRect = ui.Rect.fromLTWH(500, 500, 100, 100);   final localRect = camera.globalToLocalRect(globalRect);    final paint = ui.Paint()..color = const ui.Color(0xFF00AAFF);   canvas.drawRect(localRect, paint);    canvas.restore(); } <\/code><\/pre>\n<h3>\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0438<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430\u00a0\u0432\u0430\u0448\u0435\u043c \u043a\u0430\u043d\u0432\u0430\u0441\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u00a0\u0438\u0433\u0440\u0430\u0445, \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u0445 \u0438\u043b\u0438\u00a0\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430\u0445), \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u043c (painter) \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u043c. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u0432\u0430\u0448\u0435\u0439 \u0441\u0446\u0435\u043d\u044b \u043d\u0430\u00a0\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u2011\u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0441\u00a0\u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0441\u0442\u0438, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u0443\u0434\u043e\u0431\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0443 \u0441\u0446\u0435\u043d\u0443, \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u00a0\u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u00a0\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b\u2011\u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0438. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ul>\n<li>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0412\u0432\u043e\u0434 (\u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \/ \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b)<\/p>\n<\/li>\n<li>\n<p>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<pre><code class=\"dart\">abstract class ScenePainter {   bool get needsPaint;    bool onPointerEvent(PointerEvent event);   bool onKeyboardEvent(KeyEvent event);   void update(ui.Size size, double delta);   void paint(ui.Size size, PaintingContext context); }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438.<\/p>\n<p>\u041d\u0430\u0448\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f. \u0412\u043e\u0442 \u043a\u0430\u043a\u00a0\u043c\u043e\u0436\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:<\/p>\n<p>\u041f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0439\u0442\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0432\u0441\u0435\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430\u043c, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0438\u0437\u00a0\u043d\u0438\u0445 \u043e\u0442\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u044f\u00a0\u0431\u044b \u043e\u0434\u0438\u043d \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0435\u0433\u043e, \u0432\u0435\u0440\u043d\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>:<\/p>\n<pre><code class=\"dart\">@protected bool onKeyboardEvent(KeyEvent event) {   if (!_hasFocus) return false;   \/\/ \u041f\u0435\u0440\u0435\u0441\u044b\u043b\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0433 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.   \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 | \u0432\u043c\u0435\u0441\u0442\u043e || \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u0441\u0435\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0435.   \/\/final handled = _painters.fold(false, (prev, painter) =&gt; prev | painter.onKeyboardEvent(event));   final handled = _painters.any((painter) =&gt; painter.onKeyboardEvent(event));   return handled; }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u00a0\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0435:<\/p>\n<pre><code class=\"dart\">@override void onPointerEvent(PointerEvent event) {   if (!_hasFocus) return;   \/\/ \u041f\u0435\u0440\u0435\u0441\u044b\u043b\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0433 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.   \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 | \u0432\u043c\u0435\u0441\u0442\u043e || \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u0441\u0435\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0435.   \/\/final _ = _painters.fold(false, (prev, painter) =&gt; prev | painter.onPointerEvent(event));   final _ = _painters.any((painter) =&gt; painter.onPointerEvent(event)); }<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<code>.any()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0435\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u043b\u0430\u0433\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u043a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u043a\u0435\u0442\u0430 (layout) \u0438\u043b\u0438\u00a0\u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0430:<\/p>\n<pre><code class=\"dart\">\/\/\/ \u041c\u0430\u043a\u0435\u0442 \u0441\u0446\u0435\u043d\u044b (\u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f) \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u0430. bool _needsRelayout = true;  \/\/\/ \u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \/\/\/ \u0422\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442 `markNeedsPaint()` bool _needsPaint = true;  \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438: @override void update(ui.Size size, double delta) {   if (_needsRelayout) {     _calculateLayout();     _needsRelayout = false;     _needsPaint = true;   } }<\/code><\/pre>\n<p>\u0412\u00a0\u043d\u0430\u0448\u0435\u043c RenderObject \u043f\u0440\u0438\u00a0\u043a\u0430\u0436\u0434\u043e\u043c \u0442\u0438\u043a\u0435 vsync \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>needsPaint<\/code> \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a\u00a0\u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0443 \u043d\u0430\u00a0\u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443:<\/p>\n<pre><code class=\"dart\">\/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432: painter.update(size, delta);  \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0430, \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0441\u0446\u0435\u043d\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: if (painter.needsPaint) {   markNeedsPaint(); }<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0439\u0442\u0435 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u043b\u0430\u0433\u0438 \u0434\u043b\u044f\u00a0\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u041f\u0440\u0438\u00a0\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0439\u0442\u0435 \u0438\u0445 \u0444\u043b\u0430\u0433\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438:<\/p>\n<pre><code class=\"dart\">@override void update(RePaintBox box, Duration elapsed, double delta) {   final size = box.size;   _camera.changeSize(size); \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043a\u0430\u043c\u0435\u0440\u044b.    for (final painter in _painters)     painter.update(size, delta);    \/\/ \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u043c\u0443-\u043b\u0438\u0431\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0443 \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u043c\u0435\u0442\u044c\u0442\u0435 \u0432\u0441\u044e \u0441\u0446\u0435\u043d\u0443 \u043a\u0430\u043a \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0443\u044e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.   _needsPaint |= _painters.any((painter) =&gt; painter.needsPaint); }<\/code><\/pre>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0438\u0433\u0440\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u0443\u044e \u0440\u043e\u043b\u044c \u0432\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u0430\u0448\u0435\u0439 \u0441\u0446\u0435\u043d\u044b. \u0412\u0430\u0436\u043d\u043e \u0447\u0435\u0442\u043a\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0438 \u043d\u0435\u0443\u043a\u043e\u0441\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0435\u043c\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"dart\">@override void paint(Size size, Canvas canvas) {   canvas     ..save()     ..clipRect(Offset.zero &amp; size);    \/\/ \u0421\u043b\u043e\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435:   _backgroundPainter.paint(size, canvas); \/\/ \u0424\u043e\u043d   _spritesPainter.paint(size, canvas); \/\/ \u0418\u043a\u043e\u043d\u043a\u0438 \u0438 \u0441\u043f\u0440\u0430\u0439\u0442\u044b   _tooltipsPainter.paint(size, canvas); \/\/ \u0418\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438   _debugPainter.paint(size, canvas); \/\/ \u041e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 \u043e\u0432\u0435\u0440\u043b\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0447\u0435\u0442\u0447\u0438\u043a FPS)   _miniMapPainter.paint(size, canvas); \/\/ HUD \u043c\u0438\u043d\u0438-\u043a\u0430\u0440\u0442\u044b   _cameraPainter.paint(size, canvas); \/\/ \u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043a\u0430\u043c\u0435\u0440\u044b    canvas.restore(); }<\/code><\/pre>\n<p>\u041b\u043e\u0433\u0438\u0447\u043d\u043e\u0435 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0431\u0443\u0434\u0443\u0449\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0434 \u0441\u0446\u0435\u043d\u043e\u0439.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p><strong>\u0421\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u00a0\u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0443 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u044b:<br \/><\/strong>\u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e\u00a0\u0432\u0430\u0448\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u043b\u0430\u0433\u0438<\/strong> (<code>_needsPaint<\/code>, <code>_needsRelayout<\/code>), \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/strong>: \u041f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u041c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong>: \u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0441\u0446\u0435\u043d\u0443 \u043d\u0430\u00a0\u043a\u043b\u0430\u0441\u0441\u044b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c<\/strong>: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0444\u043b\u0430\u0433\u0438 \u0434\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u0430\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/strong>: \u041f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0439\u0442\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e\u00a0\u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u043d\u0435\u00a0\u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u0435 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/strong>: \u0427\u0435\u0442\u043a\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u044c\u0442\u0435, \u0432\u00a0\u043a\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043b\u043e\u0438, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0435<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432\u043e\u00a0Flutter, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u0438\u043b\u0438\u00a0\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u043c\u0438, \u043a\u0440\u0430\u0439\u043d\u0435 \u0432\u0430\u0436\u043d\u043e \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u041e\u0434\u043d\u0438\u043c \u0438\u0437\u00a0\u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>\u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u043e\u0432<\/strong> \u0432\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432\u00a0\u043f\u043e\u043b\u044c\u0437\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 GPU \u0434\u043b\u044f\u00a0\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430 <code>Canvas<\/code> Flutter (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>drawRect<\/code>, <code>drawCircle<\/code> \u0438\u00a0\u0442.\u00a0\u0434.), \u0432\u044b <strong>\u043d\u0435\u00a0\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0435 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u00a0\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440<\/strong>. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0438\u0445 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u00a0\u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u0432\u044b \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u044d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u00a0\u0446\u0438\u043a\u043b\u0430\u0445, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440, \u0447\u0442\u043e\u00a0\u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u00a0\u043e\u0431\u0449\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"dart\">\/\/ \u041d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438: for (final sprite in sprites) {   canvas.drawImageRect(sprite.image, sprite.srcRect, sprite.dstRect, paint); }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 GPU, \u0447\u0442\u043e\u00a0\u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a\u00a0\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u043c \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u043c \u0438 \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>Flutter \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b Canvas, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f\u00a0\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u0435\u0442\u043e\u0434<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0432\u00a0\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>drawAtlas<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (\u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432) \u0438\u0437\u00a0\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b.<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430\u00a0GPU<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>drawRawAtlas<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0438\u0441\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0438\u043b\u0438\u00a0\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u043a\u0430\u0434\u0440\u043e\u0432 \u0441\u00a0\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u043c\u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u043c\u0438.<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u0441\u043e\u0447\u0430\u0439\u0448\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u00a0GPU<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>drawRawPoints<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a (\u043a\u0440\u0443\u0433\u043e\u0432, \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u0432).<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043c\u043d\u043e\u0433\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u042d\u0442\u0438 \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043e\u043b\u0436\u043d\u044b\u00a0\u0431\u044b\u0442\u044c \u0432\u0430\u0448\u0438\u043c\u0438 \u0433\u043b\u0430\u0432\u043d\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u043b\u044f\u00a0\u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p><code>drawRawAtlas<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0438\u0437\u00a0\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b (\u0430\u0442\u043b\u0430\u0441\u0430). \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f\u00a0\u0438\u0433\u0440 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0438\u043b\u0438\u00a0\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e\u00a0\u0430\u0442\u043b\u0430\u0441\u044b \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u044b\u00a0\u0431\u044b\u0442\u044c \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u00a0\u2014\u00a0\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u00a0\u0431\u043e\u043b\u0435\u0435 <code>1024\u00d71024<\/code> \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"dart\">final visibleSkills = skills.length; final skillsPos = Float32List(visibleSkills * 4); final skillsSpr = Float32List(visibleSkills * 4);  \/\/ \u041c\u0430\u043a\u0435\u0442 \u0438 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f for (var i = 0; i &lt; visibleSkills; i++) {   final skill = skills[i];   final sprite = skill.sprite ?? skill.tags.first.sprite;   final rect = skill.boundary;   final size = rect.longestSide;    \/\/ \u0421\u043f\u0440\u0430\u0439\u0442\u044b \u0441\u043a\u0438\u043b\u043e\u0432   skillsSpr     ..[i * 4 + 0] = sprite.dx \/\/ \u0441\u043b\u0435\u0432\u0430     ..[i * 4 + 1] = sprite.dy \/\/ \u0432\u0432\u0435\u0440\u0445\u0443     ..[i * 4 + 2] = sprite.dx + sprite.size \/\/ \u0441\u043f\u0440\u0430\u0432\u0430     ..[i * 4 + 3] = sprite.dy + sprite.size; \/\/ \u0432\u043d\u0438\u0437\u0443    \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0441\u043a\u0438\u043b\u043e\u0432.   final Offset(:dx, :dy) = _camera.globalToLocal(rect.left, rect.top);    \/\/ \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u0435 \u0441\u043a\u0438\u043b \u0438\u0437 \u043b\u0435\u0432\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0433\u043b\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u0430.   skillsPos     ..[i * 4 + 0] = size * _camera.zoomDouble \/ sprite.size     ..[i * 4 + 1] = 0     ..[i * 4 + 2] = dx     ..[i * 4 + 3] = dy; }  final Paint skillsAtlasPaint =   Paint()     ..style = ui.PaintingStyle.fill     ..blendMode = BlendMode.srcOver     \/\/ \u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 \u0438 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.     ..filterQuality = FilterQuality.none     ..isAntiAlias = false;  \/\/ \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0439\u0442\u0435 \u0441\u043a\u0438\u043b\u044b \u0438\u0437 \u0430\u0442\u043b\u0430\u0441\u0430 \u043f\u043e 500 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0437\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e. \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 `visibleSkills` \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u0430 \u0432\u0438\u0434\u0438\u043c\u044b\u0445 \u0431\u0443\u0444\u0435\u0440\u043e\u0432 \u0441\u043a\u0438\u043b\u043e\u0432. for (var offset = 0; offset &lt; visibleSkills; offset += 500) {   final start = offset;   final end = math.min(offset + 500, visibleSkills);   final positionsView = Float32List.sublistView(skillsPos, start * 4, end * 4);   final spritesView = Float32List.sublistView(skillsSpr, start * 4, end * 4);   \/\/final colorsView = Int32List.sublistView(skillsColors, start, end);   canvas.drawRawAtlas(     _atlas,     positionsView,     spritesView,     null, \/\/ colorsView     BlendMode.srcOver, \/\/ BlendMode.src     null,     skillsAtlasPaint,   ); }<\/code><\/pre>\n<ul>\n<li>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0437\u0430\u00a0\u0441\u0447\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<\/li>\n<\/ul>\n<p><code>drawRawPoints<\/code> \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u0451\u0430\u043a\u0435\u0442\u043d\u043e\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0442\u043e\u0447\u0435\u043a, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0447\u0430\u0441\u0442\u0438\u0446 \u0438\u043b\u0438\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"dart\">\/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043a\u0440\u0443\u0433\u0438 final points = Float32List.fromList([   100, 100, 200, 200, 300, 300, \/\/ x1,y1, x2,y2, x3,y3... ]);  final paint = Paint()   ..color = const Color(0xFFFF0000)   ..isAntiAlias = true   ..blendMode = BlendMode.srcOver   ..style = PaintingStyle.stroke   ..strokeCap = StrokeCap.round   ..strokeJoin = StrokeJoin.round   ..strokeWidth = 6;  canvas.drawRawPoints(PointMode.points, points, paint);<\/code><\/pre>\n<ul>\n<li>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0438\u043b\u044c \u0444\u0438\u0433\u0443\u0440\u044b (<code>PointMode.points<\/code>, <code>PointMode.lines<\/code> \u0438\u043b\u0438 <code>PointMode.polygon<\/code>) \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u0432\u0430\u0448\u0438\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u00a0\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043a\u0440\u0443\u0433\u043e\u0432 \u0438\u043b\u0438\u00a0\u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u0432 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e\u00a0\u043c\u0435\u0442\u043e\u0434\u044b \u043a\u0430\u043d\u0432\u0430\u0441\u0430 Flutter \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u00a0\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430. \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u043e\u043c, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c \u0432\u0435\u0437\u0434\u0435, \u0433\u0434\u0435 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e.<\/p>\n<ul>\n<li>\n<p><strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435:<\/strong> \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>drawAtlas<\/code>, <code>drawRawAtlas<\/code>, drawRawPoints.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435:<\/strong> \u0446\u0438\u043a\u043b\u043e\u0432, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u0430\u043a\u00a0drawRect, drawCircle, <code>drawImageRect<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0434\u043b\u044f\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 Flutter canvas \u043d\u0435\u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u043c \u043e\u0442\u00a0\u0446\u0438\u043a\u043b\u043e\u0432 \u0438 \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0430\u0448\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 <code>Paint<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0435\u0441\u0442\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0438\u0433\u0440\u044b\u0448. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u044d\u0442\u043e\u0433\u043e \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 (\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432) \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 smart paint.<\/p>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 Flutter \u043d\u0435\u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u0446\u0438\u043a\u043b\u043e\u0432 \u0438 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439. \u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430\u00a0\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>Paint<\/code>\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 (\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432) \u0438 \u0443\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>Paint<\/code>\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 GPU\u2011\u0448\u0435\u0439\u0434\u0435\u0440\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u00a0\u044f\u0437\u044b\u043a\u0435 GLSL \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430\u00a0\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0435, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043d\u0435\u043f\u0440\u0435\u0432\u0437\u043e\u0439\u0434\u0435\u043d\u043d\u0443\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u0425\u043e\u0440\u043e\u0448\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b, \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u0438 \u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e\u00a0\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441\u00a0\u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c.<\/p>\n<p>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>Paint<\/code>\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f\u043c\u0438 \u0434\u043b\u044f\u00a0\u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u043d\u0432\u0430\u0441\u0430. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 <code>Paint<\/code>\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a\u00a0\u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u043e\u0431\u044a\u0435\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u0430\u043c \u043d\u0430\u00a0\u0441\u0431\u043e\u0440\u043a\u0443 \u043c\u0443\u0441\u043e\u0440\u0430, \u0447\u0442\u043e, \u0432\u00a0\u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u00a0\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p><strong>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430:<\/strong> \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043e\u0431\u0449\u0438\u0435 Paint\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f\u00a0\u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f\u00a0\u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 (\u0431\u0435\u0437 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f):<\/p>\n<pre><code class=\"dart\">final pixelArtPaint = Paint()   ..isAntiAlias = false   ..filterQuality = FilterQuality.none   ..style = PaintingStyle.fill;<\/code><\/pre>\n<ul>\n<li>\n<p>\u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u044b\u0442\u0438\u0435, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u0447\u0435\u0442\u043a\u0438\u0435 \u043f\u0438\u043a\u0441\u0435\u043b\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u0440\u0438\u0432\u044b\u0445 \u0438\u00a0\u043b\u0438\u043d\u0438\u0439 (\u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e):<\/p>\n<pre><code class=\"dart\">final smoothLinePaint = Paint()   ..isAntiAlias = true   ..strokeWidth = 2.0   ..style = PaintingStyle.stroke;<\/code><\/pre>\n<ul>\n<li>\n<p>\u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u00ab\u043d\u0435\u0440\u043e\u0432\u043d\u043e\u0441\u0442\u0438\u00bb (aliasing) \u043d\u0430\u00a0\u043b\u0438\u043d\u0438\u044f\u0445 \u0438 \u043a\u0440\u0438\u0432\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"dart\">final pointPaint = Paint()   ..color = Colors.red   ..strokeWidth = 8   ..strokeCap = StrokeCap.round; \/\/ \u0417\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435  canvas.drawPoints(PointMode.points, points, pointPaint);<\/code><\/pre>\n<ul>\n<li>\n<p><strong>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435<\/strong> <code>Paint<\/code>\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u042f\u0432\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 <code><strong>isAntiAlias<\/strong><\/code> \u0438 <code><strong>filterQuality<\/strong><\/code> \u0432\u00a0\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u00a0\u0432\u0430\u0448\u0438\u043c\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u044b (<code>vertex<\/code> \u0438 <code>fragment<\/code>) \u0434\u043b\u044f\u00a0\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430\u00a0\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u00a0\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 (<code>drawRawAtlas<\/code>, <code>drawRawPoints<\/code>) \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u044e\u0442 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<h3>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c\u00a0<\/h3>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u044f \u0441\u00a0\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u043c\u0438 \u043d\u0430\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u0435 Flutter, \u0432\u044b \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0435\u0442\u0435\u0441\u044c \u0441\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c. \u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u044f, \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0438\u0434\u043d\u044b \u0432\u043e\u00a0\u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0435 \u0432\u0430\u0448\u0435\u0439 \u043a\u0430\u043c\u0435\u0440\u044b. \u0414\u043b\u044f\u00a0\u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0441\u0446\u0435\u043d, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u043c\u0435\u043d\u0435\u0435 100\u00a0\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432,\u00a0\u043b\u0438\u043d\u0435\u0439\u043d\u0430\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0435\u0449\u0435 \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f\u00a0\u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041e\u0434\u043d\u043e\u0439 \u0438\u0437\u00a0\u0442\u0430\u043a\u0438\u0445 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>QuadTree<\/strong>.<\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/QuadTree-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0430\u0441\u0441 QuadTree\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 repaint\u00a0\u2014 Dart API <\/a><\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/QuadTree-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e\u00a0API \u0434\u043b\u044f\u00a0\u043a\u043b\u0430\u0441\u0441\u0430 QuadTree \u0438\u0437\u00a0\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 repaint \u0434\u043b\u044f\u00a0\u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Dart.<\/a><\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Quadtree?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\"><strong>QuadTree<\/strong><\/a> \ud83c\udf33\u00a0\u2014 \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0434\u0435\u043b\u0438\u0442 \u0434\u0432\u0443\u043c\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043d\u0430\u00a0\u0447\u0435\u0442\u044b\u0440\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u043d\u0442\u0430. \u042d\u0442\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0433\u0440\u0430\u043d\u0438\u0446, \u0447\u0442\u043e\u00a0\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 QuadTree:<\/p>\n<ul>\n<li>\n<p><strong>\u0411\u044b\u0441\u0442\u0440\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/strong>: \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0\u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u043e\u043d\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439<\/strong>:\u00a0\u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c<\/strong>: \u041f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u0430\u0436\u0435 \u0441\u00a0\u0442\u044b\u0441\u044f\u0447\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0423\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c QuadTree \u0432\u043e\u00a0Flutter:<\/p>\n<pre><code class=\"dart\">\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u044b (\u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u0438\u0440\u0430) \u0432\u0430\u0448\u0435\u0433\u043e QuadTree. final QuadTree qt = QuadTree(   boundary: Rect.fromLTWH(0, 0, worldWidth, worldHeight),   depth: 5,      \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u0430   capacity: 24,  \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0443\u0437\u0435\u043b \u0434\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f );  \/\/\/ \u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 QuadTree \u0441 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \/\/\/ \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043b\u044f \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 QuadTree \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438. List&lt;Object?&gt; _qt2object = List&lt;Object?&gt;.filled(64, null, growable: false);  \/\/\/ \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 QuadTree. int put(HitBox obj) {   final id = qt.insert(obj.rect);   if (_qt2object.length &lt;= id) {     final prev = _qt2object;     _qt2object = List&lt;Object?&gt;.filled(       math.max(64, _qt2object.length &lt;&lt; 1),       null,       growable: false,     )..setAll(0, prev);   }   _qt2object[id] = obj;   return id; }  \/\/\/ \u0417\u0430\u043f\u0440\u043e\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438. Iterable&lt;HitBox&gt; query(Rect rect) =&gt;   qt.queryIds(rect).map((id) =&gt; _qt2object[id]).whereType&lt;HitBox&gt;();<\/code><\/pre>\n<p>\u041f\u0440\u0438\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u0438\u043b\u0438\u00a0\u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0439\u0442\u0435 \u0441 \u00ab\u0434\u0435\u0448\u0435\u0432\u043e\u0439\u00bb \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0435\u0440\u0435\u0434 \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435 <strong>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438<\/strong> (bounding boxes).<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0430\u00a0\u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044e.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"dart\">bool checkCollision(HitBox obj1, HitBox obj2) {   \/\/ \u0414\u0435\u0448\u0435\u0432\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432   if (!obj1.rect.overlaps(obj2.rect)) return false;   \/\/ \u041f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u0435 \u0442\u043e\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438   return detailedCollisionCheck(obj1, obj2); }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u00a0\u0432\u0438\u0434\u0438\u043c\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 \u0432\u043e\u00a0\u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0435 \u043a\u0430\u043c\u0435\u0440\u044b, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0433\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043b\u0438\u00a0\u0442\u0435, \u0447\u0442\u043e\u00a0\u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0431\u043b\u0438\u0437\u043a\u043e \u043a\u00a0\u043a\u0440\u0430\u044f\u043c.<\/p>\n<pre><code class=\"dart\">final cameraBoundsInflated = camera.bound.inflate(32); final visibleObjects = quadTree.query(cameraBoundsInflated);<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u00ab\u0432\u043d\u0435\u0437\u0430\u043f\u043d\u044b\u0445 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0439\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432\u00a0\u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430.<\/p>\n<p>\u0421\u0442\u0430\u0440\u0430\u0439\u0442\u0435\u0441\u044c \u043d\u0435\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u00a0\u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>paint<\/code> \u0438\u043b\u0438 <code>update<\/code>, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u0448\u0430 \u0441\u0446\u0435\u043d\u0430 \u0432\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0430. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b Flutter, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>ChangeNotifier<\/code>, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041f\u043e\u0434\u043f\u0438\u0448\u0438\u0442\u0435\u0441\u044c \u043d\u0430\u00a0\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u00a0\u043a\u0430\u043c\u0435\u0440\u0435 \u0438 QuadTree:<\/p>\n<pre><code class=\"dart\">void init() {   camera.addListener(_onChange);   quadTree.addListener(_onChange); }  \/\/\/ \u041f\u043e\u043c\u0435\u0442\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u043e\u0432 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043c\u0430\u043a\u0435\u0442\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. void _onChange() {   _skillsPainter.changed();   _selectorPainter.changed();   _miniMapPainter.changed(); }  class SkillsPainter {   bool _needsRelayout = true;   bool _needsPaint = true;   bool get needsPaint =&gt; _needsPaint;    void changed() =&gt; _needsRelayout = true;    void update(Size size, double delta) {     if (_needsRelayout) _relayout();   }    void _relayout() {     _needsRelayout = false;     final objects = quadTree.query(camera.bound.inflate(64));     final skills = objects.whereType&lt;RoadmapSkill&gt;().toList(growable: false);          \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0430\u043a\u0435\u0442\u0430...     _needsPaint = true; \/\/ \u041f\u043e\u043c\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f   } }<\/code><\/pre>\n<p>\u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e\u00a0\u0432\u0430\u0448\u0430 \u0441\u0446\u0435\u043d\u0430 \u0447\u0435\u0442\u043a\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443:<\/p>\n<ol>\n<li>\n<p><strong>\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439<\/strong>: \u041f\u043e\u043c\u0435\u0447\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043a\u0430\u043a \u00ab\u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435\u00bb (<code>_needsRelayout<\/code>) \u043f\u0440\u0438\u00a0\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0442\u0430\u043f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f<\/strong>: \u041f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435 \u043c\u0430\u043a\u0435\u0442 \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e <\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0442\u0430\u043f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/strong>: \u041f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 (<code>_needsPaint<\/code>).<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"dart\">@override bool get needsPaint =&gt; _needsPaint |= painters.any((painter) =&gt; painter.needsPaint);<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043f\u043e\u0432\u044b\u0448\u0430\u044f \u043e\u0431\u0449\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p><em>\u0412\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u00a0\u0442\u0435\u0445\u043d\u0438\u043a\u0430 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043e\u0442\u043b\u0430\u0434\u043a\u0438.<\/em><\/p>\n<hr\/>\n<p>\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u043c \u0432\u0430\u0441 \u043d\u0430\u00a0\u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0443\u0440\u043e\u043a \u043a\u0443\u0440\u0441\u0430 \u00abFlutter Mobile Developer\u00bb\u00a0\u2014 <a href=\"https:\/\/otus.pw\/vLqZ\/\" rel=\"noopener noreferrer nofollow\">\u00abFlutter \u0432\u00a0Automotive &amp; Embedded: \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0\u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f (\u0438 \u043d\u0435\u00a0\u0442\u043e\u043b\u044c\u043a\u043e)\u00bb<\/a>. \u0423\u0440\u043e\u043a \u0441\u043e\u0441\u0442\u043e\u0438\u0442\u0441\u044f <em>12\u00a0\u0430\u0432\u0433\u0443\u0441\u0442\u0430 \u0432 20:00<\/em>. \u0412\u00a0\u0445\u043e\u0434\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u044f \u0432\u044b \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u0435\u0441\u044c \u0441\u00a0\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f\u00a0\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u0438\u043a\u0438 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Flutter.<\/p>\n<p>\u0410\u00a0\u0442\u0430\u043a\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0439\u0442\u0438 <a href=\"https:\/\/otus.pw\/i2v0\/\" rel=\"noopener noreferrer nofollow\">\u0432\u0441\u0442\u0443\u043f\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u043d\u0430\u00a0\u043e\u0446\u0435\u043d\u043a\u0443 \u0432\u0430\u0448\u0438\u0445 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 Flutter.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/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\/articles\/935384\/\"> https:\/\/habr.com\/ru\/articles\/935384\/<\/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 article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Canvas\u00bb\u0430 Flutter, \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u00a0GPU \u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u0442\u043b\u0430\u0434\u043a\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445 \u0441\u0446\u0435\u043d \u0432\u043e\u00a0Flutter \u0438\u043c\u0435\u0435\u0442 \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u044e \u043e\u0447\u0435\u043d\u044c\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0425\u043e\u0442\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432\u00a0Flutter Canvas API \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0432\u00a0\u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0437\u043d\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<p>\u0412\u00a0\u044d\u0442\u043e\u043c \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435, \u043d\u043e\u00a0\u0432\u00a0\u0442\u043e\u00a0\u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 Flutter\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 Canvas. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0443\u043c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f GPU, \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0432\u043d\u044b\u0435,\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b\u00a0\u2014 \u0434\u0430\u0436\u0435 \u0432\u00a0\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0445.<\/p>\n<h3>\u0427\u0435\u043c\u0443 \u0432\u044b \u043d\u0430\u0443\u0447\u0438\u0442\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435<\/h3>\n<ul>\n<li>\n<p><strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 Canvas:<br \/><\/strong>\u041a\u0430\u043a\u00a0\u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 (<code>CustomPaint<\/code>, \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 <code>RenderObject<\/code> \u0438\u043b\u0438 <code>LeafRenderObjectWidget<\/code>) \u0434\u043b\u044f\u00a0\u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u0430:<br \/><\/strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0433\u0438\u0431\u043a\u043e\u0439 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u0430\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u043c\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0430\u043a\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 GPU \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u043e\u0432 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438:<br \/><\/strong>\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0446\u0438\u043a\u043b\u043e\u0432 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 Flutter (<code>drawRawAtlas<\/code>, <code>drawRawPoints<\/code>, <code>drawVertices<\/code>) \u0434\u043b\u044f\u00a0\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e QuadTrees:<br \/><\/strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439, \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u0432\u044c\u044e\u043f\u043e\u0440\u0442\u043e\u0432 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 QuadTree \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u044e\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0441\u0446\u0435\u043d\u044b \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>GPU\u2011\u0448\u0435\u0439\u0434\u0435\u0440\u044b \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f Paint:<br \/><\/strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 \u0441\u00a0GPU\u2011\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435\u043c, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Paint\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430, \u0442\u0430\u043a \u0438 \u043c\u043e\u043b\u043d\u0438\u0435\u043d\u043e\u0441\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Picture \u0438 \u0440\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438:<br \/><\/strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>PictureRecorder<\/code> Flutter \u0434\u043b\u044f\u00a0\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u0438\u043b\u0438\u00a0\u0440\u0435\u0434\u043a\u043e \u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432 \u0432\u0430\u0448\u0435\u0439 \u0441\u0446\u0435\u043d\u044b, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430\u00a0\u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0434\u0435\u0436\u043d\u0430\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<br \/><\/strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043b\u043e\u044f \u0441\u00a0\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u043c \u043e\u0432\u0435\u0440\u043b\u0435\u0435\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u043e\u0440\u044f\u0447\u0438\u0445 \u043a\u043b\u0430\u0432\u0438\u0448 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <strong>F2<\/strong>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (FPS, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u00a0\u043a\u0430\u043c\u0435\u0440\u0435, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f QuadTree, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445). \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u043e\u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0438 \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435\u00a0\u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e\u00a0\u0432\u0430\u0448\u0435 Flutter\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 Canvas \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u043c, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u043c. \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u0442\u043e\u0433\u043e, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435\u00a0\u043b\u0438 \u0432\u044b \u0438\u0433\u0440\u044b, \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043b\u0438\u00a0\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u0432\u00a0\u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Flutter \u0434\u043b\u044f\u00a0\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>\u042d\u0442\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e \u0434\u043b\u044f\u00a0Flutter\u2011\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0438 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0440\u0435\u043c\u044f\u0442\u0441\u044f \u043a\u00a0\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 Canvas. \u041f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u0435\u043c \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0432\u0430\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u00a0\u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 Flutter, \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0441\u00a0Canvas\u00a0\u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442 \u0432\u0430\u0448\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c.<\/p>\n<hr\/>\n<h3>\u0412\u044b\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0430<\/h3>\n<p>\u041f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u0438\u043b\u0438\u00a0\u0432\u044b\u0441\u043e\u043a\u043e\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u043c\u0438 \u0432\u043e\u00a0Flutter \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u043c\u0435\u0435\u0442 \u0440\u0435\u0448\u0430\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0\u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u00a0\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a\u00a0\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430 CustomPaint \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f\u00a0\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u2011\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0438\u043b\u0438\u00a0\u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0447\u0430\u0441\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u0438 \u0441\u043e\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 Canvas\u00bb\u0430 \u0432\u043e\u00a0Flutter.<\/p>\n<p>Flutter \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0434\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439 \u043d\u0430\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u0435 (\u0445\u043e\u043b\u0441\u0442\u0435). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\"><strong>\u0412\u0438\u0434\u0436\u0435\u0442 \/ \u041f\u043e\u0434\u0445\u043e\u0434<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\"><strong>\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\"><strong>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">CustomPaint<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u041f\u0440\u043e\u0441\u0442\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0425\u043e\u0440\u043e\u0448\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u00a0\u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">LeafRenderObjectWidget<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"191\" width=\"191\">\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 RePaint<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td data-colwidth=\"158\" width=\"158\">\n<p align=\"left\">\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 CustomPaint<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u00a0\u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430 <code>CustomPaint<\/code>:<\/p>\n<pre><code class=\"dart\">dartCopyEditCustomPaint(   painter: MyCanvasPainter(), );<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u0448\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0438\u043b\u0438\u00a0\u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0438\u0437\u2011\u0437\u0430 \u0438\u0437\u043b\u0438\u0448\u043d\u0438\u0445 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d79d3ee88c0a9285d36d\" data-style=\"\" id=\"6895d79d3ee88c0a9285d36d\" width=\"\"><\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e LeafRenderObjectWidget<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u00a0\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438\u00a0\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u044e\u0442, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u2011\u043e\u0431\u044a\u0435\u043a\u0442\u0430 (render object), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>LeafRenderObjectWidget<\/code>. \u042d\u0442\u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439, \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u043e\u0439 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c:<\/p>\n<pre><code class=\"dart\">class CustomRenderBoxWidget extends LeafRenderObjectWidget {   \/\/ ...      @override   RenderObject createRenderObject(BuildContext context) {     final box = CustomRenderBox();     \/\/ ...     return box;   } }  class CustomRenderBox extends RenderBox with WidgetsBindingObserver {    \/\/ ...    \/\/\/ \u0442\u0438\u043a\u0435\u0440 \u0446\u0438\u043a\u043b\u0430 Vsync.   Ticker? _ticker;      @override   bool get isRepaintBoundary =&gt; true;    @override   bool get alwaysNeedsCompositing =&gt; false;    @override   bool get sizedByParent =&gt; true;      @override   Size computeDryLayout(BoxConstraints constraints) =&gt; constraints.biggest;      void _onTick(Duration elapsed) {     \/\/ ...     markNeedsPaint();   }      @override   void attach(PipelineOwner owner) {     super.attach(owner);     WidgetsBinding.instance.addObserver(this);     _ticker = Ticker(_onTick, debugLabel: 'CustomRenderBox')..start();     \/\/ ...   }      @override   void detach() {     _ticker?.dispose();     WidgetsBinding.instance.removeObserver(this);     super.detach();     \/\/ ...   }      @override   void paint(PaintingContext context, Offset offset) {     \/\/ ...   } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u00a0\u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0447\u0442\u043e\u00a0\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f\u00a0\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0445 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u044b.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d825d5124fabc4a7ac51\" data-style=\"\" id=\"6895d825d5124fabc4a7ac51\" width=\"\"><\/div>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6895d833d5124fabc4a7ac61\" data-style=\"\" id=\"6895d833d5124fabc4a7ac61\" width=\"\"><\/div>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 RePaint<\/h3>\n<p>\u0412\u00a0\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u0439 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pub.dev\/packages\/repaint?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">repaint<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f\u00a0\u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/RePaint-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0430\u0441\u0441 RePaint\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 repaint\u00a0\u2014 Dart API <\/a><\/p>\n<p><a href=\"https:\/\/pub.dev\/documentation\/repaint\/latest\/repaint\/RePaint-class.html?ref=plugfox.dev\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f API \u0434\u043b\u044f\u00a0\u043a\u043b\u0430\u0441\u0441\u0430 RePaint \u0438\u0437\u00a0\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 repaint \u0434\u043b\u044f\u00a0\u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Dart.<\/a><\/p>\n<pre><code class=\"dart\">final _painter = MyGamePainter();  @override Widget build(BuildContext context) =&gt; RePaint(     painter: _painter,   );    \/\/ ...  class MyGamePainter extends RePainterBase {   \/\/ ... }<\/code><\/pre>\n<h3>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u0440\u0430\u043d\u0438\u0446<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448 \u043a\u0430\u043d\u0432\u0430\u0441 \u0447\u0430\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442\u00a0\u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0433\u043e \u0435\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0432 \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u0438\u0434\u0436\u0435\u0442\u0430. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u0435\u0440\u043d\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 <code>CustomPaint<\/code> \u0432 <code>RepaintBoundary<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043b\u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 <code>RenderObject<\/code>, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0434\u043b\u044f\u00a0\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>isRepaintBoundary <\/code>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"dart\">RepaintBoundary(   child: CustomPaint(     painter: MyFrequentlyUpdatedPainter(),   ), )<\/code><\/pre>\n<p>\u0425\u043e\u0442\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u00a0\u0441\u0447\u0435\u0442 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u0438 \u043f\u043b\u043e\u0449\u0430\u0434\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a, \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0432\u043b\u0435\u0447\u0435\u0442 \u0437\u0430\u00a0\u0441\u043e\u0431\u043e\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u0438\u0437\u2011\u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 GPU. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0430\u0436\u043d\u043e \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u00a0\u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d.<\/p>\n<h3>\u26a0\ufe0f \u041d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0439\u0442\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438\u043b\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u043a\u0430\u043d\u0432\u0430\u0441\u043e\u043c Flutter \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 (<code>CustomPaint<\/code>) \u0432\u043d\u0443\u0442\u0440\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438\u043b\u0438\u00a0\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>setState()<\/code>. \u0425\u043e\u0442\u044f \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u0438\u043b\u0438\u00a0\u0434\u0430\u0436\u0435 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u043c, \u043e\u043d \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a\u00a0\u043d\u0435\u043d\u0443\u0436\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432, \u0447\u0442\u043e\u00a0\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0434\u043b\u044f\u00a0\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u044b\u0445 \u0438\u043b\u0438\u00a0\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0446\u0435\u043d.<\/p>\n<p>\u0412\u043e\u0442 \u0447\u0435\u0433\u043e \ud83d\udeab <strong>\u043d\u0435\u00a0\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c <\/strong>\ud83d\udeab:<\/p>\n<pre><code class=\"dart\">AnimatedBuilder(   animation: animationController,   builder: (context, _) =&gt;       CustomPaint(painter: MyPainter()), );<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code class=\"dart\">BlocBuilder(   bloc: bloc,   builder: (context, state) =&gt;       CustomPaint(painter: MyPainter()), );<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code class=\"dart\">context.watch&lt;T&gt;(); return CustomPaint(painter: MyPainter());<\/code><\/pre>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0443\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e Flutter, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f <code>Listenable <\/code>(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>AnimationController<\/code>, <code>ChangeNotifier<\/code>) \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 repaint \u0432\u0430\u0448\u0435\u0433\u043e <code>CustomPainter<\/code>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"dart\">final animationController = AnimationController(   vsync: this,   duration: const Duration(seconds: 1), )..repeat();  CustomPaint(   \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 repaint   painter: MyPainter(repaint: animationController),  );<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0449\u0438\u043a\u0430:<\/p>\n<pre><code class=\"dart\">class MyPainter extends CustomPainter {   MyPainter({required super.repaint});    @override   void paint(Canvas canvas, Size size) {     \/\/ \u0417\u0434\u0435\u0441\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438   }    @override   bool shouldRepaint(covariant MyPainter oldDelegate) =&gt; false; }<\/code><\/pre>\n<ul>\n<li>\n<p>Flutter \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0443, \u0438\u0437\u0431\u0435\u0433\u0430\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0435\u043a \u0432\u0438\u0434\u0436\u0435\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\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-470067","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/470067","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=470067"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/470067\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=470067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=470067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=470067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}