您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

control.tsx 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import state, { useSelector } from 'state'
  2. import styled from 'styles'
  3. import { ControlType, NumberCodeControl, VectorCodeControl } from 'types'
  4. export default function Control({ id }: { id: string }): JSX.Element {
  5. const control = useSelector((s) => s.data.codeControls[id])
  6. if (!control) return null
  7. return (
  8. <>
  9. <label>{control.label}</label>
  10. {control.type === ControlType.Number ? (
  11. <NumberControl {...control} />
  12. ) : control.type === ControlType.Vector ? (
  13. <VectorControl {...control} />
  14. ) : null}
  15. </>
  16. )
  17. }
  18. function NumberControl({ id, min, max, step, value }: NumberCodeControl) {
  19. return (
  20. <Inputs>
  21. <input
  22. type="range"
  23. min={min}
  24. max={max}
  25. step={step}
  26. value={value}
  27. onChange={(e) =>
  28. state.send('CHANGED_CODE_CONTROL', {
  29. [id]: Number(e.currentTarget.value),
  30. })
  31. }
  32. />
  33. <input
  34. type="number"
  35. min={min}
  36. max={max}
  37. step={step}
  38. value={value}
  39. onChange={(e) =>
  40. state.send('CHANGED_CODE_CONTROL', {
  41. [id]: Number(e.currentTarget.value),
  42. })
  43. }
  44. />
  45. </Inputs>
  46. )
  47. }
  48. function VectorControl({ id, value, isNormalized }: VectorCodeControl) {
  49. return (
  50. <Inputs>
  51. <input
  52. type="range"
  53. min={isNormalized ? -1 : -Infinity}
  54. max={isNormalized ? 1 : Infinity}
  55. step={0.01}
  56. value={value[0]}
  57. onChange={(e) =>
  58. state.send('CHANGED_CODE_CONTROL', {
  59. [id]: [Number(e.currentTarget.value), value[1]],
  60. })
  61. }
  62. />
  63. <input
  64. type="number"
  65. min={isNormalized ? -1 : -Infinity}
  66. max={isNormalized ? 1 : Infinity}
  67. step={0.01}
  68. value={value[0]}
  69. onChange={(e) =>
  70. state.send('CHANGED_CODE_CONTROL', {
  71. [id]: [Number(e.currentTarget.value), value[1]],
  72. })
  73. }
  74. />
  75. <input
  76. type="range"
  77. min={isNormalized ? -1 : -Infinity}
  78. max={isNormalized ? 1 : Infinity}
  79. step={0.01}
  80. value={value[1]}
  81. onChange={(e) =>
  82. state.send('CHANGED_CODE_CONTROL', {
  83. [id]: [value[0], Number(e.currentTarget.value)],
  84. })
  85. }
  86. />
  87. <input
  88. type="number"
  89. min={isNormalized ? -1 : -Infinity}
  90. max={isNormalized ? 1 : Infinity}
  91. step={0.01}
  92. value={value[1]}
  93. onChange={(e) =>
  94. state.send('CHANGED_CODE_CONTROL', {
  95. [id]: [value[0], Number(e.currentTarget.value)],
  96. })
  97. }
  98. />
  99. </Inputs>
  100. )
  101. }
  102. const Inputs = styled('div', {
  103. display: 'flex',
  104. gap: '8px',
  105. height: '100%',
  106. '& input': {
  107. font: '$ui',
  108. width: '64px',
  109. fontSize: '$1',
  110. border: '1px solid $inputBorder',
  111. backgroundColor: '$input',
  112. color: '$text',
  113. height: '100%',
  114. padding: '0px 6px',
  115. },
  116. "& input[type='range']": {
  117. padding: 0,
  118. flexGrow: 2,
  119. },
  120. })