OffscreenCanvas рдФрд░ рд╡реЗрдм рд╡рд░реНрдХрд░реНрд╕ рдХреЗ рд╕рд╛рде WebGL / Three.js рдХреЛ рдЧрддрд┐ рджреЗрдирд╛

OffscreenCanvas рдФрд░ рд╡реЗрдм рд╡рд░реНрдХрд░реНрд╕ рдХреЗ рд╕рд╛рде WebGL / Three.js рдХреЛ рдЧрддрд┐ рджреЗрдирд╛

рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рдореИрдВ рдЖрдкрдХреЛ OffscreenCanvas рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ, OffscreenCanvas рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП OffscreenCanvas рдореИрдВрдиреЗ рд╡реЗрдмрдЬреАрдПрд▓ рдФрд░ рдереНрд░реА.рдЬреЗрдПрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╡реЗрдм рд╡рд░реНрдХрд░ рдереНрд░реЗрдб рдореЗрдВ рд╕рднреА рдХреЛрдб рдбрд╛рд▓рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдмреА рд╣рд╛рд╕рд┐рд▓ рдХреАред рдЗрд╕рд╕реЗ рд╕рд╛рдЗрдЯ рдХрд╛ рдХрд╛рдо рддреЗрдЬ рд╣реЛ рдЧрдпрд╛ рдФрд░ рдкреЗрдЬ рд▓реЛрдбрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдХрдордЬреЛрд░ рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдлреНрд░рд┐рдЬреАрдЬрд╝ рдЧрд╛рдпрдм рд╣реЛ рдЧрдПред

рд▓реЗрдЦ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЕрдиреБрднрд╡ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрдм рдореИрдВрдиреЗ рдЕрдкрдиреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдШреВрд░реНрдгрди 3 рдбреА рдкреГрдереНрд╡реА рдХреЛ рдЬреЛрдбрд╝рд╛ рдФрд░ Google рд▓рд╛рдЗрдЯрд╣рд╛рдЙрд╕ рдореЗрдВ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХреЗ 5 рдЕрдВрдХ рд▓рд┐рдП - рдЖрд╕рд╛рди рд╢реЛ-рдСрдл рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХред

рд╕рдорд╕реНрдпрд╛


рддреАрди.рдЬреЗрдПрд╕ рдмрд╣реБрдд рд╕реЗ рдЬрдЯрд┐рд▓ рд╡реЗрдмрдЬреАрдПрд▓ рдореБрджреНрджреЛрдВ рдХреЛ рдЫреБрдкрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рдПрдХ рдЧрдВрднреАрд░ рдХреАрдордд рд╣реИ - рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рдЬреЗрдПрд╕ рдмрд┐рд▓реНрдб рдореЗрдВ 563 рдХреЗрдмреА рдЬреЛрдбрд╝рддрд╛ рд╣реИ (рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ trichashing рдХреЛ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ)ред

рдХреБрдЫ рд▓реЛрдЧ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЪрд┐рддреНрд░реЛрдВ рдХрд╛ рд╡рдЬрди рдЕрдХреНрд╕рд░ 500 рдХреЗрдмреА рд╣реЛрддрд╛ рд╣реИ - рдФрд░ рдпрд╣ рдмрд╣реБрдд рдЧрд▓рдд рд╣реЛрдЧрд╛ред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ KB рдЫрд╡рд┐ рдХреЗ KB рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИред рдХрд┐рд╕реА рд╕рд╛рдЗрдЯ рдХреЗ рддреЗрдЬрд╝ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рди рдХреЗрд╡рд▓ рдЪреИрдирд▓ рдХреА рдЪреМрдбрд╝рд╛рдИ рдФрд░ рд╡рд┐рд▓рдВрдм рд╕рдордп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рд╣реЛрдЧрд╛ - рдЖрдкрдХреЛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХрдВрдкреНрдпреВрдЯрд░ рдХреЗ рд╕реАрдкреАрдпреВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рд╕рдордп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рд╕реЛрдЪрдирд╛ рд╣реЛрдЧрд╛ред рдлреЛрди рдФрд░ рдХрдордЬреЛрд░ рд▓реИрдкрдЯреЙрдк рдкрд░, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд▓реЛрдб рд╣реЛрдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рд▓реЗ рд╕рдХрддрд╛ рд╣реИред

170K рдЬреЗрдПрд╕ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ 170K рдЫрд╡рд┐ рдХреЗ рд▓рд┐рдП 3.5 рд╕реЗрдХрдВрдб рдмрдирд╛рдо 0.1 рд╕реЗрдХрдВрдб рд▓рдЧрддреЗ рд╣реИрдВ
170K рдЬреЗрдПрд╕ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг 170K рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП 3.5 рд╕реЗрдХрдВрдб рдмрдирд╛рдо 0.1 рд╕реЗрдХрдВрдб рд▓реЗрддрд╛ рд╣реИ - рдПрдбреА рдЙрд╕реНрдорд╛рдиреА

рдЬрдмрдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ 500 KB рддреАрди.js рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛, рдореБрдЦреНрдп рдкреГрд╖реНрда рдкреНрд░рд╡рд╛рд╣ рдЕрд╡рд░реБрджреНрдз рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдлреНрд░рд┐рдЬрд╝ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред

рд╡реЗрдм рд╡рд░реНрдХрд░реНрд╕ рдФрд░ рдСрдлрд╕реНрдХреНрд░реАрди рдХреИрдирд╡рд╛рд╕


рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЬреЗрдПрд╕ рдХреЗ рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рджреМрд░рд╛рди рдлреНрд░рд┐рдЬрд╝ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ - рдПрдХ рдЕрд▓рдЧ рдзрд╛рдЧреЗ рдореЗрдВ рдХреЛрдб рдЪрд▓рд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ред

рддрд╛рдХрд┐ рд╡реЗрдм рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдорд▓реНрдЯреАрдереНрд░реЗрдбреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдирд░рдХ рдореЗрдВ рдмрджрд▓ рди рдЬрд╛рдПрдВ, рдПрдХ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреА рдбреЛрдо рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИред рдХреЗрд╡рд▓ рдореБрдЦреНрдп рдереНрд░реЗрдб HTML рдкреЗрдЬ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди DOM рддрдХ рдкрд╣реБрдБрдЪ рдХреЗ рдмрд┐рдирд╛ Three.js рдХреИрд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ, рдЬрд┐рд╕реЗ <canvas> рддрдХ рд╕реАрдзреА рдкрд╣реБрдБрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдСрдлрд╝рд╕реНрдХреНрд░реАрдирдХреИрдирд╡рд╛рд╕ рд╣реИ - рдпрд╣ рдЖрдкрдХреЛ рдПрдХ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ <canvas> рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдмрд╣реБрд╕реНрддрд░реАрдп рдирд░рдХ рдХреЗ рджреНрд╡рд╛рд░ рдирд╣реАрдВ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рдмрд╛рдж, рдореБрдЦреНрдп рдзрд╛рдЧрд╛ рдЗрд╕ <canvas> рддрдХ рдкрд╣реБрдВрдЪ рдЦреЛ рджреЗрддрд╛ рд╣реИ - рдХреЗрд╡рд▓ рдПрдХ рдзрд╛рдЧрд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд▓рдХреНрд╖реНрдп рдХреЗ рдХрд░реАрдм рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдХреЗрд╡рд▓ рдХреНрд░реЛрдо OffscreenCanvas рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

рдХреЗрд╡рд▓ Chrome рдСрдлрд╝рд╕реНрдХреНрд░реАрди рд╕реНрдХреНрд░реАрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ
рдХреИрди I рдпреВрдЬрд╝ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдкреНрд░реИрд▓ 2019 рдХреЗ рд▓рд┐рдП рдСрдлрд╝рд╕реНрдХреНрд░реАрди рдХреИрдиреНрд╡рд╛рд╕ рд╕рдорд░реНрдерди

рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рднреА, рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдореБрдЦреНрдп рджреБрд╢реНрдорди, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рдордиреЗ, рд╣рдореЗрдВ рд╣рд╛рд░ рдирд╣реАрдВ рдорд╛рдирдиреА рдЪрд╛рд╣рд┐рдПред рд╣рдо рдПрдХ рд╕рд╛рде рдорд┐рд▓рддреЗ рд╣реИрдВ рдФрд░ рдкрд╣реЗрд▓реА рдХреЗ рдЕрдВрддрд┐рдо рддрддреНрд╡ рдХреЛ рдвреВрдВрдврддреЗ рд╣реИрдВ - рдпрд╣ "рдкреНрд░рдЧрддрд┐рд╢реАрд▓ рд╕реБрдзрд╛рд░" рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрджрд░реНрд╢ рдорд╛рдорд▓рд╛ рд╣реИред рдХреНрд░реЛрдо рдФрд░ рднрд╡рд┐рд╖реНрдп рдХреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ, рд╣рдо рдлреНрд░рд┐рдЬрд╝ рдХреЛ рд╣рдЯрд╛ рджреЗрдВрдЧреЗ, рдФрд░ рдЕрдиреНрдп рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред

рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдПрдХ рдлрд╛рдЗрд▓ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИ - рдПрдХ рд╡реЗрдм рдХрд░реНрдордЪрд╛рд░реА рдФрд░ рдПрдХ рдирд┐рдпрдорд┐рдд рдореБрдЦреНрдп рдЬреЗрдПрд╕ рд╕реНрдЯреНрд░реАрдо рдореЗрдВред

рдирд┐рд░реНрдгрдп


рдЪреАрдиреА рдХреА рдПрдХ рдкрд░рдд рдХреЗ рдиреАрдЪреЗ рд╣реИрдХреНрд╕ рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ 400 рдмрд╛рдЗрдЯреНрд╕ (!) рдХреА рдПрдХ рдЫреЛрдЯреА рдСрдлрд╕реНрдХреНрд░реАрди-рдХреИрдирд╡рд╕ рдЬреЗрдПрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдмрдирд╛рдИред рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдХреЛрдб рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ "рд╣реБрдб рдХреЗ рдиреАрдЪреЗред"

рдЪрд▓реЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░реЗрдВ:

 npm install offscreen-canvas 

рд╣рдореЗрдВ рд╡реЗрдм рдХрд░реНрдордЪрд╛рд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ JS рдлрд╛рдЗрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - Webpack рдпрд╛ Parcel рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдЕрд╕реЗрдВрдмрд▓реА рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:

  entry: { 'app': './src/app.js', + 'webgl-worker': './src/webgl-worker.js' } 

рдХрд▓реЗрдХреНрдЯрд░ рдХреИрд╢рд▓реЗрдпрд░ рдХреЗ рдХрд╛рд░рдг рддреИрдирд╛рддреА рдХреЗ рджреМрд░рд╛рди рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рд▓рдЧрд╛рддрд╛рд░ рдмрджрд▓рддреЗ рд░рд╣реЗрдВрдЧреЗ - рд╣рдореЗрдВ рдкреНрд░реА рд▓реЛрдб рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ HTML рдореЗрдВ рдирд╛рдо рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣рд╛рдВ рдЙрджрд╛рд╣рд░рдг рдЕрдореВрд░реНрдд рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдЖрдкрдХреЗ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдкрд░ рдмрд╣реБрдд рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛ред

  <link type="preload" as="script" href="./webgl-worker.js"> </head> 

рдЕрдм рд╣рдореЗрдВ <canvas> JS <canvas> рд▓рд┐рдП DOM рдиреЛрдб рдФрд░ рдореБрдЦреНрдп JS рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкреНрд░реАрд▓реЛрдб рдЯреИрдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 import createWorker from 'offscreen-canvas/create-worker' const workerUrl = document.querySelector('[rel=preload][as=script]').href const canvas = document.querySelector('canvas') const worker = createWorker(canvas, workerUrl) 

createWorker рдЕрдЧрд░ рд╡рд╣рд╛рдБ рд╣реИред canvas.transferControlToOffscreen рдЬреЗрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╡реЗрдм рд╡рд░реНрдХрд░ рдореЗрдВ рд▓реЛрдб рдХрд░ canvas.transferControlToOffscreen ред рдФрд░ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ - рдПрдХ рдирд┐рдпрдорд┐рдд <script> ред

рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕ webgl-worker.js рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рдмрдирд╛рдПрдБ:

 import insideWorker from 'offscreen-canvas/inside-worker' const worker = insideWorker(e => { if (e.data.canvas) { //       <canvas> } }) 

рдЕрдВрджрд░ рджреЗрдЦрдиреЗ рд╡рд╛рд▓рд╛ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рд╡реЗрдм рдХрд░реНрдордЪрд╛рд░реА рдХреЗ рдЕрдВрджрд░ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╣ рдореБрдЦреНрдп рдереНрд░реЗрдб рдХреЗ рд╕рд╛рде рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдЪрд╛рд░ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░реЗрдЧрд╛ред

рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореБрдЦреНрдп рдзрд╛рдЧреЗ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдирдП рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП insideWorker рдПрдХ рдлрд╝рдВрдХреНрд╢рди insideWorker ред рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж, createWorker <canvas> рдкрд░ рдкрд╣рд▓рд╛ рдлреНрд░реЗрдо рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рд╕рдВрджреЗрд╢ { canvas, width, height } рднреЗрдЬреЗрдЧрд╛ред

 + import { + WebGLRenderer, Scene, PerspectiveCamera, AmbientLight, + Mesh, SphereGeometry, MeshPhongMaterial + } from 'three' import insideWorker from 'offscreen-canvas/inside-worker' + const scene = new Scene() + const camera = new PerspectiveCamera(45, 1, 0.01, 1000) + scene.add(new AmbientLight(0x909090)) + + let sphere = new Mesh( + new SphereGeometry(0.5, 64, 64), + new MeshPhongMaterial() + ) + scene.add(sphere) + + let renderer + function render () { + renderer.render(scene, camera) + } const worker = insideWorker(e => { if (e.data.canvas) { + // canvas  -    тАФ    ,     Three.js + if (!canvas.style) canvas.style = { width, height } + renderer = new WebGLRenderer({ canvas, antialias: true }) + renderer.setPixelRatio(pixelRatio) + renderer.setSize(width, height) + + render() } }) 

рдЬрдм рдЖрдк рдЕрдкрдиреЗ рдкреБрд░рд╛рдиреЗ рдХреЛрдб рдХреЛ рдХрд┐рд╕реА рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рддреАрди.js рдХреЗ рд▓рд┐рдП рдкреЛрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддреА рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ DOM API рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, SVG рдмрдирд╛рд╡рдЯ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ document.createElement рдирд╣реАрдВ рд╣реИред рддреЛ, рдХрднреА-рдХрднреА рд╣рдореЗрдВ рдПрдХ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдФрд░ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдЕрдВрджрд░ рд╡рд┐рднрд┐рдиреНрди рд▓реЛрдбрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ worker.isWorker рд╣реИрдВред worker.isWorker :

  renderer.setPixelRatio(pixelRatio) renderer.setSize(width, height) + const loader = worker.isWorker ? new ImageBitmapLoader() : new ImageLoader() + loader.load('/texture.png', mapImage => { + sphere.material.map = new CanvasTexture(mapImage) + render() + }) render() 

рд╣рдордиреЗ рдкрд╣рд▓рд╛ рдлреНрд░реЗрдо рдЦреАрдВрдЪрд╛ред рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ WebGL рджреГрд╢реНрдпреЛрдВ рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпреЛрдВ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреИрдорд░рд╛ рдШреБрдорд╛рдПрдБ рдЬрдм рдХрд░реНрд╕рд░ рдЪрд▓рддрд╛ рд╣реИ рдпрд╛ рдЦрд┐рдбрд╝рдХреА рдХреЗ рдЖрдХрд╛рд░ рдмрджрд▓рдиреЗ рдкрд░ рдПрдХ рдлреНрд░реЗрдо рдЦреАрдВрдЪрддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ DOM рдЗрд╡реЗрдВрдЯреНрд╕ рдХреЛ рдирд╣реАрдВ рд╕реБрди рд╕рдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдореБрдЦреНрдп рдзрд╛рд░рд╛ рдореЗрдВ рд╕реБрдирдиреЗ рдФрд░ рд╡реЗрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

  import createWorker from 'offscreen-canvas/create-worker' const workerUrl = document.querySelector('[rel=preload][as=script]').href const canvas = document.querySelector('canvas') const worker = createWorker(canvas, workerUrl) + window.addEventListener('resize', () => { + worker.post({ + type: 'resize', width: canvas.clientWidth, height: canvas.clientHeight + }) + }) 

  const worker = insideWorker(e => { if (e.data.canvas) { if (!canvas.style) canvas.style = { width, height } renderer = new WebGLRenderer({ canvas, antialias: true }) renderer.setPixelRatio(pixelRatio) renderer.setSize(width, height) const loader = worker.isWorker ? new ImageBitmapLoader() : new ImageLoader() loader.load('/texture.png', mapImage => { sphere.material.map = new CanvasTexture(mapImage) render() }) render() - } + } else if (e.data.type === 'resize') { + renderer.setSize(width, height) + render() + } }) 

рдкрд░рд┐рдгрд╛рдо


OffscreenCanvas рд╕рд╛рде OffscreenCanvas рдореИрдВрдиреЗ рдЕрдкрдиреА рд╕рд╛рдЗрдЯ рдкрд░ рдлреНрд░рд┐рдЬрд╝ рдХреЛ рд╣рд░рд╛рдпрд╛ рдФрд░ Google рд▓рд╛рдЗрдЯрд╣рд╛рдЙрд╕ рдкрд░ 100% рдЕрдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдПред рдФрд░ рд╡реЗрдмрдЬреАрдПрд▓ рд╕рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ OffscreenCanvas рд╕рдорд░реНрдерди рдХреЗ рдмрд┐рдирд╛ рднреАред

рдЖрдк рд▓рд╛рдЗрд╡ рд╕рд╛рдЗрдЯ рдФрд░ рдореБрдЦреНрдп рдзрд╛рдЧреЗ рдпрд╛ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред


рдСрдлрд╝рд╕реНрдХреНрд░реАрдирдХреИрдирд╡рд╛рд╕ рдХреЗ рд╕рд╛рде, Google рд▓рд╛рдЗрдЯрд╣рд╛рдЙрд╕ рдЪрд╢реНрдорд╛ 95 рд╕реЗ рдмрдврд╝рдХрд░ 100 рд╣реЛ рдЧрдпрд╛

Source: https://habr.com/ru/post/hi446682/


All Articles