рд╕реНрд╡реЗрд▓реНрдЯреЗ рдкрд░ рдкреВрд░рд╛ рдЬреАрд╡рди

рд░рд╛рджрд┐рд╕реНрд▓рд╛рд╡ рдЧрдВрдбрд╛рдкрд╕ рдХреА рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдкреБрд╕реНрддрдХ рд╣реИ рдХрдореНрдкреНрд▓реАрдЯ рдЬреЗред рдпрд╣ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЕрдкрдиреЗ рдЬреАрд╡рди рдХреА рджрд┐рд╢рд╛ рдХрд╛ рдЖрдХрд▓рди рдХреИрд╕реЗ рдХрд░реЗрдВ, рдФрд░ рд╡рд┐рдХрд╛рд╕ рдпреЛрдЬрдирд╛ рдХреИрд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдХрд░реЗрдВред


рдореИрдВ рдПрдХ рдЙрдкрдХрд░рдг рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЬреЛ рдореЗрд░реЗ рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдореЗрдВ рд╣реЛрдЧрд╛ рдФрд░ рдореЗрд░реЗ рд░рдбрд╛рд░ рдХреЛ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред


рдЫрд╡рд┐


1. рддреИрдпрд╛рд░реА


рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдФрд░ рдбреЗрдореЛ рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╣рд╛рдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рдпрд╣ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЫреЛрдЯрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдСрдирд▓рд╛рдЗрди svelte рд╕рдВрдкрд╛рджрдХ REPL рдореЗрдВ рддреБрд░рдВрдд рд▓рд┐рдЦреЗрдВрдЧреЗред рдпрджрд┐ рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдп рд╡рд┐рдХрд╛рд╕ рдкрд╕рдВрдж рд╣реИ, рддреЛ рдЖрдк рд╡реЗрдмрдкреИрдХ рдпрд╛ рд░реЛрд▓рдЕрдк svelte рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдореИрдВ рд╕реНрдерд╛рдиреАрдп рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдбреИрдВрдбрдмреЙрдХреНрд╕ рдЯреВрд▓ рдХреЛ рдСрдирд▓рд╛рдЗрди рд╕реБрдЭрд╛ рд╕рдХрддрд╛ рд╣реВрдВред


рдпрджрд┐ рдЖрдк VScode рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ svelte-vscode plugin рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ


рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЖрд░рдИрдкреАрдПрд▓ рдЦреЛрд▓рддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ


2. рдлреНрд░реЗрдо


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ App.svelte рдлрд╝рд╛рдЗрд▓ рд╣реИ, рдпрд╣ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИред рд╕реНрдЯрд╛рдЗрд▓ рдЯреИрдЧ рдХреЛ рд╕реНрдЯрд╛рдЗрд▓ рдЯреИрдЧ рдореЗрдВ рд╕реНрдЯрд╛рдЗрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬреИрд╕рд╛ рдХрд┐ рдирд┐рдпрдорд┐рдд HTML рдореЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдкрд░, рдЖрдкрдХреЛ рдШрдЯрдХ рд╕реНрддрд░ рдкрд░ рд╢реИрд▓реА рдЕрд▓рдЧрд╛рд╡ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рд╡реИрд╢реНрд╡рд┐рдХ рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╡рд╕реНрддреБ рдХреЗ рдмрд╛рд╣рд░ "рд╕реБрд▓рдн" рд╣реЛрдЧреА, рддреЛ рдЖрдкрдХреЛ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ : рд╡реИрд╢реНрд╡рд┐рдХ () ред рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдЯреЗрдирд░ рдмрдирд╛рдПрдВред


App.svelte
<style> :global(body) { height: 100%; overscroll-behavior: none; /*  pull to refresh*/ user-select: none; /*      */ margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; background: rgb(35, 41, 37); } :global(html) { height: 100%; } .container { flex-grow: 1; display: flex; flex-direction: column; justify-content: center; height: 100%; } </style> <div class="container"> </div> 

Radar.svelte рдШрдЯрдХ рдмрдирд╛рдПрдБред рдпрд╣ рдПрд╕рд╡реАрдЬреА рддрддреНрд╡ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЕрдкрдирд╛ рдкрд╣рд┐рдпрд╛ рдЦреАрдВрдЪреЗрдВрдЧреЗред


Radar.svelte
 <svg viewBox="-115 -110 230 220"> </svg> 

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдШрдЯрдХ рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб Svelte рдШрдЯрдХ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдЕрдкрдиреЗ Radar.svelte рдХреЛ App.svelte рдореЗрдВ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред


App.svelte
 <script> import Radar from './Radar.svelte' /*    */ </script> <style> :global(body) { height: 100%; overscroll-behavior: none; user-select: none; margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; background: rgb(35, 41, 37); } :global(html) { height: 100%; } .container { flex-grow: 1; display: flex; flex-direction: column; justify-content: center; height: 100%; } </style> <div class="container"> <Radar/> <!--   Radar --> </div> 

рд░рдбрд╛рд░ рдореЗрдВ рд╕реНрд╡рдпрдВ рдЬреАрд╡рди рдкрд╣рд▓реБрдУрдВ рдХреЗ рдЕрдиреБрд░реВрдк рдХреНрд╖реЗрддреНрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗред рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЕрдкрдирд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реЛрддрд╛ рд╣реИред


рдЫрд╡рд┐


рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдЧреНрд░рд┐рдб рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдПрдХ рдЫреЛрдЯреЗ рдЖрдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд╖реЗрддреНрд░ рд╣реЛрддрд╛ рд╣реИред


рдЫрд╡рд┐


рдПрдХ рд╕реЗрдХреНрдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рддреАрди рдХреЛрдиреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ред


рдЫрд╡рд┐


рд╡рд░реНрдЯреЗрдХреНрд╕ рдП рд╣рдореЗрд╢рд╛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ [0, 0] рдХреЗ рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореВрд▓ рд╣рдорд╛рд░реЗ рд░рдбрд╛рд░ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рд╣реЛрдЧрд╛ред рдмреА рдФрд░ рд╕реА рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╣реЗрдХреНрд╕рд╛рдЧреЛрдирд▓ рдЧреНрд░рд┐рдб рдкрд░ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрдирдкреБрдЯ рдкрд░, рдлрд╝рдВрдХреНрд╢рди рд╕реЗрдХреНрдЯрд░ рдЖрдХрд╛рд░ рдФрд░ рджрд┐рд╢рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ 'x, y' рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рджреЗрддрд╛ рд╣реИред
рдПрдХ рдлрд╝рд╛рдЗрд▓ getHexCorner.js рдмрдирд╛рдПрдВ, рдЬрд╣рд╛рдВ рд╣рдо рдЕрдкрдирд╛ рдлрд╝рдВрдХреНрд╢рди getHexCorner (рдЖрдХрд╛рд░, рджрд┐рд╢рд╛) рдбрд╛рд▓рддреЗ рд╣реИрдВ


getHexCorner.js
 export default function getHexCorner(size, direction) { const angleDeg = 60 * direction - 30; const angleRad = (Math.PI / 180) * angleDeg; return `${size * Math.cos(angleRad)},${size * Math.sin(angleRad)}`; } 

рдЕрдм рд╕реЗрдХреНрдЯрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдмрдирд╛рдЗрдПред рд╕реЗрдХреНрдЯрд░рд╡реЗрд▓ , рдЬреЛ рдЧреНрд░рд┐рдб рдХреЛ рдбреНрд░реЙ рдХрд░рддрд╛ рд╣реИред рд╣рдореЗрдВ 10-рдЪрд░рдг рдЪрдХреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдШрдЯрдХ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ, рд▓реВрдк рдХреЗ рд▓рд┐рдП svelte рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд╕рд┐рд░реНрдл рдПрдХ рдЧреНрд░рд┐рдб рд╕рд░рдгреА рдмрдирд╛рдИ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ #each рдирд┐рд░реНрджреЗрд╢ рдореЗрдВ рдУрд╡рд░рд░реЗрдЯ рдХрд░реВрдВрдЧрд╛ ред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП, рддреЛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреЗрдВред


Sector.svelte
 <script> import getHexCorner from "./getHexCorner.js"; export let direction = 0; const grid = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; </script> <style> polygon { fill: #293038; stroke: #424a54; } </style> {#each grid as gridValue, i} <polygon points={`${getHexCorner(gridValue * 10, direction)}, ${getHexCorner(gridValue * 10, direction + 1)}, 0, 0`} strokeLinejoin="miter-clip" stroke-dasharray="4" stroke-width="0.5" /> {/each} 

Radar.svelte рдШрдЯрдХ рдореЗрдВ рдПрдХ рд╕реЗрдХреНрдЯрд░ рдХреЛ рдЖрдпрд╛рдд рдФрд░ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реЗрдВред


Radar.svelte
 <script> import Sector from './Sector.svelte'; </script> <svg viewBox="-115 -110 230 220"> <Sector/> </svg> 

рдЕрдм рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди 1 рдХреНрд╖реЗрддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред


рдЫрд╡рд┐


3. рдбрд╛рдЯрд╛ рд╕реНрдЯреЛрд░реЗрдЬ


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


рдПрдХ store.js рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ


рд╣рдореЗрдВ рджреЛ рдЪрд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:


  • рдореМрдЬреВрджрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рдбрд╛рд░
  • рдЕрдЧрд░ рдЯрдЪрдореЙрд╡ рдФрд░ рдореВрд╕рдорд╡ рдЗрд╡реЗрдВрдЯ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╕рдХреНрд░рд┐рдп рд╕реЗрдХреНрдЯрд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреНрдЯрд┐рд╡рд╕реЗрдХреНрдЯрд░ ред

store.js
 import { writable } from "svelte/store"; const defaultStore = ["hobby", "friendship", "health", "job", "love", "rich"]; function Radar() { /*      */ const { subscribe, update } = writable(defaultStore.map(item=>({name:item, value:0}))); /*         */ return { subscribe, set: (id, value) => update(store => store.map(item => (item.name === id ? { ...item, value } : item)) ) }; } export const radar = Radar(); export const activeSector = writable(null); 

рдЕрдм рд╣рдо Radar.svelte рдШрдЯрдХ рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рд╕реНрдЯреЙрд░ рдХреЛ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреВрд░реНрдг рд░рд╛рдбрд╛рд░ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред


Radar.svelte
 <script> import { radar } from "./store.js"; import Sector from "./Sector.svelte"; </script> <svg viewBox="-115 -110 230 220"> {#each $radar as sector, direction (sector.name)} <Sector {...sector} {direction} /> {/each} </svg> 

# рдиреАрдЪ рдирд┐рд░реНрджреЗрд╢ рдХреА рдХреБрдЫ рд╕реВрдХреНрд╖реНрдорддрд╛рдПрдБред рд╣рдо рдЪрд░ рдирд╛рдо $ рд░рдбрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред $ рдирд┐рд░реНрджреЗрд╢ Svelte рд╕рдВрдХрд▓рдХ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдПрдХ рднрдВрдбрд╛рд░ рд╣реИ, рдФрд░ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рджрд╕реНрдпрддрд╛ рдмрдирд╛рддрд╛ рд╣реИред рджрд┐рд╢рд╛ рдЪрд░ рд╡рд░реНрддрдорд╛рди рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣рдо рдЕрдкрдиреЗ рдХреНрд╖реЗрддреНрд░ рдХреА рджрд┐рд╢рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ (рд╕реЗрдХреНрдЯрд░.рдПрдирдЖрдИ) , рд╡рд╕реНрддреБ рдореЗрдВ рдЖрдИрдбреА рдХреЗ рдЖрдЗрдбрд▓ рдкрд░ рд╕реЗрд╡рд▓ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ ред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдПрдирд╛рд▓реЙрдЧ рдХреБрдВрдЬреАред


рдЕрдм рд╣рдорд╛рд░рд╛ рдЧреНрд░рд┐рдб рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ


рдЫрд╡рд┐


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

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ Svelte {varName} рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рдХреЛ varName = {varName} рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдкреНрд░реЛрдХреЗрдбреНрдпрд╡рд╛рди рдЧреБрдгреЛрдВ рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред


Sector.svelte
 <script> import getHexCorner from "./getHexCorner.js"; export let direction = 0; export let name; export let value; const grid = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; </script> <style> polygon { fill: #293038; stroke: #424a54; } .rich { fill: #469573; } .hobby { fill: #7c3f7a; } .friendship { fill: #5c6bc0; } .health { fill: #e5b744; } .job { fill: #e16838; } .love { fill: #e23f45; } </style> {#each grid as gridValue, i} <polygon points={`${getHexCorner(gridValue * 10, direction)}, ${getHexCorner(gridValue * 10, direction + 1)}, 0, 0`} strokeLinejoin="miter-clip" stroke-dasharray="4" stroke-width="0.5" class={value >= gridValue ? name : ''} {name} value={gridValue} /> /> {/each} 

рдпрджрд┐ рд╣рдо рдЕрдкрдиреЗ рд╕реНрдЯреЛрд░ (store.js) рдореЗрдВ рд╢реВрдиреНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреЛрдИ рдореВрд▓реНрдп рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдпрд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:


4. рдШрдЯрдирд╛рдПрдБ


рд╣рдорд╛рд░реЗ рд░рдбрд╛рд░ рдореЗрдВ рдЬреАрд╡рди рдХреЛ рд╕рд╛рдВрд╕ рд▓реЗрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ, рдПрдХ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдПрдВ рдЬреЛ рдЗрдирдкреБрдЯ рдкрд░ рдПрдХ рдиреЛрдб рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рд╕реНрдкрд░реНрд╢ рдФрд░ рдорд╛рдЙрд╕ рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред


handleRadar.js
 import { radar, activeSector } from "./store.js"; /*  get            */ import { get } from "svelte/store"; export default function handleRadar(node) { const getRadarElementAtPoint = e => { /*   :    */ const event = e.touches ? e.touches[0] : e; const element = document.elementFromPoint(event.pageX, event.pageY); /*       html  */ const score = element.getAttribute("value"); const id = element.getAttribute("name"); return { id, score, type: event.type }; }; const start = e => { /*       */ const { id } = getRadarElementAtPoint(e); /*     */ activeSector.set(id); }; const end = () => { /*    */ activeSector.set(null); }; const move = e => { /*   requestAnimationFrame       */ window.requestAnimationFrame(() => { const { id, score, type } = getRadarElementAtPoint(e); /* ,      , ..    ,     */ if (!id || (id !== get(activeSector) && type !== "click") || !score) return; /*    */ radar.set(id, score); }); }; /*   */ node.addEventListener("mousedown", start); node.addEventListener("touchstart", start); node.addEventListener("mouseup", end); node.addEventListener("touchend", end); node.addEventListener("mousemove", move); node.addEventListener("touchmove", move); node.addEventListener("touch", move); node.addEventListener("click", move); /*     destroy,          DOM */ return { destroy() { node.removeEventListener("mousedown", start); node.removeEventListener("touchstart", start); node.removeEventListener("mouseup", end); node.removeEventListener("touchend", end); node.removeEventListener("mousemove", move); node.removeEventListener("touchmove", move); node.removeEventListener("touch", move); node.removeEventListener("click", move); } }; } 

рдЕрдм рдЙрдкрдпреЛрдЧ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ svg рд░рдбрд╛рд░ рддрддреНрд╡ рдореЗрдВ рд╣рдорд╛рд░реЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЬреЛрдбрд╝реЗрдВ :


Radar.svelte
 <script> import { radar } from "./store.js"; import Sector from "./Sector.svelte"; import handleRadar from "./handleRadar.js"; </script> <svg viewBox="-115 -110 230 220" use:handleRadar> {#each $radar as sector, direction (sector.name)} <Sector {...sector} {direction} /> {/each} </svg> 

рд░рдбрд╛рд░ рдЕрдм рдХреНрд▓рд┐рдХ рдФрд░ рдбреНрд░реИрдЧ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИред


6. рдлрд╛рдЗрдирд▓ рдЯрдЪ


рд╕реЗрдХреНрдЯрд░ рдФрд░ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдХреИрдкреНрд╢рди рдЬреЛрдбрд╝реЗрдВ


Sector.svelte
 <script> import getHexCorner from "./getHexCorner.js"; export let name; export let value; export let direction; const grid = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; const flip = direction === 2 || direction === 1; const radarTranslation = { hobby: "", friendship: "", health: "", job: "", love: "", rich: "" }; </script> <style> polygon { fill: #293038; stroke: #424a54; } text { font-size: 8px; fill: white; } .value { font-weight: bold; font-size: 12px; } .rich { fill: #469573; } .hobby { fill: #7c3f7a; } .friendship { fill: #5c6bc0; } .health { fill: #e5b744; } .job { fill: #e16838; } .love { fill: #e23f45; } </style> {#each grid as gridValue, i} <polygon points={`${getHexCorner(gridValue * 10, direction)}, ${getHexCorner(gridValue * 10, direction + 1)}, 0, 0`} strokeLinejoin="miter-clip" stroke-dasharray="4" stroke-width="0.5" class={value >= gridValue ? name : ''} {name} value={gridValue} /> {/each} <g transform={`translate(${getHexCorner(105, flip ? direction + 1 : direction)}) rotate(${direction * 60 + (flip ? -90 : 90)})`}> <text x="50" y={flip ? 5 : 0} text-anchor="middle"> {radarTranslation[name]} </text> <text x="50" y={flip ? 18 : -10} text-anchor="middle" class="value"> {value} </text> </g> 

рд░рдбрд╛рд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдЫрд╡рд┐


5. рдмреЛрдирд╕


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


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


All Articles