Skip to content

Commit

Permalink
Add rest of inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
baku89 committed Sep 30, 2023
1 parent 66b7854 commit 0fed88a
Show file tree
Hide file tree
Showing 35 changed files with 2,235 additions and 7 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"devDependencies": {
"@material/material-color-utilities": "^0.2.7",
"@traptitech/markdown-it-katex": "^3.6.0",
"@types/chroma-js": "^2.4.1",
"@types/lodash": "^4.14.199",
"@types/wicg-file-system-access": "^2020.9.6",
"@typescript-eslint/eslint-plugin": "^6.7.0",
Expand All @@ -23,6 +24,7 @@
"@vueuse/core": "^10.4.1",
"@vueuse/gesture": "^2.0.0-beta.1",
"case": "^1.6.3",
"chroma-js": "^2.4.2",
"eslint": "^8.49.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest": "^27.2.3",
Expand All @@ -32,6 +34,7 @@
"eslint-plugin-vue": "^9.17.0",
"fast-fuzzy": "^1.12.0",
"fp-ts": "^2.16.1",
"fuzzy": "^0.1.3",
"line-intersect": "^3.0.0",
"lodash": "^4.17.21",
"markdown-it": "^13.0.2",
Expand All @@ -43,10 +46,12 @@
"monaco-themes": "^0.4.4",
"paper": "^0.12.17",
"paperjs-offset": "^1.0.8",
"regl": "^2.1.0",
"reset-css": "^5.0.2",
"stylus": "^0.60.0",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"vite-plugin-glsl": "^1.1.2",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-pwa": "^0.16.5",
"vue": "^3.3.4",
Expand Down
18 changes: 18 additions & 0 deletions src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const {appStorage, registerActions, performAction} = useTweeq(
const testString = ref('Hello World')
const testNumber = ref(Math.PI)
const testBoolean = ref(false)
const testAlign = ref<'left' | 'center' | 'right'>('left')
const colorSpace = ref<'r|g|b' | 'svh' | 'hsv' | 'hvs' | 'hsvr'>('hsv')
// interface PaperDesc {
// id?: string
Expand Down Expand Up @@ -420,6 +422,22 @@ window.addEventListener('drop', async e => {
<Tq.Parameter label="Seed">
<Tq.InputSeed v-model="testNumber" />
</Tq.Parameter>
<Tq.Parameter label="Radio">
<Tq.InputRadio
v-model="testAlign"
:items="['left', 'center', 'right']"
/>
</Tq.Parameter>
<Tq.Parameter label="Radio">
<Tq.InputDropdown
v-model="colorSpace"
:items="['r|g|b', 'svh', 'hsv', 'hvs', 'hsvr']"
:labels="['RGB', 'SVH', 'HSV', 'HVS', 'Radial']"
/>
</Tq.Parameter>
<Tq.Parameter label="Button">
<Tq.InputButton label="Hey" />
</Tq.Parameter>
</Tq.ParameterGrid>
</Tq.FloatingPane>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/tweeq/CommandPalette/CommandPalette.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {search} from 'fast-fuzzy'
import {computed, ref, watch} from 'vue'
import {type Action, useActions} from '../useActions'
import {unsignedMod} from '../util'
const {actions} = useActions()
Expand Down Expand Up @@ -54,8 +55,7 @@ function onKeydown(e: KeyboardEvent) {
const move = e.key === 'ArrowDown' ? 1 : -1
const newIndex = (index + move + length) % length
const newIndex = unsignedMod(index + move, length)
selectedAction.value = filteredActions.value[newIndex]
}
Expand Down
87 changes: 87 additions & 0 deletions src/tweeq/GlslCanvas.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<script lang="ts">
import _ from 'lodash'
import Regl from 'regl'
import REGL from 'regl'
import {
computed,
defineComponent,
onMounted,
onUnmounted,
PropType,
ref,
watch,
} from 'vue'
import {REGL_QUAD_DEFAULT} from './util'
interface UniformsProp {
[name: string]: number[] | string
}
export default defineComponent({
name: 'GlslCnavas',
props: {
fragmentString: {
type: String,
default: `
precision mediump float;
varying vec2 uv;
void main() { gl_FragColor = vec4(uv, 0, 1); }`,
},
uniforms: {
type: Object as PropType<UniformsProp>,
default: () => ({}),
},
},
setup(props) {
const canvas = ref<null | HTMLCanvasElement>(null)
const regl = ref<null | REGL.Regl>(null)
onMounted(() => {
if (!canvas.value) {
return
}
regl.value = Regl({
attributes: {
depth: false,
premultipliedAlpha: false,
},
canvas: canvas.value,
})
})
onUnmounted(() => regl.value?.destroy())
const uniformKeys = ref(_.keys(props.uniforms))
const drawCommand = computed(() => {
if (!regl.value) return null
const prop = regl.value.prop as any
const uniforms = _.fromPairs(uniformKeys.value.map(k => [k, prop(k)]))
return regl.value({
...REGL_QUAD_DEFAULT,
frag: props.fragmentString,
uniforms,
})
})
watch(
() => [regl.value, drawCommand.value, props.uniforms],
() => {
drawCommand.value && drawCommand.value(props.uniforms)
}
)
return {canvas}
},
})
</script>

<template>
<canvas ref="canvas" />
</template>
28 changes: 28 additions & 0 deletions src/tweeq/InputButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<button class="InputButton">{{ label }}</button>
</template>

<script lang="ts" setup>
interface Props {
label: string
}
withDefaults(defineProps<Props>(), {label: ''})
</script>

<style lang="stylus" scoped>
@import './common.styl'
.InputButton
padding 0 1em
height var(--tq-input-height)
border-radius var(--tq-input-border-radius)
background var(--tq-color-primary-container)
color var(--md-sys-color-on-primary-container)
font-size inherit
hover-transition(background, collor)
&:hover, &:focus-visible
color var(--tq-color-on-primary)
background var(--tq-color-primary)
</style>
149 changes: 149 additions & 0 deletions src/tweeq/InputColorPicker/InputColorPicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<template>
<div class="InputColorPicker">
<div class="InputColorPicker__wrapper">
<div
v-for="({name, mode}, i) in pickerData"
:key="i"
class="InputColorPicker__picker"
>
<component
:is="name"
:rgba="rgba"
:mode="mode"
@partialUpdate="onPartialUpdate"
/>
</div>
<Button
v-if="isEyeDropperSupported"
class="InputColorPicker__eyeDropper"
label="Pick Color"
@click="pickColor"
/>
</div>
</div>
</template>

<script lang="ts">
import {computed, defineComponent, shallowRef, watch} from 'vue'
import InputButton from '../InputButton.vue'
import SliderAlpha from './SliderAlpha.vue'
import SliderHSV from './SliderHSV.vue'
import SliderHSVRadial from './SliderHSVRadial.vue'
import SliderRGB from './SliderRGB.vue'
import {color2rgba, RGBA, rgba2color} from './use-hsv'
export default defineComponent({
name: 'InputColorPicker',
components: {
SliderHSV,
SliderHSVRadial,
SliderRGB,
SliderAlpha,
InputButton,
},
props: {
modelValue: {
type: String,
required: true,
},
colorSpace: {
type: String,
default: 'rgba',
},
pickers: {
type: String,
default: 'svh,a',
},
},
emit: ['update:modelValue'],
setup(props, context) {
const rgba = shallowRef<RGBA>({r: 0, g: 0, b: 0, a: 0})
const hasAlpha = computed(() => props.colorSpace.endsWith('a'))
const colorString = computed(() => rgba2color(rgba.value, hasAlpha.value))
watch(
() => props.modelValue,
() => {
if (props.modelValue !== colorString.value) {
const _rgba = color2rgba(props.modelValue, hasAlpha.value)
if (!_rgba) {
return
}
rgba.value = _rgba
}
},
{immediate: true}
)
function onPartialUpdate(newPartialDict: Partial<RGBA>) {
const newDict = {...rgba.value, ...newPartialDict}
rgba.value = newDict
const newValue = rgba2color(newDict, hasAlpha.value)
context.emit('update:modelValue', newValue)
}
const pickerData = computed(() =>
props.pickers
.split(',')
.map(picker => {
if (/^[hsv]{3}$/.test(picker)) {
return {name: 'SliderHSV', mode: picker}
} else if (['r', 'g', 'b'].includes(picker)) {
return {name: 'SliderRGB', mode: picker}
} else if (picker === 'hsvr') {
return {name: 'SliderHSVRadial'}
} else if (picker === 'a') {
return {name: 'SliderAlpha'}
}
return null
})
.filter(v => v !== null)
)
// EyeDropper
const isEyeDropperSupported = 'EyeDropper' in window
async function pickColor() {
const eyeDropper = new (window as any)['EyeDropper']()
const newValue: string = (await eyeDropper.open()).sRGBHex
context.emit('update:modelValue', newValue)
}
return {
rgba,
onPartialUpdate,
pickerData,
isEyeDropperSupported,
pickColor,
}
},
})
</script>

<style lang="stylus">
@import './common.styl'
.InputColorPicker
padding 0
&__wrapper
position relative
&__picker
margin-bottom $picker-gap
&:last-child
margin-bottom 0
&__eyeDropper
display block
margin 0 auto
</style>
Loading

0 comments on commit 0fed88a

Please sign in to comment.