dev #84

Merged
ksenia_mikhailova merged 141 commits from dev into main 2024-10-03 15:30:24 +03:00
9 changed files with 161 additions and 148 deletions
Showing only changes of commit 1e14b9dc95 - Show all commits

View File

@ -348,11 +348,6 @@ button {
&_color { &_color {
@apply w-full; @apply w-full;
.color_picker,
.list_picker {
// @apply ml-4;
}
} }
input[type=range] { input[type=range] {
@ -361,35 +356,15 @@ button {
} }
} }
.color_picker { .picker {
@apply leading-none; @apply leading-none;
&-selected { &-selected {
@apply size-10 rounded border-gray-300 shadow inline-block leading-none; @apply size-10 rounded border-gray-300 shadow inline-block leading-none;
&__active {
@apply outline outline-2 outline-offset-2 outline-primary;
}
} }
&-changer { &-changer {
@apply absolute w-80 z-20 p-4 border rounded bg-white flex gap-0 right-0; @apply flex gap-0;
}
}
.list_picker {
@apply leading-none;
&-selected {
@apply size-10 rounded border-gray-300 shadow inline-block leading-none;
&__active {
@apply outline outline-2 outline-offset-2 outline-primary;
}
}
&-changer {
@apply absolute w-80 z-20 p-4 border rounded bg-white flex gap-0 right-0;
} }
&-list { &-list {

View File

@ -4,7 +4,6 @@ import { Stats, OrbitControls } from '@tresjs/cientos'
import { degToRad } from 'three/src/math/MathUtils.js'; import { degToRad } from 'three/src/math/MathUtils.js';
const section_count = use_section_count() const section_count = use_section_count()
const extra_section = use_extra_section()
const fence_section = use_fence_section() const fence_section = use_fence_section()
const defDistance = 3 const defDistance = 3
@ -47,12 +46,14 @@ watch(fence_section, ()=>{
<TresCanvas> <TresCanvas>
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" /> <TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
<OrbitControls v-bind="controlsState" make-default /> <OrbitControls v-bind="controlsState" make-default />
<Suspense>
<ModelCamera />
</Suspense>
<TresGroup :position-y="-0.5"> <TresGroup :position-y="-0.5">
<Suspense> <Suspense>
<ModelParametric /> <ModelParametric />
</Suspense> </Suspense>
</TresGroup> </TresGroup>
</TresCanvas> </TresCanvas>
</ClientOnly> </ClientOnly>
</div> </div>

View File

@ -139,12 +139,10 @@ const changeParametres = () => {
const setLamelleColor = (color: ralTypes) => { const setLamelleColor = (color: ralTypes) => {
goto_cam.value = new Vector3(-2, -2, -2)
lamelle_color.value = color; lamelle_color.value = color;
lamelle_text.value = contrastColor(color) ?? '#000' lamelle_text.value = contrastColor(color) ?? '#000'
} }
const setPillarColor = (color: ralTypes) => { const setPillarColor = (color: ralTypes) => {
goto_cam.value = new Vector3(2, 2, 2)
pillar_color.value = color pillar_color.value = color
pillar_text.value = contrastColor(color) ?? '#000' pillar_text.value = contrastColor(color) ?? '#000'
} }
@ -225,43 +223,48 @@ const calc_table = computed(() => {
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" /> <input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
<label for="remove_pillar">Без столбов</label> <label for="remove_pillar">Без столбов</label>
</div> </div>
</div> </div>
</div> </div>
<div class="col-span-3 col-start-10"> <div class="col-span-3 col-start-10">
<div class="form-row"> <div class="form-row">
<div class="form-item form-item_color"> <div class="form-item form-item_color">
<label for="lamelle_color">Цвет ламелей</label> <label for="lamelle_color">Цвет ламелей</label>
<DropdownColorPicker :cb="setLamelleColor"> <DropdownPicker type="color" :cb="setLamelleColor" name="lamelle_color">
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" :style="{ <input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" :style="{
backgroundColor: getColorHexFromRal(lamelle_color) ?? 'transparent', backgroundColor: getColorHexFromRal(lamelle_color) ?? 'transparent',
color: lamelle_text color: lamelle_text
}" /> }" />
</DropdownColorPicker> </DropdownPicker>
</div> </div>
<div class="form-item form-item_color"> <div class="form-item form-item_color">
<label for="pillar_color">Цвет столба</label> <label for="pillar_color">Цвет столба</label>
<DropdownColorPicker :cb="setPillarColor"> <DropdownPicker type="color" :cb="setPillarColor" name="pillar_color">
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" :style="{ <input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" :style="{
backgroundColor: getColorHexFromRal(pillar_color) ?? 'transparent', backgroundColor: getColorHexFromRal(pillar_color) ?? 'transparent',
color: pillar_text color: pillar_text
}" /> }" />
</DropdownColorPicker> </DropdownPicker>
</div> </div>
<div class="form-item form-item_color"> <div class="form-item form-item_color">
<label for="pillar_pattern">Узор столба</label> <label for="pillar_pattern">Узор столба</label>
<DropdownList :cb="setPillarPattern"> <DropdownPicker type="pattern" :cb="setPillarPattern">
<input id="pillar_pattern" type="text" :value="pillar_pattern" :style="{ <input id="pillar_pattern" type="text" :value="pillar_pattern" :style="{
backgroundImage: `url(${getFilename(pillar_pattern)})`}" /> backgroundImage: `url(${getFilename(pillar_pattern)})`
</DropdownList> }" />
</DropdownPicker>
</div> </div>
{{ goto_cam }}
</div> </div>
</div> </div>
<template v-if="(form_state.total_length * 1000) >= parametric.length.min"> <template v-if="(form_state.total_length * 1000) >= parametric.length.min">
<div class="col-span-12 xl:col-span-6 xl:col-start-4 grid calc_table"> <div class="col-span-12 xl:col-span-6 xl:col-start-4 grid calc_table">
<div class="grid grid-cols-4 relative"> <div class="grid grid-cols-4 relative">
<template v-for="item in calc_table"> <template v-for="item in calc_table">
<div class="col-span-3 calc_table-maincell">{{ <div class="col-span-3 calc_table-maincell">
item.name }}</div> {{ item.name }}
</div>
<div class="col-span-1 calc_table-maincell">{{ item.value }}</div> <div class="col-span-1 calc_table-maincell">{{ item.value }}</div>
</template> </template>
</div> </div>
@ -274,7 +277,8 @@ const calc_table = computed(() => {
#pillar_pattern { #pillar_pattern {
background-clip: content-box; background-clip: content-box;
background-size: contain; background-size: contain;
&:not([style*='url("undefined")']) {
&[style*='url("/'] {
color: transparent; color: transparent;
} }
} }

View File

@ -1,61 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ralClassicPallette, getColorHexFromRal } from '@/components/ral' import { ralClassicPallette } from '@/components/ral'
const props = defineProps(['color', 'cb', 'open', 'active']) const props = defineProps(['color', 'cb'])
const open = props.open ?? true
const goto_cam = use_goto_camera()
const onClick = (color: string) => {
if (props.cb) {
props.cb(color)
}
toggleOpen()
}
const isOpenPicker = ref<boolean>(false)
const toggleOpen = (value: boolean = !isOpenPicker) => {
if (value == false) {
goto_cam.value = undefined
}
isOpenPicker.value = value !== undefined ? value : !isOpenPicker.value
}
const picker = ref()
const clickOutside = (e: Event) => {
if (!picker.value.contains(e.target)) {
toggleOpen(false)
}
}
onMounted(() => {
document.addEventListener('click', clickOutside)
})
onUnmounted(() => {
document.removeEventListener('click', clickOutside)
})
</script> </script>
<template> <template>
<div class="color_picker" ref="picker">
<template v-if="$slots.default">
<div @click="open ? toggleOpen(!isOpenPicker) : onClick(props.color)">
<slot></slot>
</div>
</template>
<template v-else>
<div class="color_picker-selected" @click="open ? toggleOpen(!isOpenPicker) : onClick(props.color)"
:style="[props.color && { backgroundColor: getColorHexFromRal(props.color) ?? '' }]"
:class="[{ 'color_picker-selected__active': active }]"></div>
</template>
<div class="color_picker-changer flex flex-wrap" v-if="isOpenPicker">
<template v-for="col in ralClassicPallette"> <template v-for="col in ralClassicPallette">
<div class="color size-5" :class="[{ 'outline outline-primary': props.color == col.hex }]" <div class="color size-5" :class="[{ 'outline outline-primary': props.color == col.hex }]"
:style="[{ backgroundColor: col.hex }]" @click="onClick(col.code)"> :style="[{ backgroundColor: col.hex }]" @click="props.cb(col.code)">
</div> </div>
</template> </template>
</div>
</div>
</template> </template>
<style scoped>
.color_picker-selected:not([style*=color]) {
background-image: conic-gradient(from 50deg, orange, yellow, green, cyan, blue, violet)
}
</style>

View File

@ -1,56 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { getFilename, patterns } from '../pattern'; import { getFilename, patterns } from '../pattern';
const props = defineProps(['color', 'cb', 'open', 'active']) const props = defineProps(['color', 'cb'])
const open = props.open ?? true
const is_open = ref<boolean>(false)
const picker = ref()
const onClick = (color: string) => {
if (props.cb) {
props.cb(color)
}
toggleOpen()
}
const toggleOpen = (value: boolean = !is_open) => {
is_open.value = value !== undefined ? value : !is_open.value
}
const clickOutside = (e: Event) => {
if (!picker.value.contains(e.target)) {
toggleOpen(false)
}
}
onMounted(() => {
document.addEventListener('click', clickOutside)
})
onUnmounted(() => {
document.removeEventListener('click', clickOutside)
})
</script> </script>
<template> <template>
<div class="list_picker" ref="picker">
<template v-if="$slots.default">
<div @click="open ? toggleOpen(!is_open) : onClick(props.color)">
<slot></slot>
</div>
</template>
<template v-else>
<div class="list_picker-selected" @click="open ? toggleOpen(!is_open) : onClick(props.color)"
:class="[{ 'list_picker-selected__active': active }]">
<NuxtImg :src="getFilename(patterns[1].name)" />
</div>
</template>
<div class="list_picker-changer" v-if="is_open">
<div class="list_picker-list">
<template v-for="item in patterns"> <template v-for="item in patterns">
<NuxtImg :src="getFilename(item.name)" class="list_picker-item" @click="onClick(item.name)" <NuxtImg :src="getFilename(item.name)" class="picker-item" @click="props.cb(item.name)"
v-if="item.filename" /> v-if="item.filename" />
<span class=" list_picker-item list_picker-item--empty" @click="onClick(item.name)" v-else /> <span class="picker-item list_picker-item--empty" @click="props.cb(item.name)" v-else />
</template> </template>
</div>
</div>
</div>
</template> </template>

View File

@ -0,0 +1,73 @@
<script setup lang="ts">
import { ralClassicPallette, getColorHexFromRal } from '@/components/ral'
const props = defineProps(['color', 'cb', 'name', 'type'])
const goto_cam = use_goto_camera()
const open_calc = use_open_calc()
const picker = ref()
const is_open = ref<boolean>(open_calc.value.includes(props.name))
const toggleOpen = (value: boolean = !is_open) => {
is_open.value = value
if (value == true) open_calc.value = [props.name]
else if (value == false) open_calc.value.splice(open_calc.value.indexOf(props.name), 1)
if (value == true) goto_cam.value = undefined
else if (value == false) goto_cam.value = undefined
}
const onClick = (color: string) => {
if (props.cb) {
props.cb(color)
}
}
const clickOutside = (e: Event) => {
if (!picker.value.contains(e.target)) {
toggleOpen(false)
}
}
onMounted(() => {
document.addEventListener('click', clickOutside)
})
onUnmounted(() => {
document.removeEventListener('click', clickOutside)
})
watch(open_calc, () => {
if (open_calc.value.includes(props.name) && is_open.value !== true) {
is_open.value = true
} else if (!open_calc.value.includes(props.name) && is_open.value !== false) {
is_open.value = false
}
})
</script>
<template>
<div class="picker" ref="picker">
<template v-if="$slots.default">
<div @click="toggleOpen(!is_open)">
<slot></slot>
</div>
</template>
<template v-else>
<div class="picker-selected" @click="toggleOpen(!is_open)"
:style="[props.color && { backgroundColor: getColorHexFromRal(props.color) ?? '' }]"></div>
</template>
<div class="picker-changer flex flex-wrap" v-if="is_open">
<template v-if="props.type == 'color'">
<DropdownColorPicker :color="props.color" :cb="onClick" />
</template>
<template v-else-if="props.type == 'pattern'">
<DropdownList :color="props.color" :cb="onClick" />
</template>
</div>
</div>
</template>
<style scoped>
.color_picker-selected:not([style*=color]) {
background-image: conic-gradient(from 50deg, orange, yellow, green, cyan, blue, violet)
}
</style>

View File

@ -0,0 +1,50 @@
<script setup lang="ts">
import { useLoop } from '@tresjs/core';
import { Vector3 } from 'three';
const { controls, camera } = useTresContext();
const goto_camera = use_goto_camera();
const COUNT = 30
type smooth = {
value: Vector3 | undefined,
count: number
}
const smooth_target = reactive({}) as smooth
const smooth_move = reactive({}) as smooth
const set_moveto = (obj: smooth, value: smooth["value"]) => {
obj.value = value
obj.count = COUNT
}
watch(goto_camera, () => {
smooth_target.value = goto_camera.value
smooth_target.count = COUNT
})
const koef = (1 / COUNT) * 3
const { onBeforeLoop } = useRenderLoop()
onBeforeLoop(() => {
if (smooth_target.value || smooth_move.value) {
if (smooth_target.value) {
(controls.value as any).target.lerp(smooth_target.value as Vector3, koef);
(controls.value as any).update();
smooth_target.count -= 1;
if (smooth_target.count == 1) {
set_moveto(smooth_target, undefined);
}
} else if (smooth_move.value) {
camera.value?.position.lerp(smooth_move.value as Vector3, koef);
camera.value?.updateMatrixWorld();
(controls.value as any).update();
smooth_move.count -= 1;
if (smooth_move.count == 1) {
set_moveto(smooth_move, undefined);
}
}
}
})
</script>
<template></template>

View File

@ -23,3 +23,4 @@ export const use_max_size = () => useState<number>('max_size', () => 20)
export const use_explosion_state = () => useState<boolean>('explosion_state', () => false) export const use_explosion_state = () => useState<boolean>('explosion_state', () => false)
export const use_goto_camera = () => useState<Vector3 | undefined>('gotocam', () => undefined) export const use_goto_camera = () => useState<Vector3 | undefined>('gotocam', () => undefined)
export const use_open_calc = () => useState<string[]>('open_calc', () => [])

View File

@ -1,6 +1,7 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
devtools: { enabled: false },
hooks: {}, hooks: {},
app: { app: {
pageTransition: { name: 'page', mode: 'out-in' }, pageTransition: { name: 'page', mode: 'out-in' },