This commit is contained in:
Kseninia Mikhaylova 2024-09-24 15:50:45 +03:00
parent 127447eeaf
commit e6c25b4be2
12 changed files with 137 additions and 27 deletions

View File

@ -345,8 +345,10 @@ button {
&_checkbox {
@apply w-full xl:w-auto flex-row xl:flex-initial flex-nowrap gap-4;
}
&_color {
@apply w-full;
.color_picker {
@apply ml-4;
}
@ -374,6 +376,34 @@ button {
}
}
.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 {
@apply flex gap-4 w-full;
}
&-item {
@apply w-10 h-10;
&--empty {
@apply block bg-slate-300;
}
}
}
.feature {
@apply col-span-full flex gap-10 mt-4 justify-center xl:justify-between flex-wrap items-center;

View File

@ -1,15 +1,16 @@
<script setup lang="ts">
import { getColorHexFromRal, getColorNameFromRal } from '@/components/ral'
import type { ralTypes } from '@/components/ral'
import { Color } from 'three';
import { predefLamelleColors, predefPillarColors } from '~/composables/useCalc';
import type { patternTypes } from '../pattern';
const lamelle_height = use_lamelle_height()
const lamelles_count = use_lamelles_count()
const fence_section = use_fence_section()
const remove_pillar = use_remove_pillar()
const pillar_color = use_pillar_color()
const pillar_pattern = use_pattern()
const lamelle_color = use_lamelle_color()
const section_count = use_section_count()
const extra_section = use_extra_section()
@ -143,6 +144,9 @@ const setPillarColor = (color: ralTypes) => {
pillar_color.value = color
pillar_text.value = contrastColor(color) ?? '#000'
}
const setPillarPattern = (pattern:patternTypes) => {
pillar_pattern.value = pattern
}
watch(() => form_state, changeParametres, { deep: true })
const isModalOpen = useState('modal_open', () => false)
@ -223,20 +227,24 @@ const calc_table = computed(() => {
<div class="form-row">
<div class="form-item form-item_color">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
:style="{
backgroundColor: getColorHexFromRal(lamelle_color) ?? 'transparent',
color: lamelle_text
}" disabled />
<ColorPicker :cb="setLamelleColor" />
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" :style="{
backgroundColor: getColorHexFromRal(lamelle_color) ?? 'transparent',
color: lamelle_text
}" disabled />
<DropdownColorPicker :cb="setLamelleColor" />
</div>
<div class="form-item form-item_color">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" :style="{
backgroundColor: getColorHexFromRal(pillar_color) ?? 'transparent',
color: pillar_text
}" class="w-60" disabled />
<ColorPicker :cb="setPillarColor" />
}" disabled />
<DropdownColorPicker :cb="setPillarColor" />
</div>
<div class="form-item form-item_color">
<label for="pattern">Узор</label>
<input id="pattern" type="text" :value="pillar_pattern" />
<DropdownList :cb="setPillarPattern" />
</div>
</div>
</div>

View File

@ -0,0 +1,49 @@
<script setup lang="ts">
import { getFilename, patterns } from '../pattern';
const props = defineProps(['color', 'cb', 'open', 'active'])
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>
<template>
<div class="list_picker" ref="picker">
<div class="list_picker-selected" @click="open ? toggleOpen(!is_open) : onClick(props.color)"
:class="[{ 'list_picker-selected__active': active }]">
pick
</div>
<div class="list_picker-changer" v-if="is_open">
<div class="list_picker-list">
<template v-for="item in patterns">
<NuxtImg :src="getFilename(item.name)" class="list_picker-item" @click="onClick(item.name)"
v-if="item.filename" />
<span class=" list_picker-item list_picker-item--empty" @click="onClick(item.name)" v-else />
</template>
</div>
</div>
</div>
</template>

View File

@ -13,8 +13,10 @@ import { GainMapLoader, } from '@monogrid/gainmap-js'
//@ts-ignore
import { useGLTF, } from '@tresjs/cientos'
import { getColorHexFromRal, type ralTypes } from '../ral';
import { getFilename } from '../pattern';
const pillar_color = use_pillar_color()
const pillar_pattern = use_pattern()
const lamelle_color = use_lamelle_color()
const section_count = use_section_count()
const lamelle_count = use_lamelles_count()
@ -76,8 +78,6 @@ watch(lamelle_color, () => {
watch(pillar_color, () => {
[top, fastening, fence, fence_bottom, fence_top].map(
(el: Ref) => { set_material(el.value, getColorHexFromRal(pillar_color.value)) });
[fence_inner].map(
(el: Ref) => { set_material(el.value, getColorHexFromRal(pillar_color.value), lamelle_count.value) });
const items = [
...seekAll(scene.value, 'name', "pillar_one"),
@ -90,6 +90,15 @@ watch(pillar_color, () => {
set_material(element, getColorHexFromRal(pillar_color.value))
})
})
watch([pillar_color, pillar_pattern], () => {
[fence_inner].map(
(el: Ref) => {
set_material(el.value, getColorHexFromRal(pillar_color.value), {
pattern: pillar_pattern.value,
count: lamelle_count.value
})
});
})
const total = ref((section_count.value + ~~(!!extra_section.value)))
const size = ref(Math.ceil(total.value / 4))
@ -154,8 +163,8 @@ onMounted(async () => {
<template>
<TresGroup name="base">
<template v-for="line in (total >= 4) ? 4 : 1" :key="`${line}_${count}`">
<ModelLine :models="{ top, fence, fence_top, fence_bottom, fence_inner, fastening, lamelle }"
:number="line" :count="count" />
<ModelLine :models="{ top, fence, fence_top, fence_bottom, fence_inner, fastening, lamelle }" :number="line"
:count="count" />
</template>
</TresGroup>
</template>

10
components/pattern.ts Normal file
View File

@ -0,0 +1,10 @@
export const patterns = [
{ name: 'no pattern', },
{ name: 'pattern1', filename: 'tile1.png' },
{ name: 'pattern2', filename: 'tile1.png' },
]
export const getFilename = (name: patternTypes) => {
return `/pattern/${patterns.find(el => el.name == name)?.filename}`
}
export type patternTypes = typeof patterns[number]['name']

View File

@ -1,7 +0,0 @@
<script setup lang="ts">
const props = defineProps(['forms', 'n'])
const ruOrdinalRules = new Intl.PluralRules("ru-RU");
</script>
<template>
{{ props.forms[ruOrdinalRules.select(props.n)] }}
</template>

View File

@ -1,4 +1,5 @@
import type { ralTypes } from '@/components/ral'
import { type patternTypes } from '~/components/pattern'
export const predefPillarColors = ['3004', '7043', '6028', '5013', '8016', '1020', '3005', '4009']
export const predefLamelleColors = ['3009', '9003', '6027', '5024', '9001', '1012', '3007', '4007']
@ -12,6 +13,7 @@ export const use_fence_section = () => useState<number>('fence_section', () => m
export const use_remove_pillar = () => useState<boolean>('remove_pillar', () => false)
export const use_pillar_color = () => useState<ralTypes>('pillar_color')
export const use_lamelle_color = () => useState<ralTypes>('lamelle_color')
export const use_pattern = () => useState<patternTypes>('pattern')
export const use_section_count = () => useState('section_count', () => n)
export const use_extra_section = () => useState('extra_section', () => 0)
export const use_total_length = () => useState('total_length', () => (((min + 104) * n) + 104) * 0.001)

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,5 +1,6 @@
import { Color, DoubleSide, MeshBasicMaterial, MeshStandardMaterial, RepeatWrapping, TextureLoader, Vector2 } from "three"
import { useLoader, type TresLoader } from '@tresjs/core'
import { getFilename, type patternTypes } from "~/components/pattern"
const set_metaril_func = (scene: any, material: any) => {
scene.children.forEach((el: any) => {
@ -19,22 +20,30 @@ const set_metaril_func = (scene: any, material: any) => {
// const texture = await get_texture()
// texture.wrapT = RepeatWrapping;
export const set_material = (scene: any, color: any, count: number | undefined = undefined) => {
export const set_material = (scene: any, color: any, pattern: { pattern: patternTypes, count: number } | undefined = undefined) => {
let c = color
// if (count) {
// // console.log(texture)
// texture.repeat.set(1, count);
// texture.needsUpdate = true
// }
const material = new MeshStandardMaterial({
color: new Color(c || '#9c9c00'),
// alphaMap: count ? texture : null,
// alphaMap: pattern ? texture : null,
transparent: true,
opacity: 1,
roughness: 0.2,
metalness: 0,
side: DoubleSide,
})
if (pattern && pattern.pattern !== undefined) {
const filename = getFilename(pattern.pattern)
const texture = useLoader(TextureLoader, filename)
texture.then(res => {
res.wrapT = RepeatWrapping;
res.repeat.set(1, pattern.count);
res.needsUpdate = true
// return res
material.alphaMap = res
})
}
set_metaril_func(scene, material)
}