mns-mini-zabor/components/calcValues.vue

191 lines
7.6 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">
const lamelles_count = useState('lamelles_count', () => 8)
const fence_section = useState<number>('fence_section', () => 2000 * 0.001)
const pillar_color = useState('pillar_color', () => '#828282')
const lamelle_color = useState('lamelle_color', () => '#C2B078')
const parametric = {
length: {
min: 400,
max: 2400,
step: 50,
},
total_length: {
min: 0.4,
step: 0.05,
},
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,
total_length_mm: fence_section.value * 1000,
full_sections: 1,
extra_section: 0
})
const form_errors = reactive({
length: false,
height: false,
total_length: false,
})
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) && parametric[key].max) {
if (form_state[key] > parametric[key].max) {
form_state[key] = parametric[key].max
}
}
if (parametric.hasOwnProperty(key) && parametric[key].min) {
if (form_state[key] < parametric[key].min) {
form_state[key] = parametric[key].min
}
}
}
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)
if (t_f % i_f) {
form_state.extra_section = Math.round(t_f % i_f)
} else {
form_state.extra_section = 0
}
form_refs.total_length.value.setCustomValidity('')
if (form_state.extra_section && form_state.extra_section < parametric.length.min) {
form_refs.total_length.value.setCustomValidity('Расчет невозможен')
}
}
const setLamelleColor = (color: string) => {
lamelle_color.value = color
}
const setPillarColor = (color: string) => {
pillar_color.value = color
}
const increment = (field: keyof typeof form_state, value: number) => {
if (form_state.hasOwnProperty(field)) {
let v = (form_state[field] + value * parametric[field].step ?? 1)
if (parametric.hasOwnProperty(field)) {
if (v > parametric[field].max) {
v = parametric[field].max
}
if (v < parametric[field].min) {
v = parametric[field].min
}
}
form_state[field] = parseFloat(v.toFixed(2))
}
}
const autoSectionWidth = () => {
auto_section_width.value = !auto_section_width.value
}
const predefLamelleColors = ['#474B4E', '#705335', '#FDF4E3', '#2F4538']
const predefPillarColors = ['#474B4E', '#6A5D4D', '#F4F4F4', '#2F4538']
watch(form_state, changeParametres, { deep: true })
watch(form_state, changeParametres, { deep: true })
const calc_text = computed(() => {
let txt = `Всего секций: ${form_state.full_sections} по ${form_state.length}мм`
if (form_state.extra_section) {
txt += `, 1 по ${form_state.extra_section}мм`
}
return txt
})
const isModalOpen = useState('modal_open', () => false)
const toggleModal = () => {
isModalOpen.value = !isModalOpen.value
}
</script>
<template>
<div class="container py-4">
<form class="form">
<div class="form-row">
<div class="form-item">
<label for="length">Длина секции, мм</label>
<Icon type="button" @click="increment('length', -1)" name="mdi:minus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<input id="length" type="number" v-bind="parametric.length" v-model="form_state.length"
:disabled="auto_section_width" :ref="form_refs.length" />
<Icon type="button" @click="increment('length', 1)" name="mdi:plus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<Icon name="mdi:calculator-variant" @click="autoSectionWidth" />
</div>
<div class="form-item">
<label for="height">Высота забора, мм</label>
<Icon type="button" @click="increment('height', -1)" name="mdi:minus-circle-outline" />
<input id="height" type="number" v-bind="parametric.height" v-model="form_state.height"
:ref="form_refs.height" />
<Icon type="button" @click="increment('height', 1)" name="mdi:plus-circle-outline" />
</div>
</div>
<div class="form-row">
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" v-model="lamelle_color" 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" v-model="pillar_color" 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>
<Icon type="button" @click="increment('total_length', -1)" name="mdi:minus-circle-outline" />
<input type="number" id="total_length" v-bind="parametric.total_length"
v-model="form_state.total_length" :ref="form_refs.total_length" />
<Icon type="button" @click="increment('total_length', 1)" name="mdi:plus-circle-outline" />
</div>
<div class="form-item grow">
<label for="calculation">Приблизительный расчет забора</label>
<textarea id="calculation" disabled class="w-full">{{ calc_text }}</textarea>
</div>
</div>
<div class="form-row justify-center">
<button @click.prevent="toggleModal">Купить прямо сейчас</button>
</div>
</form>
</div>
</template>