{"id":367454,"date":"2024-05-21T03:21:20","date_gmt":"2024-05-21T03:21:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=367454"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=367454","title":{"rendered":"<span>VR-\u0442\u0443\u0440 \u043d\u0430 A-Frame + React<\/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<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2cf\/847\/976\/2cf847976ca8515f9ce2f9cf318d62e2.gif\" width=\"600\" height=\"300\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2cf\/847\/976\/2cf847976ca8515f9ce2f9cf318d62e2.gif\"\/><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0415\u0433\u043e\u0440 \u041c\u043e\u043b\u0447\u0430\u043d\u043e\u0432, \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432\u00a0\u043a\u043e\u043c\u0430\u043d\u0434\u0435 CRM \u0434\u043b\u044f\u00a0\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u0432 \u0438\u043f\u043e\u0442\u0435\u0447\u043d\u043e\u0433\u043e \u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u00a0\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0414\u043e\u043c\u043a\u043b\u0438\u043a. \u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f VR\u2011\u0442\u0443\u0440\u0430 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 A\u2011Frame \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 React. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 pet\u2011\u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c.<\/p>\n<h3>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b<\/h3>\n<p><a href=\"https:\/\/aframe.io\/\">A\u2011Frame<\/a>\u00a0\u2014 \u044d\u0442\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 VR\u2011\u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041e\u043d \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430\u00a0HTML, \u0447\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443. \u0423\u00a0\u043d\u0435\u0433\u043e \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043d\u0435\u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u00a0\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f<br \/>\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d \u043d\u0430\u00a0\u0447\u0438\u0441\u0442\u043e\u043c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/WebGL\">WebGL<\/a>, \u0432\u00a0\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0438\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/threejs.org\/\">Three.js<\/a>. \u041e\u043d \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0441\u0446\u0435\u043d\u0443 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a\u00a0\u0446\u0438\u043b\u0438\u043d\u0434\u0440, \u043a\u0443\u0431 \u0438\u043b\u0438\u00a0\u0441\u0444\u0435\u0440\u0430.<\/p>\n<p><a href=\"https:\/\/react.dev\/\">React<\/a>\u00a0\u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432.<\/p>\n<h3>\u0422\u0417 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u0439\u0442, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e\u00a0\u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u044f\u043c, \u043f\u043e\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0433\u043e\u043b\u043e\u0432\u043e\u0439 \u043d\u0430 360\u00a0\u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432, \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0438 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437\u00a0VR-\u0440\u0435\u0436\u0438\u043c\u0430.<\/p>\n<h3>\u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435<\/h3>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438. \u041d\u0430\u00a0\u0441\u0430\u0439\u0442\u0435 \u0441\u00a0\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432\u00a0\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442. \u0414\u043b\u044f\u00a0\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432\u00a0A\u2011Frame, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>position<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b (x, y, z), \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u043e\u0442\u00a0\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 (0, 0, 0), \u043a\u0430\u043a\u00a0\u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430\u00a0\u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/821\/1fa\/8d2\/8211fa8d27761cc0c970af0c0dc3ef05.png\" alt=\"\u0422\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.\" title=\"\u0422\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.\" width=\"926\" height=\"757\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/821\/1fa\/8d2\/8211fa8d27761cc0c970af0c0dc3ef05.png\"\/><\/p>\n<div><figcaption>\u0422\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/figcaption><\/div>\n<\/figure>\n<p>Three.js \u0438 WebGL \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u00a0\u0438\u043c\u0435\u044e\u0442 \u0435\u0434\u0438\u043d\u0438\u0446 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f, \u043d\u043e\u00a0\u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0432\u043d\u043e\u0439 \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u0440\u0443. <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>rotation<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438 \u043f\u043e\u00a0\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c (x, y, z). \u0415\u0434\u0438\u043d\u0438\u0446\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u00a0\u2014 \u0433\u0440\u0430\u0434\u0443\u0441\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ac9\/5a0\/8ce\/ac95a08ce96194cbbefe751800d89d86.png\" alt=\"\u0412\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438.\" title=\"\u0412\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438.\" width=\"1100\" height=\"808\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ac9\/5a0\/8ce\/ac95a08ce96194cbbefe751800d89d86.png\"\/><\/p>\n<div><figcaption>\u0412\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440 A-Frame<\/h3>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u0430\u043a <code>position<\/code>, <code>rotation<\/code>, <code>width<\/code>, <code>height<\/code>, <code>scale<\/code>, <code>radius<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0421\u0440\u0430\u0437\u0443 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043a\u0430\u043a\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D\u2011\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u00a0A\u2011Frame. \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 <strong>Ctrl + Alt + i<\/strong> \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0435 \u043e\u043a\u043d\u043e:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f44\/19f\/645\/f4419f64589f8f58f24f9fea2556ec23.png\" alt=\"\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440.\" title=\"\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440.\" width=\"2553\" height=\"1277\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f44\/19f\/645\/f4419f64589f8f58f24f9fea2556ec23.png\"\/><\/p>\n<div><figcaption>\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440.<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u00a0\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0438 \u043e\u0441\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u043a, \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u0412\u00a0\u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bd6\/460\/67e\/bd646067e84beb9061a824bb85447ab8.png\" alt=\" \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.\" title=\" \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.\" width=\"313\" height=\"273\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd6\/460\/67e\/bd646067e84beb9061a824bb85447ab8.png\"\/><\/p>\n<div><figcaption> \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u0430\u00a0\u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u00a0\u043a\u043e\u0434.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0446\u0435\u043d\u0443<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"json\">\"aframe\": \"^1.4.2\", \"react\": \"^18.2.0\", \"react-dom\": \"^18.2.0\"<\/code><\/pre>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 data.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043d\u0430\u0442 \u0432\u00a0\u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"javascript\">export default {   room_1: {     nameScense: 'room_1',     nextScense: [       {         position: '-2.110 -0.500 -5.990',         rotation: '0 0 0',         next: 'room_2'       }     ],     info: [       {         position: '-2.679 1.000 -1.201',         rotation: '0 90 0',         textModal: '\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0435\u0441\u0435\u043f\u0448\u0435\u043d'     ]   },   room_2: { ...<\/code><\/pre>\n<ul>\n<li>\n<p><code>nameScense<\/code>\u00a0\u2014 \u0438\u043c\u044f \u043a\u043e\u043c\u043d\u0430\u0442\u044b, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 360\u00a0\u00b0.<\/p>\n<\/li>\n<li>\n<p><code>nextScens<\/code>\u00a0\u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u0434\u043b\u044f\u00a0\u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432\u00a0\u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043d\u0430\u0442\u044b. \u0412\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u0432\u00a0\u043a\u0430\u043a\u0443\u044e \u043a\u043e\u043c\u043d\u0430\u0442\u0443 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c.<\/p>\n<\/li>\n<li>\n<p><code>info<\/code>\u00a0\u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u0435\u043a, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0442\u0435\u043a\u0441\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>state<\/code> \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">const [event, setEvent] = useState(data.room_1)<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0446\u0435\u043d\u0443:<\/p>\n<pre><code class=\"javascript\">&lt;a-scene cursor='rayOrigin: mouse;' raycaster='objects: .clickable'>   &lt;a-light type='ambient' \/>   &lt;a-sky      position='0 1 -10'      rotation='0 0 0'      src={`assets\/img\/${event.nameScense}.jpg`}     radius='50' \/> &lt;\/a-scene><\/code><\/pre>\n<p>\u0412\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b A\u2011Frame \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <code>\u0430\u2011<\/code>.<\/p>\n<ul>\n<li>\n<p><strong>a\u2011scene<\/strong>\u00a0\u2014 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0446\u0435\u043d\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>cursor<\/strong>\u00a0\u2014 \u0441\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>rayOrigin: mouse<\/code> \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 \u043d\u0430\u043c \u043a\u043b\u0438\u043a \u043f\u043e\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u043a\u0438, \u0431\u0435\u0437\u00a0\u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043b\u0438\u043a \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 <code>&lt;a-cursor><\/code><strong>,<\/strong> \u043e\u00a0\u043d\u0451\u043c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>raycaster<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0443 \u0441\u00a0\u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u0414\u043b\u044f\u00a0\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u044f \u0443\u043a\u0430\u0437\u0430\u043b \u043a\u043b\u0430\u0441\u0441 <code>.clickable<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0443 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 ,\u0441\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011light<\/strong>\u00a0\u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u0442\u0435\u043d\u044c\u044e. \u041f\u043e\u00a0\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e A\u2011Frame \u0441\u0430\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0435\u043d\u044c \u043d\u0430\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u043d\u0435 \u044d\u0442\u043e \u043d\u0435\u00a0\u043d\u0443\u0436\u043d\u043e, \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>type='ambient'<\/code> \u0441\u0434\u0435\u043b\u0430\u043b \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0439 \u0441\u0432\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c, \u0431\u0435\u0437\u00a0\u0442\u0435\u043d\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011sky<\/strong>\u00a0\u2014 \u0441\u0444\u0435\u0440\u0430, \u043d\u0430\u00a0\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043d\u0430\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 360\u00a0\u00b0.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>radius<\/code> \u0438 <code>position<\/code> \u043d\u0430\u0448\u0435\u0439 \u0441\u0444\u0435\u0440\u044b, \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e\u00a0\u043d\u0430\u0448\u0435\u0439 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u043a\u043e\u043c\u043d\u0430\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e81\/be0\/5dd\/e81be05dd6315b406019277f0899d252.png\" alt=\"\u0421\u0444\u0435\u0440\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c 360 \u00b0.\" title=\"\u0421\u0444\u0435\u0440\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c 360 \u00b0.\" width=\"1270\" height=\"1178\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e81\/be0\/5dd\/e81be05dd6315b406019277f0899d252.png\"\/><\/p>\n<div><figcaption>\u0421\u0444\u0435\u0440\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c 360 \u00b0.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0423\u00a0\u043c\u0435\u043d\u044f \u0432\u00a0\u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0438\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0438 \u0434\u043e\u00a0\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c\u00a0\u0431\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u044d\u0442\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u00a0A\u2011Frame \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0433 <code>&lt;a-assets><\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-assets timeout='5000'>   &lt;img id='info' src='assets\/img\/info.png' \/>   &lt;img id='vr' src='assets\/img\/vr.png' \/>   &lt;img id='arrow' src='assets\/img\/arrow.svg' \/> &lt;\/a-assets><\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011assets<\/strong>\u00a0\u2014 \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u0442\u0435\u0433\u0435 <code>&lt;img><\/code> \u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c ID, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 \u0438\u043d\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440.<\/p>\n<\/li>\n<li>\n<p><strong>timeout<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0436\u0434\u0451\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0446\u0435\u043d\u0443 \u043a\u0430\u043a\u00a0\u0435\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c<\/h3>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 Arrow.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">const Arrow = props => {   return (     &lt;a-image       class='clickable'       onClick={() => props.eventHandler(props.next)}       src='#arrow'       position={props.position}       rotation={props.rotation}       width='0.8'       height='0.65'       scale='1 1 1'     \/>   ) }  export default Arrow<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0448\u0438\u0440\u0438\u043d\u0443, \u0432\u044b\u0441\u043e\u0442\u0443 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 <code>width, height<\/code> \u0438 <code>scale<\/code><strong>.<\/strong><\/p>\n<ul>\n<li>\n<p><strong>a\u2011image<\/strong>\u00a0\u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043b\u043e\u0441\u043a\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>src<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0432 <code>&lt;a\u2011assets><\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>onClick<\/strong>\u00a0\u2014 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u043c \u0441\u0446\u0435\u043d\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>class=&#8217;clickable&#8217;<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u00a0\u0431\u044b\u043b \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439, \u043e\u00a0\u0447\u0451\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0446\u0435\u043d\u0443:<\/p>\n<pre><code class=\"javascript\">const eventHandler = event => {     setEvent(data[event])   }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c:<\/p>\n<pre><code class=\"javascript\">const getArrow = () => {   return event.nextScense.map(e => {     return (       &lt;Arrow          position={e.position}          rotation={e.rotation}          next={e.next}          eventHandler={eventHandler}          key={e.position} \/>     )   }) }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-scene><\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>{getArrow()}<\/code>, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u00a0\u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c.<\/p>\n<h3>\u0420\u0435\u0436\u0438\u043c VR<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c VR, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 <code>&lt;a-scene><\/code>. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 state <code>isVrMode<\/code> \u0438 \u0445\u0443\u043a <code>useRef<\/code> .<\/p>\n<pre><code class=\"javascript\">const [isVrMode, setVrMode] = useState(false) const scenesRef = useRef(null)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>ref<\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-scene ref={scenesRef} cursor='rayOrigin: mouse;' raycaster='objects: .clickable'><\/code><\/pre>\n<p>\u0412 <code>useEffect<\/code> \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0436\u0438\u043c\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">useEffect(() => {     isVrMode ? scenesRef?.current.enterVR() : scenesRef?.current.exitVR() }, [isVrMode])<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445 \u0444\u043b\u0430\u0433\u0430 <code>isVrMode<\/code> \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c <code>useEffect<\/code> \u0438 \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u0443 <code>&lt;a\u2011scene><\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0444\u043b\u0430\u0433. \u0414\u043b\u044f\u00a0\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0437\u0430\u00a0\u043a\u0430\u043c\u0435\u0440\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u043d\u0435\u00a0\u0438\u0441\u043a\u0430\u0442\u044c \u0433\u0434\u0435\u2011\u0442\u043e \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435. \u041f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-scene><\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-camera position='0 1 -1' rotation='0 0 0'>   &lt;a-image     class='clickable'     onClick={() => setVrMode(!isVrMode)}     src='#vr'     position='-1.5 2.7 -4'     rotation='0 0 0'     width='1'     height='1'   \/> &lt;\/a-camera><\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011camera<\/strong>\u00a0\u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0433\u043b\u0430\u0437\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412\u0441\u0451, \u0447\u0442\u043e\u00a0\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0432\u043d\u0443\u0442\u0440\u044c, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a <code>position: fixed<\/code> \u0432\u00a0CSS.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011image<\/strong>\u00a0\u2014 \u043f\u043e\u00a0\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438, \u043a\u0430\u043a\u00a0\u0434\u0435\u043b\u0430\u043b\u0438 \u0432\u00a0\u0441\u0442\u0440\u0435\u043b\u043a\u0430\u0445.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c VR-\u043a\u0443\u0440\u0441\u043e\u0440: \u0432\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-camera><\/code> \u043f\u0438\u0448\u0435\u043c <code>&lt;a-cursor \/><\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0443\u00a0\u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0435\u0447\u043a\u043e, \u0432\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f\u00a0VR-\u0440\u0435\u0436\u0438\u043c\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u043d\u043e\u00a0\u043c\u043e\u0436\u043d\u043e \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c. \u041d\u0430\u00a0\u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 VR-\u0440\u0435\u0436\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/6e7\/008\/362\/6e7008362dba924eea05493c48ce854f.jpg\" alt=\"VR-\u0440\u0435\u0436\u0438\u043c \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.\" title=\"VR-\u0440\u0435\u0436\u0438\u043c \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.\" width=\"1280\" height=\"605\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6e7\/008\/362\/6e7008362dba924eea05493c48ce854f.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>VR-\u0440\u0435\u0436\u0438\u043c \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u0435\u043a<\/h3>\n<p>\u0422\u0430\u0431\u043b\u0438\u0447\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u0430\u043a\u00a0\u0436\u0435, \u043a\u0430\u043a\u00a0\u0438 \u0441\u0442\u0440\u0435\u043b\u043a\u0438, \u043d\u043e\u00a0\u043f\u0440\u0438\u00a0\u043a\u043b\u0438\u043a\u0435 \u043d\u0430\u00a0\u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0451\u043d\u043d\u043e\u0435 \u043d\u0430\u00a0\u043a\u0430\u043c\u0435\u0440\u0435. \u0412\u00a0\u0444\u0430\u0439\u043b\u0435 Info.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439\u00a0\u0436\u0435, \u043a\u0430\u043a\u00a0\u0438 \u0443\u00a0\u0441\u0442\u0440\u0435\u043b\u043e\u043a:<\/p>\n<pre><code class=\"javascript\">const Info = props => {   return (     &lt;a-image       class='clickable'       onClick={() => props.openModal(props.text)}       src='#info'       position={props.position}       rotation={props.rotation}       width='0.75'       height='0.5'     \/>   ) }  export default Info<\/code><\/pre>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 Modal.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u043a\u043d\u043e:<\/p>\n<pre><code class=\"javascript\">const Modal = props => {   return (     &lt;a-rounded       position='-0.8 -0.3 -1.5'       width='1.5'       height='0.5'       color='#fff'       radius='0.07'       onClick={() => props.openModal()}       class='clickable'>       &lt;a-text         align='left'         position='0.1 0.3 0.007'         width='0.7'         wrap-count='40'         scale='2 2 1'         value={props.text}         font='assets\/fonts\/Regular.fnt'         color='black'       \/>     &lt;\/a-rounded>   ) }  export default Modal<\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011rounded<\/strong>\u00a0\u2014 \u043d\u0435\u00a0\u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u00a0A\u2011Frame, \u0435\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430, \u0443\u00a0\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u044c \u0443\u0433\u043b\u044b c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>radius<\/code>. \u0424\u043e\u043d \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c <code>color<\/code>.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"javascript\">\"aframe-rounded\": \"^1.0.3\"<\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011text<\/strong>\u00a0\u2014 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f\u00a0\u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430. \u0422\u0430\u043a \u043a\u0430\u043a\u00a0\u043e\u043d \u0432\u043b\u043e\u0436\u0435\u043d \u0432 <code>a-rounded<\/code>, \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0451\u0442 \u043e\u0442\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>align<\/strong>\u00a0\u2014 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u00a0\u043b\u0435\u0432\u043e\u043c\u0443 \u043a\u0440\u0430\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>wrap\u2011count<\/strong>\u00a0\u2014 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>font<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0448\u0440\u0438\u0444\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c state \u0434\u043b\u044f\u00a0\u043f\u043e\u043a\u0430\u0437\u0430 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442:<\/p>\n<pre><code class=\"javascript\">const [isOpenInfo, setOpenInfo] = useState(false) const [textModal, setTextModal] = useState('')<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>&lt;Info><\/code>:<\/p>\n<pre><code class=\"javascript\">const getInfo = () => {   return event?.info?.map(e => {     return (       &lt;Info          position={e.position}          rotation={e.rotation}          openModal={openModal}          text={e.textModal}          key={e.position} \/>     )   }) }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u044f\u0434\u043e\u043c \u0441 <code>getArrow()<\/code> \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>getInfo()<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043c\u0435\u043d\u044b \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u0440\u0438\u00a0\u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043c\u0435\u043d\u044f\u0435\u043c \u0444\u043b\u0430\u0433 <code>isOpenInfo<\/code>:<\/p>\n<pre><code class=\"javascript\">const openModal = textModal => {   setTextModal(textModal) }  useEffect(() => {   setOpenInfo(!!textModal) }, [textModal])<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-camera><\/code> \u043f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">{isOpenInfo ? &lt;Modal text={textModal} openModal={openModal} \/> : null}<\/code><\/pre>\n<p>\u0423\u00a0\u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a\u043e\u0435 \u043e\u043a\u043d\u043e \u0441\u00a0\u0442\u0435\u043a\u0441\u0442\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/054\/ae4\/7b8\/054ae47b81a0f13ce010553f4528606f.png\" alt=\"\u041e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e.\" title=\"\u041e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e.\" width=\"1441\" height=\"867\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/054\/ae4\/7b8\/054ae47b81a0f13ce010553f4528606f.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>A\u2011Frame\u00a0\u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f VR-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f\u043c\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 VR\u2011\u0442\u0443\u0440 \u0441\u00a0\u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u00a0\u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043e\u043c \u0432\u00a0\u0432\u0438\u0434\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u0435\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f44\/485\/5ad\/f444855ada796caeaadef973b71a10ad.gif\" alt=\"\u0417\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" title=\"\u0417\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" width=\"600\" height=\"307\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f44\/485\/5ad\/f444855ada796caeaadef973b71a10ad.gif\"\/><\/p>\n<div><figcaption>\u0417\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 A\u2011Frame \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0442\u0435\u0445\u00a0\u0436\u0435 \u0438\u0433\u0440. \u0418 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441\u00a0\u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a\u00a0Angular \u0438 Vue.<\/p>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/egormolchanov\/A-frame-360-tour\">GitHub<\/a>.<\/p>\n<\/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\/791790\/\"> https:\/\/habr.com\/ru\/articles\/791790\/<\/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<figure class=\"full-width\"><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0415\u0433\u043e\u0440 \u041c\u043e\u043b\u0447\u0430\u043d\u043e\u0432, \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432\u00a0\u043a\u043e\u043c\u0430\u043d\u0434\u0435 CRM \u0434\u043b\u044f\u00a0\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u0432 \u0438\u043f\u043e\u0442\u0435\u0447\u043d\u043e\u0433\u043e \u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u00a0\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0414\u043e\u043c\u043a\u043b\u0438\u043a. \u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f VR\u2011\u0442\u0443\u0440\u0430 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 A\u2011Frame \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 React. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 pet\u2011\u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c.<\/p>\n<h3>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b<\/h3>\n<p><a href=\"https:\/\/aframe.io\/\">A\u2011Frame<\/a>\u00a0\u2014 \u044d\u0442\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 VR\u2011\u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041e\u043d \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430\u00a0HTML, \u0447\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443. \u0423\u00a0\u043d\u0435\u0433\u043e \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043d\u0435\u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u00a0\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f<br \/>\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d \u043d\u0430\u00a0\u0447\u0438\u0441\u0442\u043e\u043c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/WebGL\">WebGL<\/a>, \u0432\u00a0\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0438\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/threejs.org\/\">Three.js<\/a>. \u041e\u043d \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0441\u0446\u0435\u043d\u0443 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a\u00a0\u0446\u0438\u043b\u0438\u043d\u0434\u0440, \u043a\u0443\u0431 \u0438\u043b\u0438\u00a0\u0441\u0444\u0435\u0440\u0430.<\/p>\n<p><a href=\"https:\/\/react.dev\/\">React<\/a>\u00a0\u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432.<\/p>\n<h3>\u0422\u0417 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u0439\u0442, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e\u00a0\u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u044f\u043c, \u043f\u043e\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0433\u043e\u043b\u043e\u0432\u043e\u0439 \u043d\u0430 360\u00a0\u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432, \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0438 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437\u00a0VR-\u0440\u0435\u0436\u0438\u043c\u0430.<\/p>\n<h3>\u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435<\/h3>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438. \u041d\u0430\u00a0\u0441\u0430\u0439\u0442\u0435 \u0441\u00a0\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432\u00a0\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442. \u0414\u043b\u044f\u00a0\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432\u00a0A\u2011Frame, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>position<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b (x, y, z), \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u043e\u0442\u00a0\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 (0, 0, 0), \u043a\u0430\u043a\u00a0\u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430\u00a0\u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0422\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/figcaption><\/div>\n<\/figure>\n<p>Three.js \u0438 WebGL \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u00a0\u0438\u043c\u0435\u044e\u0442 \u0435\u0434\u0438\u043d\u0438\u0446 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f, \u043d\u043e\u00a0\u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0432\u043d\u043e\u0439 \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u0440\u0443. <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>rotation<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u00a0\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438 \u043f\u043e\u00a0\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c (x, y, z). \u0415\u0434\u0438\u043d\u0438\u0446\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u00a0\u2014 \u0433\u0440\u0430\u0434\u0443\u0441\u044b.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0412\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u043e\u0435\u0439 \u043e\u0441\u0438.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440 A-Frame<\/h3>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u0430\u043a <code>position<\/code>, <code>rotation<\/code>, <code>width<\/code>, <code>height<\/code>, <code>scale<\/code>, <code>radius<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0421\u0440\u0430\u0437\u0443 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043a\u0430\u043a\u00a0\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D\u2011\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u00a0A\u2011Frame. \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 <strong>Ctrl + Alt + i<\/strong> \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0435 \u043e\u043a\u043d\u043e:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 3D-\u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440.<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u00a0\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0438 \u043e\u0441\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u043a, \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u0412\u00a0\u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432.<\/p>\n<figure class=\"\">\n<div><figcaption> \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u00a0\u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u0430\u00a0\u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u00a0\u043a\u043e\u0434.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0446\u0435\u043d\u0443<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"json\">\"aframe\": \"^1.4.2\", \"react\": \"^18.2.0\", \"react-dom\": \"^18.2.0\"<\/code><\/pre>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 data.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043d\u0430\u0442 \u0432\u00a0\u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"javascript\">export default {   room_1: {     nameScense: 'room_1',     nextScense: [       {         position: '-2.110 -0.500 -5.990',         rotation: '0 0 0',         next: 'room_2'       }     ],     info: [       {         position: '-2.679 1.000 -1.201',         rotation: '0 90 0',         textModal: '\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0435\u0441\u0435\u043f\u0448\u0435\u043d'     ]   },   room_2: { ...<\/code><\/pre>\n<ul>\n<li>\n<p><code>nameScense<\/code>\u00a0\u2014 \u0438\u043c\u044f \u043a\u043e\u043c\u043d\u0430\u0442\u044b, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 360\u00a0\u00b0.<\/p>\n<\/li>\n<li>\n<p><code>nextScens<\/code>\u00a0\u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u0434\u043b\u044f\u00a0\u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432\u00a0\u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043d\u0430\u0442\u044b. \u0412\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u0432\u00a0\u043a\u0430\u043a\u0443\u044e \u043a\u043e\u043c\u043d\u0430\u0442\u0443 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c.<\/p>\n<\/li>\n<li>\n<p><code>info<\/code>\u00a0\u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u0435\u043a, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0442\u0435\u043a\u0441\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>state<\/code> \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">const [event, setEvent] = useState(data.room_1)<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0446\u0435\u043d\u0443:<\/p>\n<pre><code class=\"javascript\">&lt;a-scene cursor='rayOrigin: mouse;' raycaster='objects: .clickable'>   &lt;a-light type='ambient' \/>   &lt;a-sky      position='0 1 -10'      rotation='0 0 0'      src={`assets\/img\/${event.nameScense}.jpg`}     radius='50' \/> &lt;\/a-scene><\/code><\/pre>\n<p>\u0412\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b A\u2011Frame \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <code>\u0430\u2011<\/code>.<\/p>\n<ul>\n<li>\n<p><strong>a\u2011scene<\/strong>\u00a0\u2014 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0446\u0435\u043d\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>cursor<\/strong>\u00a0\u2014 \u0441\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>rayOrigin: mouse<\/code> \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 \u043d\u0430\u043c \u043a\u043b\u0438\u043a \u043f\u043e\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u043a\u0438, \u0431\u0435\u0437\u00a0\u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043b\u0438\u043a \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 <code>&lt;a-cursor><\/code><strong>,<\/strong> \u043e\u00a0\u043d\u0451\u043c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>raycaster<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0443 \u0441\u00a0\u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u0414\u043b\u044f\u00a0\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u044f \u0443\u043a\u0430\u0437\u0430\u043b \u043a\u043b\u0430\u0441\u0441 <code>.clickable<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0443 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 ,\u0441\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011light<\/strong>\u00a0\u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u0442\u0435\u043d\u044c\u044e. \u041f\u043e\u00a0\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e A\u2011Frame \u0441\u0430\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0435\u043d\u044c \u043d\u0430\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445 \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u043d\u0435 \u044d\u0442\u043e \u043d\u0435\u00a0\u043d\u0443\u0436\u043d\u043e, \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>type='ambient'<\/code> \u0441\u0434\u0435\u043b\u0430\u043b \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0439 \u0441\u0432\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c, \u0431\u0435\u0437\u00a0\u0442\u0435\u043d\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011sky<\/strong>\u00a0\u2014 \u0441\u0444\u0435\u0440\u0430, \u043d\u0430\u00a0\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043d\u0430\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 360\u00a0\u00b0.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>radius<\/code> \u0438 <code>position<\/code> \u043d\u0430\u0448\u0435\u0439 \u0441\u0444\u0435\u0440\u044b, \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e\u00a0\u043d\u0430\u0448\u0435\u0439 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0432\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u00a0\u043a\u043e\u043c\u043d\u0430\u0442\u044b.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u0444\u0435\u0440\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c 360 \u00b0.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0423\u00a0\u043c\u0435\u043d\u044f \u0432\u00a0\u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0438\u00a0\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0438 \u0434\u043e\u00a0\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c\u00a0\u0431\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u044d\u0442\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u00a0A\u2011Frame \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0433 <code>&lt;a-assets><\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-assets timeout='5000'>   &lt;img id='info' src='assets\/img\/info.png' \/>   &lt;img id='vr' src='assets\/img\/vr.png' \/>   &lt;img id='arrow' src='assets\/img\/arrow.svg' \/> &lt;\/a-assets><\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011assets<\/strong>\u00a0\u2014 \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u0442\u0435\u0433\u0435 <code>&lt;img><\/code> \u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c ID, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 \u0438\u043d\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440.<\/p>\n<\/li>\n<li>\n<p><strong>timeout<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0436\u0434\u0451\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0446\u0435\u043d\u0443 \u043a\u0430\u043a\u00a0\u0435\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c<\/h3>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 Arrow.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">const Arrow = props => {   return (     &lt;a-image       class='clickable'       onClick={() => props.eventHandler(props.next)}       src='#arrow'       position={props.position}       rotation={props.rotation}       width='0.8'       height='0.65'       scale='1 1 1'     \/>   ) }  export default Arrow<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0448\u0438\u0440\u0438\u043d\u0443, \u0432\u044b\u0441\u043e\u0442\u0443 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 <code>width, height<\/code> \u0438 <code>scale<\/code><strong>.<\/strong><\/p>\n<ul>\n<li>\n<p><strong>a\u2011image<\/strong>\u00a0\u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043b\u043e\u0441\u043a\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>src<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0432 <code>&lt;a\u2011assets><\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>onClick<\/strong>\u00a0\u2014 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u043c \u0441\u0446\u0435\u043d\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>class=&#8217;clickable&#8217;<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u00a0\u0431\u044b\u043b \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439, \u043e\u00a0\u0447\u0451\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0446\u0435\u043d\u0443:<\/p>\n<pre><code class=\"javascript\">const eventHandler = event => {     setEvent(data[event])   }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c:<\/p>\n<pre><code class=\"javascript\">const getArrow = () => {   return event.nextScense.map(e => {     return (       &lt;Arrow          position={e.position}          rotation={e.rotation}          next={e.next}          eventHandler={eventHandler}          key={e.position} \/>     )   }) }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-scene><\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>{getArrow()}<\/code>, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u00a0\u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c.<\/p>\n<h3>\u0420\u0435\u0436\u0438\u043c VR<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c VR, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 <code>&lt;a-scene><\/code>. \u0414\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 state <code>isVrMode<\/code> \u0438 \u0445\u0443\u043a <code>useRef<\/code> .<\/p>\n<pre><code class=\"javascript\">const [isVrMode, setVrMode] = useState(false) const scenesRef = useRef(null)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>ref<\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-scene ref={scenesRef} cursor='rayOrigin: mouse;' raycaster='objects: .clickable'><\/code><\/pre>\n<p>\u0412 <code>useEffect<\/code> \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0436\u0438\u043c\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">useEffect(() => {     isVrMode ? scenesRef?.current.enterVR() : scenesRef?.current.exitVR() }, [isVrMode])<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445 \u0444\u043b\u0430\u0433\u0430 <code>isVrMode<\/code> \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c <code>useEffect<\/code> \u0438 \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u0443 <code>&lt;a\u2011scene><\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0444\u043b\u0430\u0433. \u0414\u043b\u044f\u00a0\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0437\u0430\u00a0\u043a\u0430\u043c\u0435\u0440\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u043d\u0435\u00a0\u0438\u0441\u043a\u0430\u0442\u044c \u0433\u0434\u0435\u2011\u0442\u043e \u0432\u00a0\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435. \u041f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-scene><\/code>:<\/p>\n<pre><code class=\"javascript\">&lt;a-camera position='0 1 -1' rotation='0 0 0'>   &lt;a-image     class='clickable'     onClick={() => setVrMode(!isVrMode)}     src='#vr'     position='-1.5 2.7 -4'     rotation='0 0 0'     width='1'     height='1'   \/> &lt;\/a-camera><\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011camera<\/strong>\u00a0\u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0433\u043b\u0430\u0437\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412\u0441\u0451, \u0447\u0442\u043e\u00a0\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0432\u043d\u0443\u0442\u0440\u044c, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a <code>position: fixed<\/code> \u0432\u00a0CSS.<\/p>\n<\/li>\n<li>\n<p><strong>a\u2011image<\/strong>\u00a0\u2014 \u043f\u043e\u00a0\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438, \u043a\u0430\u043a\u00a0\u0434\u0435\u043b\u0430\u043b\u0438 \u0432\u00a0\u0441\u0442\u0440\u0435\u043b\u043a\u0430\u0445.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c VR-\u043a\u0443\u0440\u0441\u043e\u0440: \u0432\u043d\u0443\u0442\u0440\u0438 <code>&lt;a-camera><\/code> \u043f\u0438\u0448\u0435\u043c <code>&lt;a-cursor \/><\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0443\u00a0\u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0435\u0447\u043a\u043e, \u0432\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f\u00a0VR-\u0440\u0435\u0436\u0438\u043c\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u043d\u043e\u00a0\u043c\u043e\u0436\u043d\u043e \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c. \u041d\u0430\u00a0\u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 VR-\u0440\u0435\u0436\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>VR-\u0440\u0435\u0436\u0438\u043c \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u0435\u043a<\/h3>\n<p>\u0422\u0430\u0431\u043b\u0438\u0447\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u0430\u043a\u00a0\u0436\u0435, \u043a\u0430\u043a\u00a0\u0438 \u0441\u0442\u0440\u0435\u043b\u043a\u0438, \u043d\u043e\u00a0\u043f\u0440\u0438\u00a0\u043a\u043b\u0438\u043a\u0435 \u043d\u0430\u00a0\u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0451\u043d\u043d\u043e\u0435 \u043d\u0430\u00a0\u043a\u0430\u043c\u0435\u0440\u0435. \u0412\u00a0\u0444\u0430\u0439\u043b\u0435 Info.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439\u00a0\u0436\u0435, \u043a\u0430\u043a\u00a0\u0438 \u0443\u00a0\u0441\u0442\u0440\u0435\u043b\u043e\u043a:<\/p>\n<pre><code class=\"javascript\">const Info = props => {   return (     &lt;a-image       class='clickable'       onClick={() => props.openModal(props.text)}       src='#info'       position={props.position}       rotation={props.rotation}       width='0.75'       height='0.5'     \/>   ) }  export default Info<\/code><\/pre>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 Modal.js \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u043a\u043d\u043e:<\/p>\n<pre><code class=\"javascript\">const Modal = props => {   return (     &lt;a-rounded       position='-0.8 -0.3 -1.5'       width='1.5'       height='0.5'       color='#fff'       radius='0.07'       onClick={() => props.openModal()}       class='clickable'>       &lt;a-text         align='left'         position='0.1 0.3 0.007'         width='0.7'         wrap-count='40'         scale='2 2 1'         value={props.text}         font='assets\/fonts\/Regular.fnt'         color='black'       \/>     &lt;\/a-rounded>   ) }  export default Modal<\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011rounded<\/strong>\u00a0\u2014 \u043d\u0435\u00a0\u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u00a0A\u2011Frame, \u0435\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430, \u0443\u00a0\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u044c \u0443\u0433\u043b\u044b c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>radius<\/code>. \u0424\u043e\u043d \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c <code>color<\/code>.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"javascript\">\"aframe-rounded\": \"^1.0.3\"<\/code><\/pre>\n<ul>\n<li>\n<p><strong>a\u2011text<\/strong>\u00a0\u2014 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f\u00a0\u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0430. \u0422\u0430\u043a \u043a\u0430\u043a\u00a0\u043e\u043d \u0432\u043b\u043e\u0436\u0435\u043d \u0432 <code>a-rounded<\/code>, \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0451\u0442 \u043e\u0442\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>align<\/strong>\u00a0\u2014 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u00a0\u043b\u0435\u0432\u043e\u043c\u0443 \u043a\u0440\u0430\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>wrap\u2011count<\/strong>\u00a0\u2014 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>font<\/strong>\u00a0\u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0448\u0440\u0438\u0444\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u00a0\u0444\u0430\u0439\u043b\u0435 App.js \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c state \u0434\u043b\u044f\u00a0\u043f\u043e\u043a\u0430\u0437\u0430 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0435\u0433\u043e \u0442\u0435\u043a\u0441\u0442:<\/p>\n<pre><code class=\"javascript\">const [isOpenInfo, setOpenInfo] = useState(false) const [textModal, setTextModal] = useState('')<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>&lt;Info><\/code>:<\/p>\n<pre><code class=\"javascript\">const getInfo = () => {   return event?.info?.map(e => {     return (       &lt;Info          position={e.position}          rotation={e.rotation}          openModal={openModal}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-367454","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/367454","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=367454"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/367454\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=367454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=367454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=367454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}