snd.React로 dev를 사용해 봤어요.

(추기: 마지막에 썼다SE에 관한 시.
전통의 토옥 씨와 StaryWorks 씨가 UI를 위한 사운드 라이브러리snd.dev를 내놓았다고 해서 바로 만든 앱을 시도했습니다.
npm과 CDN이 모두 있기 때문에 HTML/VanillaJS로 간단하게 사용하고 React 등 제품을 가져오기 쉽습니다.
여기는 React/Next입니다.js에 삽입된 내용을 총괄해 보세요.
프로젝트 구성
  • TypeScript 4.5.5
  • React 17.0.2
  • Next 12.0.8
  • Chakra 1.8.1
  • ※ UI는 Chakra 적용됐지만, 다른 제품에도 적용할 수 있다고 적혀 있습니다.
    설치 방법
    콘솔 등으로 package.json에 추가.
    npm i snd-lib
    
    기본용법
  • Snd 인스턴스 생성
  • 사운드 자산 탑재
  • Snd 인스턴스를 호출하는 방법
  • const snd = new Snd(/* options */)
    
    snd.load(Snd.KITS.SND01)
    
    document.getElementById("button").addEventListener("click", () => {
      snd.playButton()
    })
    
    도 초기화할 때 자동으로 불러오는 옵션이 있습니다.
    const snd = new Snd({
      preloadSoundKit: Snd.KITS.SND01 // or Snd.KITS.SND02
    })
    
    또한 iOS 등 모바일 단말기는 소리를 재생할 때 제약이 존재하기 때문에 사용자가 동작을 촉발점에 재생하지 않으면 함부로 소리를 낼 수 없기 때문에 일부 사용자의 조작을 통해 소리 없는 방식으로 첫 번째 해커를 미리 울려야 한다.그건 Snd 구조기 안에서 이동도 잘 되고 문제없이 사용할 수 있기 때문이다.
    대박이다.
    리액트로 사용하기 편해요.
    Context/Provider를 통해 Snd 인스턴스 재생
    마찬가지로 Snd 실례를 사용하여 자산을 한 번만 탑재하고 싶기 때문에 초기화 처리를 Context.Provider에 수집하고 이용자는 Context를 통해만 실례를 접수하여 사용한다.
    우선 제작치의 유형SndContext.
    초기 값의 유형을 대략적으로 분배할 테니 프로젝트 제작에 따라 적절하게 변경하세요.
    export const SoundContext = createContext<Snd>({} as Snd)
    
    Snd의 지식을 숨기려면 필요한 방법과 조작만 제공하는 것도 좋다.
    type ISoundContext = {
      play: (key:string) => void 
      stop: (key:string) => void 
      mute: () => void 
      unmute: () => void 
    }
    
    export const SoundContext = createContext<ISoundContext>({} as ISoundContext)
    
    Provider는 실례 생성 시 제출한 옵션을 직접 받아들일 수 있음SndOptions.
    type IProps = {
      options?: SndOptions 
    }
    
    export const SoundContextProvider: VFC<PropsWithChildren<IProps>> = ({
      options,
      children,
    }) => {
      const [snd, setSnd] = useState<Snd>()
    
      const load = useCallback(async () => {
        await snd?.load(Snd.KITS.SND01)
      }, [snd])
    
      useEffect(() => {
        setSnd(new Snd(options))
      }, [options])
    
      useEffect(() => {
        // preloadSoundKitがある場合はコンストラクタで自動的にロードされるのでloadメソッドを呼ばない
        if (options?.preloadSoundKit) return
        void load()
      }, [options?.preloadSoundKit, load])
     
      if (!snd) return <>{children}</>
    
      return <SoundContext.Provider value={snd}>{children}</SoundContext.Provider>
    }
    
    참고로 Snd류 주체 이외의 유형은 포장 내의 정의 파일에서 읽어내면 사용할 수 있다.
    import { SndOptions, PlayOptions } from 'snd-lib/dist/snd'
    
    Next.jspages/_app.tsx이기 때문에 방금 초기화된 SoundContextProvider를 가져와서 페이지 구성 요소를 포위합니다.
    ※ 실제 항목 중에는 여러 개なんとかProvider가 있지만, 생략합니다.
    const App: VFC<AppProps> = ({ Component, pageProps }) => (
      <SoundContextProvider options={{ preloadSoundKit: Snd.KITS.SND02 }}>
        <ChakraProvider>
          <Component {...pageProps} />
        </ChakraProvider>
      </SoundContextProvider>
    )
    
    export default App
    
    React 어셈블리에서 사용
    이렇게 하면 하층의 구성 요소Context는 수신 실례Snd를 통해 사용할 수 있다.
    const snd = useContext(SoundContext)
    
    그러나 매번 입력과useContext()는 버튼 등 많은 요소이기 때문에 UI 프로그램 라이브러리에 의존하지 않는 Hooks를 제작하고 UI 프로그램 라이브러리와 관련된 일반적인 UI 구성 요소를 제작한다.
    설치useClickSound().
    Hooks로서 마우스 이벤트 처리 프로그램onClick()을 포함하는 프로포즈를 수신하고 onClick()에 소리 처리를 삽입하고 다른 프로포즈는 그대로 느낌의 I/F를 넣는다.
    import { useContext, useCallback, MouseEventHandler } from 'react'
    import { SoundContext } from 'views/features/sounds/Context'
    
    export const useClickSound = <T extends { onClick?: MouseEventHandler }>({
      onClick,
      ...props
    }: T) => {
      const snd = useContext(SoundContext)
    
      const onClickHandler: MouseEventHandler = useCallback(
        (e) => {
          snd.playButton()
    
          onClick?.(e)
        },
        [onClick, snd],
      )
    
      return {
        ...props,
        onClick: onClickHandler,
      }
    }
    
    이 UI 라이브러리의 일반 부품으로 조립하여 사용합니다.
    Chakra시 설치는 다음과 같습니다.
    버튼을 받는propsuseClickSound(), 통과한 값Button을 건네줍니다. 
    이때ref를 전송할 수 있습니다.(차크라의 경우 리액트가 아닌 차크라forwardRef()를 사용했다.)
    import {
      Button,
      ButtonProps,
      forwardRef,
      IconButtonProps,
    } from '@chakra-ui/react'
    
    import useClickSound from 'views/features/sounds/useClickSound'
    
    export const SoundButton = forwardRef((props: ButtonProps | IconButtonProps, ref) => (
      <Button {...useClickSound(props)} ref={ref} />
    ))
    
    이렇게 하면 onClick()를 포함하여 원래의 버튼props만 투명하게 전달되기 때문에 원래Button 구성 요소의 사용감과 완전히 같다.
    const SomeComponent = () => {
      const clickHandler = useCallback(() => {
        // Do something.
      }, []) 
      
      return (
        <SoundButton size="lg" onClick={clickHandler}>ボタン</SoundButton>
      ) 
    }
    
    as 속성 중에서도 IconButton 등으로 변경할 수 있다.
    좀 더 통용될 수 있을 것 같았지만 상관없는 데에 시간이 많이 걸려 타협했다.
    <SoundButton as={IconButton} aria-label="ボタン" icon={<SomeIcon />} />
    
    추기as 속성이 구성 요소를 변경했을 때 다른 속성을 잘 반영하지 못하는 경우가 있으므로 ButtonIconButton의 전환 정도라면 각각 랩으로 솔직하게 싸는 것이 좋다.
    잘 통용될 수 있는 사람은 상술한 형식으로 디자인하면 좋겠다.
    export const SoundButton = forwardRef((props: ButtonProps, ref) => (
      <Button {...useClickSound(props)} ref={ref} />
    ))
    
    export const SoundIconButton = forwardRef((props: IconButtonProps, ref) => (
      <IconButton {...useClickSound(props)} ref={ref} />
    ))
    
    이렇게 되면 기존 프로젝트에 버튼이 설치되어 있어도 구성 요소를 교체하면 위화감 없이 조립할 수 있다.
    즐거운 생활 되세요.
    잡담
    짧은 시간 안에 시원한 SE를 넣는 것 자체가 UX를 가져올 수 있다는 오해는 없었으면 좋겠다.
    '인터랙티브 디자인'으로서 터치의 일부분을 담당하는 촉각은 SE의 역할이다
    UI의 피드백이 정확하지 않으면 직원이 스스로 만족합니다.
    인터넷에는 애플리케이션, 광고, 잡지 같은 글이 많다.
    UI에서의 SE는 OS와 로컬 애플리케이션의 UI와의 연속성에 적정한 일치성을 유지하는 것이 유용하지만, 잡지나 병원 웹사이트 등이 트위스트 SE로 변할 필요성에도 의문이 있다.
    이런 UI성의 상하문과 문법을 이해하는 것이 비교적 좋다
    SE에 효과적으로 가입하기 위해 인터페이스와의 대화에서 시각 이외의 피드백으로서 필연성과 의도를 가지고 적당한 음질 음질로 시각적 토마나와 일치성을 확보하는 것이 중요하다.
    (사용자를 방해하지 않는다면 시각적인 공연을 포함한 전제조건이다.)
    비즈니스나 공공성이 높은 웹사이트에서는 소리를 낼 수 없는 환경에서 구상되는 상황(원래 울리지 않고 사전에 주의해 소리를 선택할 수 있는 ON/OFF 등)을 고려해 SE 가입을 통해 경험을 높인다는 점에서 UX(UI의 입장)라고 본다.
    소리를 듣지 못하면 이해할 수 없는 용도도 피해야 한다.
    비록 없어도 성립할 수 있지만, 나는 이 라이브러리의 분배에는 이런 생각이 포함되어 있다고 생각한다. 그것이 있으면 더욱 좋을 것이다.
    snd.나는 dev를 세운 사람의 그런 철학적인 곳도 함께 확장할 수 있었으면 좋겠다고 생각한다.

    좋은 웹페이지 즐겨찾기