mns-mini-zabor/components/calcValues.vue

214 lines
9.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { getColorNameFromRal } from '@/components/ral'
import type { ralTypes } from '@/components/ral'
const lamelles_count = useState('lamelles_count', () => 8)
const fence_section = useState<number>('fence_section', () => 2000 * 0.001)
const pillar_color = useState<ralTypes>('pillar_color', () => '3009')
const lamelle_color = useState<ralTypes>('lamelle_color', () => '3004')
const section_count = useState('section_count', () => 1)
const extra_section = useState('extra_section', () => 0)
const total_length = useState('total_length', () => 2000 * 0.001 * 2)
const parametric = {
length: {
min: 1000,
max: 2400,
step: 1,
},
total_length: {
min: 1,
max: undefined,
step: 0.1,
},
height: {
min: 675,
max: 2400,
step: 115,
}
}
const form_state = reactive({
length: fence_section.value * 1000,
fence_length: 100,
height: 100 + lamelles_count.value * parametric.height.step,
total_length: fence_section.value * 2,
total_length_mm: fence_section.value * 1000,
full_sections: 1,
extra_section: 0
})
const form_refs = {
length: ref(),
height: ref(),
total_length: ref(),
}
const auto_section_width = ref<boolean>(false)
const changeParametres = () => {
const lamelles = Math.floor(form_state.height / parametric.height.step)
lamelles_count.value = lamelles
fence_section.value = form_state.length * 0.001
for (const key in form_state) {
if (parametric.hasOwnProperty(key)) {
const key_p = key as keyof typeof parametric
const key_s = key as keyof typeof form_state
if (parametric[key_p].max) {
if (form_state[key_s] > parametric[key_p].max) {
form_state[key_s] = parametric[key_p].max
}
}
}
form_state.total_length_mm = form_state.total_length * 1000
if (auto_section_width.value) {
let w = parametric.length.max
while (((form_state.total_length_mm % w) > 0) && w > (parametric.length.min + parametric.length.step * 10)) {
w -= parametric.length.step
}
form_state.length = w
}
if (form_state.total_length_mm < form_state.length) {
form_state.length = form_state.total_length_mm
}
const t_f = (form_state.total_length_mm - form_state.fence_length)
const i_f = (form_state.length - form_state.fence_length)
form_state.full_sections = Math.floor(t_f / i_f)
section_count.value = form_state.full_sections
if (t_f % i_f) {
form_state.extra_section = Math.round(t_f % i_f)
} else {
form_state.extra_section = 0
}
extra_section.value = form_state.extra_section
form_refs.total_length.value.setCustomValidity('')
if (form_state.extra_section && form_state.extra_section < parametric.length.min) {
form_refs.total_length.value.setCustomValidity('Расчет невозможен')
}
setTimeout(() => {
if (form_state.total_length < parametric.total_length.min) {
form_state.total_length = parametric.total_length.min
form_state.length = parametric.length.min
}
}, 300)
total_length.value = form_state.total_length
}
}
const setLamelleColor = (color: ralTypes) => {
lamelle_color.value = color
}
const setPillarColor = (color: ralTypes) => {
pillar_color.value = color
}
const autoSectionWidth = () => {
auto_section_width.value = !auto_section_width.value
}
const predefLamelleColors = ['3009', '9003', '6027', '5024', '9001', '1012', '3007', '4007']
const predefPillarColors = ['3004', '7043', '6028', '5013', '8016', '1020', '3005', '4009']
watch(form_state, changeParametres, { deep: true })
const isModalOpen = useState('modal_open', () => false)
const toggleModal = () => {
isModalOpen.value = !isModalOpen.value
}
const plurals = {
lamelle: { one: 'ламель', few: 'ламели', many: 'ламелей' },
fence: { one: 'cстолб', few: 'столба', many: 'столбов' },
section: { one: 'секция', few: 'секции', many: 'секций' },
}
</script>
<template>
<div class="container py-4">
<ClientOnly fallback-tag="div" fallback="Загрузка 3D модели">
<form class="form">
<div class="form-row">
<div class="form-item w-full">
<label for="length">Длина секции, мм</label>
<input disabled :value="`${form_state.length} мм`" class="w-28" />
<input id="length" type="range" class="w-full" v-bind="parametric.length"
v-model="form_state.length" :disabled="auto_section_width" :ref="form_refs.length" />
<Icon name="mdi:calculator-variant" @click="autoSectionWidth" />
</div>
</div>
<div class="form-row">
<div class="form-item w-full">
<label for="height">Высота забора, мм</label>
<input disabled :value="`${form_state.height} мм`" class="w-28" />
<input id="height" type="range" class="w-full" v-bind="parametric.height"
v-model="form_state.height" :ref="form_refs.height" />
</div>
</div>
<div class="form-row">
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
disabled />
<template v-for="item in predefLamelleColors">
<ColorPicker :color="item" :cb="setLamelleColor" :open="false"
:active="lamelle_color == item" />
</template>
<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 />
<template v-for="item in predefPillarColors">
<ColorPicker :color="item" :cb="setPillarColor" :open="false"
:active="pillar_color == item" />
</template>
<ColorPicker :cb="setPillarColor" />
</div>
</div>
<div class="form-row">
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<input type="number" id="total_length" v-bind="parametric.total_length"
v-model="form_state.total_length" :ref="form_refs.total_length" />
</div>
</div>
<div class="form-row">
<div class="col-span-8 prose">
<p>
Забор общей длиной {{ form_state.total_length }}{{'\xa0'}}м,
{{ section_count }}
<Plural :n="section_count" :forms="plurals.section" /> по
{{ form_state.length }}{{'\xa0'}}мм<span class="contents" v-if="form_state.extra_section">
и 1 дополнительная секция длиной {{ form_state.extra_section }}{{'\xa0'}}мм</span>.
</p>
<p>
Всего {{ section_count + ~~(!!form_state.extra_section) + 1 }}
<Plural :forms="plurals.fence" :n="section_count + ~~(!!form_state.extra_section) + 1" />,
{{ section_count * lamelles_count }}
<Plural :n="section_count * lamelles_count" :forms="plurals.lamelle" />
длиной {{ form_state.length }}{{'\xa0'}}мм
<span class="contents" v-if="form_state.extra_section">
и {{ ~~(!!form_state.extra_section) * lamelles_count }}
<Plural :n="~~(!!form_state.extra_section) * lamelles_count" :forms="plurals.lamelle" /> длиной {{
form_state.extra_section }}{{'\xa0'}}мм</span>.
</p>
<p>
Все элементы окрашиваются порошковым методом: <br />
ламели: {{ getColorNameFromRal(lamelle_color)?.toLowerCase() }};
столбы: {{ getColorNameFromRal(pillar_color)?.toLowerCase() }}.
</p>
</div>
<div class="prose col-span-4">
<p v-if="form_state.extra_section" class="text-ioprim">
Внимание! Дополнительная секция приводит к увеличению стоимости.
Рекомендуем вам изменить длину забора или длину секции!
</p>
</div>
</div>
<div class="form-row justify-center">
<button @click.prevent="toggleModal">Купить прямо сейчас</button>
</div>
</form>
</ClientOnly>
</div>
</template>