bx-1480-constructor #68
|
@ -178,10 +178,17 @@ a[href^="#"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
&_calc {
|
&_calc {
|
||||||
@apply py-0;
|
@apply py-0 relative;
|
||||||
|
|
||||||
|
> .container:first-child {
|
||||||
|
@apply relative h-[50vh] min-h-[600px] justify-between;
|
||||||
|
> * {
|
||||||
|
@apply z-10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-canvas {
|
&-canvas {
|
||||||
@apply relative h-[50vh] min-h-[600px];
|
@apply absolute top-0 bottom-0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,10 +308,10 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
@apply flex flex-row gap-4 items-center justify-start xl:justify-center flex-wrap xl:flex-nowrap;
|
@apply flex flex-row items-center justify-start flex-wrap;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@apply w-full xl:w-auto;
|
@apply w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
@ -316,7 +323,7 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
&_checkbox {
|
&_checkbox {
|
||||||
@apply w-full xl:w-auto flex-row xl:flex-initial flex-nowrap
|
@apply w-full xl:w-auto flex-row xl:flex-initial flex-nowrap gap-4
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=range] {
|
input[type=range] {
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
import { TresCanvas } from '@tresjs/core'
|
import { TresCanvas } from '@tresjs/core'
|
||||||
import { OrbitControls } from '@tresjs/cientos'
|
import { OrbitControls } from '@tresjs/cientos'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { useGLTF } from '@tresjs/cientos'
|
import { useGLTF, Stats } from '@tresjs/cientos'
|
||||||
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
|
import { degToRad } from 'three/src/math/MathUtils.js';
|
||||||
|
|
||||||
const fence_section = use_fence_section()
|
|
||||||
const section_count = use_section_count()
|
const section_count = use_section_count()
|
||||||
const extra_section = use_extra_section()
|
const extra_section = use_extra_section()
|
||||||
const max_size = use_max_size()
|
const max_size = use_max_size()
|
||||||
|
@ -13,14 +12,15 @@ const max_size = use_max_size()
|
||||||
const controlsState = reactive({
|
const controlsState = reactive({
|
||||||
distance: section_count.value,
|
distance: section_count.value,
|
||||||
minDistance: 10,
|
minDistance: 10,
|
||||||
maxDistance: 20,
|
maxDistance: 10,
|
||||||
position: { x: 0, y: 0, z: 0 },
|
position: { x: 0, y: 0, z: 0 },
|
||||||
// enablePan: false,
|
enablePan: false,
|
||||||
minPolarAngle: degToRad(30),
|
enableZoom: false,
|
||||||
maxPolarAngle: degToRad(80),
|
minPolarAngle: degToRad(45),
|
||||||
|
maxPolarAngle: degToRad(45),
|
||||||
})
|
})
|
||||||
const cameraStat = reactive({
|
const cameraStat = reactive({
|
||||||
position: [-4, 2, 8],
|
position: [-5, 7, 5],
|
||||||
aspect: 1920 / 600,
|
aspect: 1920 / 600,
|
||||||
// fov: 40,
|
// fov: 40,
|
||||||
})
|
})
|
||||||
|
@ -50,10 +50,11 @@ onMounted(() => {
|
||||||
loadAll()
|
loadAll()
|
||||||
})
|
})
|
||||||
watch([section_count, extra_section], () => {
|
watch([section_count, extra_section], () => {
|
||||||
let v = (section_count.value + ~~(!!extra_section.value)) * 2
|
let v = (section_count.value + ~~(!!extra_section.value));
|
||||||
if (v < controlsState.minDistance) v = controlsState.minDistance;
|
if (v <= 10) v = 10
|
||||||
if (v > controlsState.maxDistance) v = controlsState.maxDistance;
|
controlsState.minDistance = v;
|
||||||
// (camera.value as any).position.normalize().multiplyScalar(v)
|
controlsState.maxDistance = v;
|
||||||
|
(camera.value as any).position.normalize().multiplyScalar(v)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -65,6 +66,7 @@ watch([section_count, extra_section], () => {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<Loader />
|
<Loader />
|
||||||
|
<Stats />
|
||||||
<TresCanvas clear-color="#ccc">
|
<TresCanvas clear-color="#ccc">
|
||||||
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
|
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
|
||||||
<OrbitControls v-bind="controlsState" make-default />
|
<OrbitControls v-bind="controlsState" make-default />
|
||||||
|
|
|
@ -151,69 +151,62 @@ const goal = (target: string, params: object) => {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="container relative py-4">
|
<div class="container relative py-4">
|
||||||
<form class="form">
|
<div class="col-span-4">
|
||||||
<div class="col-span-12 sm:col-span-6">
|
<div class="form-row">
|
||||||
<div class="form-row">
|
<div class="form-item w-full">
|
||||||
<div class="form-item w-full">
|
<label for="length">Длина ламельного блока, мм</label>
|
||||||
<label for="length">Длина ламельного блока, мм</label>
|
<input disabled :value.input="`${form_state.length.toFixed(0)} мм`" class="w-28" />
|
||||||
<input disabled :value.input="`${form_state.length.toFixed(0)} мм`" class="w-28" />
|
<input id="length" type="range" class="xl:w-full" v-bind="parametric.length"
|
||||||
<input id="length" type="range" class="xl:w-full" v-bind="parametric.length"
|
v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" />
|
||||||
v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" />
|
</div>
|
||||||
</div>
|
<div class="form-item w-full">
|
||||||
<div class="form-item w-full">
|
<label for="height">Высота забора, мм</label>
|
||||||
<label for="height">Высота забора, мм</label>
|
<input disabled :value="`${form_state.height} мм`" class="w-28" />
|
||||||
<input disabled :value="`${form_state.height} мм`" class="w-28" />
|
<input id="height" type="range" class="xl:w-full" v-bind="parametric.height"
|
||||||
<input id="height" type="range" class="xl:w-full" v-bind="parametric.height"
|
v-model="form_state.height" :ref="form_refs.height" />
|
||||||
v-model="form_state.height" :ref="form_refs.height" />
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="lamelle_color">Цвет ламелей</label>
|
||||||
|
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
|
||||||
|
disabled />
|
||||||
|
<ColorPicker :cb="setLamelleColor" />
|
||||||
|
</div>
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="pillar_color">Цвет столба</label>
|
||||||
|
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
|
||||||
|
disabled />
|
||||||
|
<ColorPicker :cb="setPillarColor" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="total_length">Общая длина забора, м</label>
|
||||||
|
<input type="number" id="total_length" v-bind="parametric.total_length" min=0
|
||||||
|
v-model="form_state.total_length" :ref="form_refs.total_length" />
|
||||||
|
</div>
|
||||||
|
<div class="form-item xl:w-2/4 text-sm xl:text-base">
|
||||||
|
<p v-if="form_state.total_length_mm < parametric.length.min" class="text-ioprim">
|
||||||
|
Выбранный размер забора слишком мал для расчета стоимости. Пожалуйста, выберите больший
|
||||||
|
размер, чтобы продолжить.
|
||||||
|
</p>
|
||||||
|
<p v-if="form_state.extra_section" class="text-ioprim">
|
||||||
|
Внимание! Дополнительная секция приводит к увеличению стоимости.
|
||||||
|
Рекомендуем вам изменить длину забора или длину секции!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-item form-item_checkbox">
|
||||||
|
<input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
|
||||||
|
<label for="auto_length">Автоматический подбор секции</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-item form-item_checkbox">
|
||||||
|
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
|
||||||
|
<label for="remove_pillar">Без столбов</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-12 sm:col-span-6">
|
</div>
|
||||||
<div class="form-row">
|
<template v-if="(form_state.total_length * 1000) >= parametric.length.min">
|
||||||
<div class="form-item">
|
<div class="col-span-4 col-start-9">
|
||||||
<label for="lamelle_color">Цвет ламелей</label>
|
|
||||||
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
|
|
||||||
disabled />
|
|
||||||
<ColorPicker :cb="setLamelleColor" />
|
|
||||||
</div>
|
|
||||||
<div class="form-item">
|
|
||||||
<label for="pillar_color">Цвет столба</label>
|
|
||||||
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
|
|
||||||
disabled />
|
|
||||||
<ColorPicker :cb="setPillarColor" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-item">
|
|
||||||
<label for="total_length">Общая длина забора, м</label>
|
|
||||||
<input type="number" id="total_length" v-bind="parametric.total_length" min=0
|
|
||||||
v-model="form_state.total_length" :ref="form_refs.total_length" />
|
|
||||||
</div>
|
|
||||||
<div class="form-item xl:w-2/4 text-sm xl:text-base">
|
|
||||||
<p v-if="form_state.total_length_mm < parametric.length.min" class="text-ioprim">
|
|
||||||
Выбранный размер забора слишком мал для расчета стоимости. Пожалуйста, выберите больший
|
|
||||||
размер, чтобы продолжить.
|
|
||||||
</p>
|
|
||||||
<p v-if="form_state.extra_section" class="text-ioprim">
|
|
||||||
Внимание! Дополнительная секция приводит к увеличению стоимости.
|
|
||||||
Рекомендуем вам изменить длину забора или длину секции!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row min-h-12 mt-2 xl:mt-0">
|
|
||||||
<div class="form-item form-item_checkbox">
|
|
||||||
<input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
|
|
||||||
<label for="auto_length">Автоматический подбор секции</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-item form-item_checkbox">
|
|
||||||
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
|
|
||||||
<label for="remove_pillar">Без столбов</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<template v-if="(form_state.total_length * 1000) >= parametric.length.min">
|
|
||||||
<div class="col-span-12 xl:col-span-8 xl:col-start-3 grid calc_table">
|
<div class="col-span-12 xl:col-span-8 xl:col-start-3 grid calc_table">
|
||||||
<div class="grid grid-cols-6">
|
<div class="grid grid-cols-6">
|
||||||
<div class="col-span-4 calc_table-maincell">Секции</div>
|
<div class="col-span-4 calc_table-maincell">Секции</div>
|
||||||
|
@ -250,7 +243,7 @@ const goal = (target: string, params: object) => {
|
||||||
<div class="col-span-12 text-center mb-4">
|
<div class="col-span-12 text-center mb-4">
|
||||||
<button @click.prevent="toggleModal">Рассчитать</button>
|
<button @click.prevent="toggleModal">Рассчитать</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</form>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
|
@ -9,7 +9,6 @@ const fence_section = use_fence_section()
|
||||||
const section_count = use_section_count()
|
const section_count = use_section_count()
|
||||||
const extra_section = use_extra_section()
|
const extra_section = use_extra_section()
|
||||||
const remove_pillar = use_remove_pillar()
|
const remove_pillar = use_remove_pillar()
|
||||||
const max_size = use_max_size()
|
|
||||||
|
|
||||||
const lSize = lamelle_height.value
|
const lSize = lamelle_height.value
|
||||||
const bSize = 0.0235
|
const bSize = 0.0235
|
||||||
|
|
|
@ -20,6 +20,8 @@ const { scene } = useTresContext()
|
||||||
|
|
||||||
const section_count = use_section_count()
|
const section_count = use_section_count()
|
||||||
const extra_section = use_extra_section()
|
const extra_section = use_extra_section()
|
||||||
|
const fence_section = use_fence_section()
|
||||||
|
const max_size = use_max_size()
|
||||||
|
|
||||||
const total = ref((section_count.value + ~~(!!extra_section.value)))
|
const total = ref((section_count.value + ~~(!!extra_section.value)))
|
||||||
const position = ref(new Vector3())
|
const position = ref(new Vector3())
|
||||||
|
@ -29,12 +31,11 @@ const count_pos = () => {
|
||||||
const line = seekByName(scene.value, `line_${props.number}`)
|
const line = seekByName(scene.value, `line_${props.number}`)
|
||||||
const line_size = new Vector3()
|
const line_size = new Vector3()
|
||||||
const line_pos = new Vector3()
|
const line_pos = new Vector3()
|
||||||
const line_lpos = new Vector3()
|
|
||||||
if (line && line.children.length) {
|
if (line && line.children.length) {
|
||||||
line.updateMatrixWorld()
|
line.updateMatrixWorld()
|
||||||
new Box3().expandByObject(line).getSize(line_size)
|
new Box3().expandByObject(line).getSize(line_size)
|
||||||
line.getWorldPosition(line_pos)
|
line.getWorldPosition(line_pos)
|
||||||
console.log(`line_${props.number}`, line, line_size, line_pos)
|
|
||||||
}
|
}
|
||||||
const line1 = seekByName(scene.value, `line_1`);
|
const line1 = seekByName(scene.value, `line_1`);
|
||||||
const line1_size = new Vector3()
|
const line1_size = new Vector3()
|
||||||
|
@ -42,7 +43,6 @@ const count_pos = () => {
|
||||||
if (line1) {
|
if (line1) {
|
||||||
new Box3().expandByObject(line1).getSize(line1_size)
|
new Box3().expandByObject(line1).getSize(line1_size)
|
||||||
line1.getWorldPosition(line1_pos)
|
line1.getWorldPosition(line1_pos)
|
||||||
console.log('first', line1, line1_size, line1_pos)
|
|
||||||
}
|
}
|
||||||
const k = ((line1_size.x / props.count) - line1_size.z) * 0.5
|
const k = ((line1_size.x / props.count) - line1_size.z) * 0.5
|
||||||
switch (props.number) {
|
switch (props.number) {
|
||||||
|
@ -64,7 +64,7 @@ const count_pos = () => {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
count_pos()
|
count_pos()
|
||||||
})
|
})
|
||||||
watch(() => [props.count, section_count.value, extra_section.value], count_pos)
|
watch(() => [props.count, fence_section.value, section_count.value, extra_section.value], count_pos)
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<TresGroup :name="`line_${props.number}`" :rotate-y="rotate()" :position-x="position.x" :position-y="position.y"
|
<TresGroup :name="`line_${props.number}`" :rotate-y="rotate()" :position-x="position.x" :position-y="position.y"
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
PCFSoftShadowMap,
|
PCFSoftShadowMap,
|
||||||
EquirectangularReflectionMapping,
|
|
||||||
CineonToneMapping,
|
CineonToneMapping,
|
||||||
Euler,
|
|
||||||
Mesh,
|
Mesh,
|
||||||
Group,
|
|
||||||
Object3D,
|
Object3D,
|
||||||
} from 'three';
|
} from 'three';
|
||||||
import { GainMapLoader, } from '@monogrid/gainmap-js'
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { useGLTF, } from '@tresjs/cientos'
|
import { useGLTF, } from '@tresjs/cientos'
|
||||||
import { getColorHexFromRal, type ralTypes } from '../ral';
|
import { getColorHexFromRal, type ralTypes } from '../ral';
|
||||||
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
|
|
||||||
|
|
||||||
const pillar_color = use_pillar_color()
|
const pillar_color = use_pillar_color()
|
||||||
const lamelle_color = use_lamelle_color()
|
const lamelle_color = use_lamelle_color()
|
||||||
const section_count = use_section_count()
|
const section_count = use_section_count()
|
||||||
const lamelle_count = use_lamelles_count()
|
const lamelle_count = use_lamelles_count()
|
||||||
const extra_section = use_extra_section()
|
const extra_section = use_extra_section()
|
||||||
const max_size = use_max_size()
|
|
||||||
|
|
||||||
const { scene, renderer, camera } = useTresContext()
|
const { scene, renderer, camera } = useTresContext()
|
||||||
renderer.value.toneMapping = CineonToneMapping
|
renderer.value.toneMapping = CineonToneMapping
|
||||||
|
@ -29,7 +23,6 @@ renderer.value.shadowMap.enabled = true
|
||||||
renderer.value.shadowMap.type = PCFSoftShadowMap
|
renderer.value.shadowMap.type = PCFSoftShadowMap
|
||||||
|
|
||||||
const { scene: top_model } = await useGLTF('/models_one/verh_100.glb', { draco: true })
|
const { scene: top_model } = await useGLTF('/models_one/verh_100.glb', { draco: true })
|
||||||
// const { scene: fence_model } = await useGLTF('/models_one/fence.glb', { draco: true })
|
|
||||||
const { scene: model_fence_top } = await useGLTF('/fence_one/top.glb')
|
const { scene: model_fence_top } = await useGLTF('/fence_one/top.glb')
|
||||||
const { scene: model_fence_center } = await useGLTF('/fence_one/center.glb')
|
const { scene: model_fence_center } = await useGLTF('/fence_one/center.glb')
|
||||||
const { scene: model_fence_bottom } = await useGLTF('/fence_one/bottom.glb')
|
const { scene: model_fence_bottom } = await useGLTF('/fence_one/bottom.glb')
|
||||||
|
@ -98,7 +91,6 @@ const size = ref(Math.ceil(total.value / 4))
|
||||||
const count = ref((total.value >= 4) ? size.value : total.value)
|
const count = ref((total.value >= 4) ? size.value : total.value)
|
||||||
|
|
||||||
watch(() => [section_count.value, extra_section.value], () => {
|
watch(() => [section_count.value, extra_section.value], () => {
|
||||||
console.log('parametric line clear')
|
|
||||||
total.value = (section_count.value + ~~(!!extra_section.value))
|
total.value = (section_count.value + ~~(!!extra_section.value))
|
||||||
size.value = Math.ceil(total.value / 4);
|
size.value = Math.ceil(total.value / 4);
|
||||||
count.value = (total.value >= 4) ? size.value : total.value;
|
count.value = (total.value >= 4) ? size.value : total.value;
|
||||||
|
|
Loading…
Reference in New Issue