Skip to content

N-JELLY/XRift_ContextMenu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 

Repository files navigation

XRift ContextMenu

XRift ワールド向けのラジアルメニューコンポーネントです。
キーを押している間、カメラ正面に円形のボタンメニューを表示します。

導入方法

A. フォルダをコピーする

ContextMenu/ フォルダをあなたのワールドプロジェクトの src/components/ にコピーしてください。

git clone https://github.com/N-JELLY/XRift_ContextMenu.git
cp -r XRift_ContextMenu/ContextMenu your-world/src/components/
import { ContextMenu, MenuButtonConfig } from './components/ContextMenu'

B. git clone したままインポートする

プロジェクトの隣にクローンして、パスで直接 import する方法もあります。

# your-world/ の隣にクローン
git clone https://github.com/N-JELLY/XRift_ContextMenu.git
// src/World.tsx から参照する例(相対パスはプロジェクト構成に合わせて調整)
import { ContextMenu, MenuButtonConfig } from '../../XRift_ContextMenu/ContextMenu'

TypeScript の paths エイリアスを使うとすっきり書けます(tsconfig.json):

{
  "compilerOptions": {
    "paths": {
      "@context-menu": ["../XRift_ContextMenu/ContextMenu/index.tsx"]
    }
  }
}
import { ContextMenu, MenuButtonConfig } from '@context-menu'

使い方

基本

ContextMenu コンポーネントに buttons 配列を渡します。デフォルトで R キー を押している間メニューが表示されます。

import { ContextMenu, MenuButtonConfig } from './components/ContextMenu'

const buttons: MenuButtonConfig[] = [
  { icon: '●', label: 'Sphere',  onSelect: () => console.log('sphere') },
  { icon: '■', label: 'Box',     onSelect: () => console.log('box') },
  { icon: '⚙', label: 'Setting', onSelect: () => console.log('setting') },
]

export const World = () => (
  <>
    <ContextMenu buttons={buttons} />
  </>
)

スポーン+Delete の例

ref を渡すとメニューの表示位置(Group)を取得でき、スポーン位置をメニューに合わせられます。

import { useRef, useState } from 'react'
import { Group } from 'three'
import { ContextMenu, MenuButtonConfig } from './components/ContextMenu'

interface SpawnedObject {
  id: number
  type: 'sphere' | 'box'
  position: [number, number, number]
}

let spawnIdCounter = 0

export const World = () => {
  const menuRef = useRef<Group>(null)
  const [spawnedObjects, setSpawnedObjects] = useState<SpawnedObject[]>([])

  const spawnAt = (type: SpawnedObject['type']) => {
    const pos = menuRef.current?.position
    if (!pos) return
    setSpawnedObjects(prev => [...prev, { id: spawnIdCounter++, type, position: [pos.x, pos.y, pos.z] }])
  }

  const buttons: MenuButtonConfig[] = [
    { icon: '●', label: 'Sphere',  onSelect: () => spawnAt('sphere') },
    { icon: '■', label: 'Box',     onSelect: () => spawnAt('box') },
    { icon: '🗑️', label: 'Delete', onSelect: () => setSpawnedObjects([]) },
  ]

  return (
    <>
      <ContextMenu ref={menuRef} buttons={buttons} />
      {spawnedObjects.map(obj => (
        <mesh key={obj.id} position={obj.position}>
          {obj.type === 'sphere' ? <sphereGeometry args={[0.3, 32, 32]} /> : <boxGeometry args={[0.5, 0.5, 0.5]} />}
          <meshStandardMaterial color={obj.type === 'sphere' ? '#6688ff' : '#ff8844'} />
        </mesh>
      ))}
    </>
  )
}

Props

ContextMenu

Prop デフォルト 説明
buttons MenuButtonConfig[] 必須 表示するボタンの配列
triggerKey string 'r' メニューを開くキー
distance number 1.4 カメラからメニューまでの距離(m)
ref React.Ref<Group> メニューの Group への ref(スポーン位置の取得などに使用)

MenuButtonConfig

フィールド デフォルト 説明
icon string ボタン中央に表示するアイコン(絵文字可)
label string ボタン下のラベル
color string '#646464' 通常時の色
colorHover string '#a0a0ff' ホバー時の色
colorClick string '#ffffff' クリック時の色
onSelect () => void 必須 選択時のコールバック

操作

操作 動作
R キーを押す メニューを表示(カメラ正面に固定)
R キーを離す メニューを非表示
ボタンをクリック onSelect を実行

ライセンス

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors