You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

control.tsx 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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({
  49. id,
  50. value,
  51. min = -Infinity,
  52. max = Infinity,
  53. step = 0.01,
  54. isNormalized = false,
  55. }: VectorCodeControl) {
  56. return (
  57. <Inputs>
  58. <input
  59. type="range"
  60. min={isNormalized ? -1 : min}
  61. max={isNormalized ? 1 : max}
  62. step={step}
  63. value={value[0]}
  64. onChange={(e) =>
  65. state.send('CHANGED_CODE_CONTROL', {
  66. [id]: [Number(e.currentTarget.value), value[1]],
  67. })
  68. }
  69. />
  70. <input
  71. type="number"
  72. min={isNormalized ? -1 : min}
  73. max={isNormalized ? 1 : max}
  74. step={step}
  75. value={value[0]}
  76. onChange={(e) =>
  77. state.send('CHANGED_CODE_CONTROL', {
  78. [id]: [Number(e.currentTarget.value), value[1]],
  79. })
  80. }
  81. />
  82. <input
  83. type="range"
  84. min={isNormalized ? -1 : min}
  85. max={isNormalized ? 1 : max}
  86. step={step}
  87. value={value[1]}
  88. onChange={(e) =>
  89. state.send('CHANGED_CODE_CONTROL', {
  90. [id]: [value[0], Number(e.currentTarget.value)],
  91. })
  92. }
  93. />
  94. <input
  95. type="number"
  96. min={isNormalized ? -1 : min}
  97. max={isNormalized ? 1 : max}
  98. step={step}
  99. value={value[1]}
  100. onChange={(e) =>
  101. state.send('CHANGED_CODE_CONTROL', {
  102. [id]: [value[0], Number(e.currentTarget.value)],
  103. })
  104. }
  105. />
  106. </Inputs>
  107. )
  108. }
  109. const Inputs = styled('div', {
  110. display: 'flex',
  111. gap: '8px',
  112. height: '100%',
  113. '& input': {
  114. font: '$ui',
  115. width: '64px',
  116. fontSize: '$1',
  117. border: '1px solid $inputBorder',
  118. backgroundColor: '$input',
  119. color: '$text',
  120. height: '100%',
  121. padding: '0px 6px',
  122. },
  123. "& input[type='range']": {
  124. padding: 0,
  125. flexGrow: 2,
  126. },
  127. })