Штукатурка стен — расчёт расхода на 1 м²
3–5 замеров стены, расход по маркам (Ротбанд 8.5 кг/м²·10 мм, ЦПС 16 кг), мешки 30 кг, грунт, маяки.
Короткий ответ
Калькулятор считает расход штукатурки с учётом реальной кривизны стены: на основе 3–5 замеров вычисляется средняя толщина слоя и итоговый объём смеси. Поддерживает популярные марки (Ротбанд, ЦПС, Кнауф, Волма) с автоматической подстановкой нормы расхода. Считает число мешков, грунт и маяки.
Что считает
- Средняя толщина слоя — по 3–5 замерам кривизны стены
- Расход смеси — с учётом марки (кг/м² на 10 мм слоя)
- Число мешков — обычно 30 кг
- Грунт — расход в литрах
- Маяки — штуки по длине стены
- Смета — материалы + работы
Источники
- СП 71.13330.2017 «Изоляционные и отделочные покрытия» (допуски по толщине, подготовка основания)
- ГОСТ Р 58279-2018 «Смеси сухие штукатурные» (нормы расхода по маркам)
Калькулятор
Как пользоваться
- Сделайте 3–5 замеров кривизны стены лазерным уровнем или правилом.
- Введите длину и высоту стены в метрах.
- Введите замеренные отклонения (мм) в поля «Замер 1», «Замер 2» и т. д.
- Выберите марку штукатурки — норма расхода подставится автоматически.
- Укажите цену мешка, грунта, маяков.
- Нажмите «Рассчитать» — увидите среднюю толщину, число мешков и смету.
Советы
- Перед замером кривизны очистите стену от старой отделки.
- Замеры делайте в углах, по центру, у пола и потолка.
- Если средняя толщина больше 30 мм — рассмотрите выравнивание гипсокартоном (см. сравнение в калькуляторе).
<!DOCTYPE html>
<html lang="ru">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--
================================================================================
КАЛЬКУЛЯТОР №3. «ШТУКАТУРКА С УЧЁТОМ КРИВИЗНЫ СТЕН» (smetach.ru)
Самодостаточный модуль: ванильный JS, без внешних библиотек и сетевых запросов.
Все CSS-классы с префиксом smc- (безопасное встраивание в WordPress-тему).
Данные и формулы проверены поиском в июле 2026 г.
ИСПОЛЬЗОВАННЫЕ ФОРМУЛЫ И ИСТОЧНИКИ
--------------------------------------------------------------------------------
1. Площадь оштукатуриваемой поверхности:
S = L × H − S_проёмов (либо ручной ввод площади)
Источник: общепринятая методика сметного расчёта (ГЭСН 81-02-15,
площадь отделки стен — за вычетом проёмов).
2. Средняя толщина штукатурного слоя:
d̄ = (d1 + d2 + … + dn) / n — среднее отклонение от плоскости (3–5 точек)
t = d̄ + 6 мм — 6 мм = высота маячкового профиля,
т.е. минимально возможный слой по маякам
Источники: технология оштукатуривания по маякам — профиль 6 мм задаёт
минимальную толщину слоя (inner.su/articles/mayaki-shtukaturnye…, 2025;
aplaster.ru/shtukaturka-sten-po-mayakam, 2026); методика усреднения
отклонений по контрольным точкам — ilmax.by/sovety/…/raskhod-shtukaturki.
СП 71.13330.2017 (Изоляционные и отделочные покрытия) регламентирует
допуски качества, но не нормирует этот расчётный приём — это
общепринятая практическая технология.
3. Масса сухой смеси:
M = S × t × q / 10, кг
где q — расход смеси, кг/м² при слое 10 мм (нормируется производителем):
• Knauf Ротбанд (гипсовая) q = 8,5 — официальные ТХ Кнауф
(knauf… Rotband.pdf: «при слое 10 мм ~ 8,5 кг/м²»)
• Цементная универсальная (ЦПС) q = 17 — отраслевой типовой показатель
1,7 кг/м²/мм (st-par.ru; ilmax 6800: 16–18 кг/м² при 10 мм)
• ВОЛМА-Слой (гипсовая) q = 9 — volmatech.ru (офиц.):
«8–9 кг на 1 кв.м при толщине 10 мм», ГОСТ Р 58279-2018
• Основит Стартвэлл Т-21 (гипс.) q = 10 — паспорт производителя
(расход ~1,0 кг/м²/мм; осн. Т-21 гипсовая)
4. Количество мешков (30 кг): N = ⌈M / 30⌉ — округление вверх.
5. Грунтовка глубокого проникновения:
G = S × 0,2 л/м² × 2 прохода = S × 0,4 л
Источник: типовой расход акриловой грунтовки глубокого проникновения
0,1–0,2 л/м² за проход (тех. листы Knauf-Тифенгрунд, Литокол и др.);
принят верхний безопасный ориентир 0,2 л/м².
6. Маячковые профили 6 мм:
B = ⌈L / 1,0⌉ шт — 1 маяк на метр длины стены (шаг 1 м)
Источник: рекомендуемый шаг маяков 1,0–1,5 м (меньше длины правила),
inner.su (2025), aplaster.ru (2026); принят консервативный шаг 1 м.
Длина профиля — стандартная 3 м.
7. Смета: ИТОГО = N×Цена_мешка + G×Цена_литра + B×Цена_маяка.
Цены — дефолты середины 2026 г., ориентировочные, все редактируемые.
ТЕСТОВЫЕ ВЕКТОРА (вход → ожидаемый выход)
--------------------------------------------------------------------------------
Вектор 1: L=10 м, H=2,7 м, проёмы=0, отклонения [10,20,30], Ротбанд.
S=27 м²; d̄=20 мм; t=26 мм; M=27×26×8,5/10=596,7 кг; N=⌈596,7/30⌉=20 мешков;
G=10,8 л; B=10 шт; смета при дефолтах: 20×680+10,8×65+10×75 = 15 052 ₽.
Вектор 2: ручной ввод S=20 м², L=8 м, отклонения [5,15,25,35,45], Цементная.
d̄=25 мм; t=31 мм; M=20×31×17/10=1 054 кг; N=⌈1054/30⌉=36 мешков;
G=8 л; B=8 шт; смета: 36×520+8×65+8×75 = 19 840 ₽.
Вектор 3: L=5 м, H=2,5 м, проёмы=2 м², отклонения [0,0,0], Волма-Слой.
S=10,5 м²; d̄=0 мм; t=6 мм; M=10,5×6×9/10=56,7 кг; N=⌈56,7/30⌉=2 мешка;
G=4,2 л; B=5 шт; смета: 2×620+4,2×65+5×75 = 1 888 ₽.
Вектор 4 (граничный): L=12 м, H=3 м, проёмы=3,5, отклонения [40,50,60,70],
Стартвэлл.
S=32,5 м²; d̄=55 мм; t=61 мм; M=32,5×61×10/10=1 982,5 кг; N=67 мешков;
G=13 л; B=12 шт; смета: 67×580+13×65+12×75 = 40 605 ₽.
================================================================================
-->
<style>
.smc-calc {
--smc-accent: #b0603a;
--smc-accent-hover: #95502f;
--smc-bg: #faf8f5;
--smc-panel: #ffffff;
--smc-border: #e3ddd4;
--smc-text: #2f2b26;
--smc-muted: #7a7268;
--smc-error: #b23b3b;
--smc-ok: #3e7a4e;
--smc-radius: 10px;
box-sizing: border-box;
max-width: 780px;
margin: 0 auto;
padding: 24px 20px;
background: var(--smc-bg);
border: 1px solid var(--smc-border);
border-radius: var(--smc-radius);
font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
font-size: 15px;
line-height: 1.5;
color: var(--smc-text);
}
.smc-calc *, .smc-calc *::before, .smc-calc *::after { box-sizing: border-box; }
.smc-calc h2.smc-title {
margin: 0 0 6px;
font-size: 22px;
line-height: 1.3;
color: var(--smc-text);
}
.smc-subtitle { margin: 0 0 18px; font-size: 13px; color: var(--smc-muted); }
.smc-fieldset {
margin: 0 0 16px;
padding: 14px 14px 6px;
background: var(--smc-panel);
border: 1px solid var(--smc-border);
border-radius: var(--smc-radius);
}
.smc-fieldset legend {
padding: 0 8px;
font-size: 13px;
font-weight: 600;
color: var(--smc-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.smc-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 12px;
}
.smc-field { margin-bottom: 12px; }
.smc-field label {
display: block;
margin-bottom: 4px;
font-size: 13px;
font-weight: 600;
}
.smc-field label .smc-unit { font-weight: 400; color: var(--smc-muted); }
.smc-hint { display: block; margin-top: 3px; font-size: 12px; color: var(--smc-muted); }
.smc-input, .smc-select {
width: 100%;
padding: 9px 10px;
border: 1px solid var(--smc-border);
border-radius: 7px;
background: #fff;
color: var(--smc-text);
font-size: 15px;
font-family: inherit;
}
.smc-input:focus, .smc-select:focus {
outline: 2px solid var(--smc-accent);
outline-offset: 0;
border-color: var(--smc-accent);
}
.smc-input.smc-invalid { border-color: var(--smc-error); }
.smc-deviations {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
gap: 10px;
}
.smc-radio-row { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 12px; }
.smc-radio-row label { display: flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.smc-btn {
display: inline-block;
width: 100%;
padding: 13px 20px;
border: 0;
border-radius: 8px;
background: var(--smc-accent);
color: #fff;
font-size: 16px;
font-weight: 700;
font-family: inherit;
cursor: pointer;
transition: background 0.15s ease;
}
.smc-btn:hover { background: var(--smc-accent-hover); }
.smc-btn-secondary {
background: transparent;
color: var(--smc-accent);
border: 1px solid var(--smc-accent);
font-size: 14px;
font-weight: 600;
padding: 10px 16px;
}
.smc-btn-secondary:hover { background: rgba(176, 96, 58, 0.08); }
.smc-error-box {
display: none;
margin: 0 0 14px;
padding: 10px 14px;
border: 1px solid var(--smc-error);
border-radius: 8px;
background: #fdf3f2;
color: var(--smc-error);
font-size: 14px;
}
.smc-error-box.smc-visible { display: block; }
.smc-results { display: none; margin-top: 20px; }
.smc-results.smc-visible { display: block; }
.smc-table-wrap { overflow-x: auto; margin-bottom: 16px; }
.smc-table {
width: 100%;
border-collapse: collapse;
background: var(--smc-panel);
font-size: 14px;
}
.smc-table th, .smc-table td {
padding: 9px 10px;
border: 1px solid var(--smc-border);
text-align: left;
vertical-align: middle;
}
.smc-table th {
background: #f2ede6;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--smc-muted);
}
.smc-table td.smc-num { text-align: right; white-space: nowrap; }
.smc-table tfoot td { font-weight: 700; background: #f2ede6; }
.smc-table .smc-price-input { width: 100px; padding: 6px 8px; font-size: 14px; }
.smc-total-row td { font-size: 16px; }
.smc-copy-status { margin-top: 8px; font-size: 13px; color: var(--smc-ok); min-height: 18px; }
.smc-disclaimer {
margin-top: 16px;
padding: 10px 14px;
border-left: 3px solid var(--smc-accent);
background: #f5f1ea;
font-size: 12.5px;
color: var(--smc-muted);
}
@media (max-width: 560px) {
.smc-calc { padding: 16px 12px; }
.smc-calc h2.smc-title { font-size: 19px; }
.smc-table { font-size: 13px; }
.smc-table .smc-price-input { width: 84px; }
}
</style>
<body>
<div class="smc-calc" id="smc-plaster-calc">
<h2 class="smc-title">Калькулятор штукатурки с учётом кривизны стен</h2>
<p class="smc-subtitle">Расчёт толщины слоя по отклонениям стены, расхода смеси, грунтовки, маяков и ориентировочной сметы.</p>
<form id="smc-form" novalidate>
<fieldset class="smc-fieldset">
<legend>Геометрия стен</legend>
<div class="smc-radio-row">
<label><input type="radio" name="smc-area-mode" value="auto" checked> По размерам стен</label>
<label><input type="radio" name="smc-area-mode" value="manual"> Задать площадь вручную</label>
</div>
<div class="smc-grid">
<div class="smc-field" id="smc-wrap-length">
<label for="smc-length">Суммарная длина стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-length" min="0.5" max="200" step="0.1" value="10" inputmode="decimal">
<span class="smc-hint">Периметр всех штукатуримых стен</span>
</div>
<div class="smc-field" id="smc-wrap-height">
<label for="smc-height">Высота стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-height" min="1" max="6" step="0.05" value="2.7" inputmode="decimal">
</div>
<div class="smc-field" id="smc-wrap-openings">
<label for="smc-openings">Площадь проёмов <span class="smc-unit">(м²)</span></label>
<input class="smc-input" type="number" id="smc-openings" min="0" max="500" step="0.1" value="0" inputmode="decimal">
<span class="smc-hint">Окна и двери — вычитаются из площади</span>
</div>
<div class="smc-field" id="smc-wrap-area" style="display:none;">
<label for="smc-area">Площадь под штукатурку <span class="smc-unit">(м²)</span></label>
<input class="smc-input" type="number" id="smc-area" min="1" max="1000" step="0.1" value="20" inputmode="decimal">
</div>
</div>
<div class="smc-field" id="smc-wrap-length2" style="display:none;">
<label for="smc-length2">Суммарная длина стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-length2" min="0.5" max="200" step="0.1" value="8" inputmode="decimal">
<span class="smc-hint">Нужна только для подсчёта маяков (шаг 1 м)</span>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Кривизна стены</legend>
<p class="smc-hint" style="margin:0 0 10px;">Измерьте отклонение стены от вертикальной плоскости (правилом/уровнем) в 3–5 точках и впишите значения. Минимум 3 точки.</p>
<div class="smc-deviations">
<div class="smc-field">
<label for="smc-dev1">Точка 1 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev1" min="0" max="100" step="1" value="10" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev2">Точка 2 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev2" min="0" max="100" step="1" value="20" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev3">Точка 3 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev3" min="0" max="100" step="1" value="30" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev4">Точка 4 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev4" min="0" max="100" step="1" placeholder="—" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev5">Точка 5 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev5" min="0" max="100" step="1" placeholder="—" inputmode="decimal">
</div>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Штукатурная смесь</legend>
<div class="smc-grid">
<div class="smc-field">
<label for="smc-mix">Смесь</label>
<select class="smc-select" id="smc-mix">
<option value="rotband" selected>Knauf Ротбанд (гипсовая) — 8,5 кг/м² на 10 мм</option>
<option value="cement">Цементная универсальная (ЦПС) — 17 кг/м² на 10 мм</option>
<option value="volma">ВОЛМА-Слой (гипсовая) — 9 кг/м² на 10 мм</option>
<option value="startwell">Основит Стартвэлл Т-21 (гипсовая) — 10 кг/м² на 10 мм</option>
</select>
<span class="smc-hint">Расход указан производителем для слоя 10 мм</span>
</div>
</div>
</fieldset>
<div class="smc-error-box" id="smc-errors" role="alert"></div>
<button type="submit" class="smc-btn">Рассчитать</button>
</form>
<div class="smc-results" id="smc-results" aria-live="polite">
<fieldset class="smc-fieldset">
<legend>Результаты расчёта</legend>
<div class="smc-table-wrap">
<table class="smc-table">
<tbody id="smc-calc-rows"></tbody>
</table>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Смета на материалы</legend>
<div class="smc-table-wrap">
<table class="smc-table">
<thead>
<tr>
<th>Материал</th>
<th>Кол-во</th>
<th>Цена, ₽ *</th>
<th>Сумма, ₽</th>
</tr>
</thead>
<tbody id="smc-estimate-rows"></tbody>
<tfoot>
<tr class="smc-total-row">
<td colspan="3">Итого по смете</td>
<td class="smc-num" id="smc-total">—</td>
</tr>
</tfoot>
</table>
</div>
<span class="smc-hint">* Цены ориентировочные (середина 2026 г.), редактируйте под свой регион и магазин — смета пересчитается автоматически.</span>
</fieldset>
<button type="button" class="smc-btn smc-btn-secondary" id="smc-copy">Скопировать смету</button>
<div class="smc-copy-status" id="smc-copy-status"></div>
<div class="smc-disclaimer">
Расчёт ориентировочный, не является офертой. Фактический расход зависит от основания, технологии нанесения и квалификации мастера; рекомендуется запас материала 5–10 %. Перед закупкой сверьтесь с паспортом выбранной смеси.
</div>
</div>
</div>
<script>
(function () {
'use strict';
/* База смесей: q — расход кг/м² при слое 10 мм (по данным производителей),
bagKg — вес мешка, price — ориентировочная цена мешка на середину 2026 г. */
var MIXES = {
rotband: { name: 'Knauf Ротбанд (гипсовая)', q: 8.5, bagKg: 30, price: 680 },
cement: { name: 'Цементная универсальная (ЦПС)', q: 17, bagKg: 30, price: 520 },
volma: { name: 'ВОЛМА-Слой (гипсовая)', q: 9, bagKg: 30, price: 620 },
startwell: { name: 'Основит Стартвэлл Т-21 (гипс.)', q: 10, bagKg: 30, price: 580 }
};
/* Нормы по сопутствующим материалам */
var PRIMER_PER_M2 = 0.2; /* л/м² за один проход */
var PRIMER_PASSES = 2; /* число проходов */
var BEACON_STEP = 1; /* м — шаг маячковых профилей */
var MIN_LAYER = 6; /* мм — минимальный слой по маяку 6 мм */
/* Ориентировочные цены по умолчанию (середина 2026 г.) */
var PRIMER_PRICE = 65; /* ₽/л грунтовки глубокого проникновения */
var BEACON_PRICE = 75; /* ₽/шт маяк 6 мм, 3 м */
var $ = function (id) { return document.getElementById(id); };
var form = $('smc-form');
var errorsBox = $('smc-errors');
var resultsBox = $('smc-results');
var state = null; /* последний успешный расчёт */
/* ---------- Переключение способа задания площади ---------- */
var modeRadios = form.querySelectorAll('input[name="smc-area-mode"]');
function syncAreaMode() {
var manual = form.querySelector('input[name="smc-area-mode"]:checked').value === 'manual';
$('smc-wrap-height').style.display = manual ? 'none' : '';
$('smc-wrap-openings').style.display = manual ? 'none' : '';
$('smc-wrap-area').style.display = manual ? '' : 'none';
$('smc-wrap-length').style.display = manual ? 'none' : '';
$('smc-wrap-length2').style.display = manual ? '' : 'none';
}
for (var r = 0; r < modeRadios.length; r++) {
modeRadios[r].addEventListener('change', syncAreaMode);
}
/* ---------- Утилиты ---------- */
function num(id) {
var el = $(id);
var v = parseFloat(String(el.value).replace(',', '.'));
return isNaN(v) ? null : v;
}
function markInvalid(id) { $(id).classList.add('smc-invalid'); }
function clearInvalid() {
var els = form.querySelectorAll('.smc-invalid');
for (var i = 0; i < els.length; i++) els[i].classList.remove('smc-invalid');
}
function fmtNum(v, digits) {
return v.toLocaleString('ru-RU', { minimumFractionDigits: digits, maximumFractionDigits: digits });
}
function fmtMoney(v) {
return v.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 }) + ' ₽';
}
/* ---------- Валидация ---------- */
function validate(manual) {
var errors = [];
clearInvalid();
var L, H, openings, area;
if (manual) {
area = num('smc-area');
if (area === null || area < 1 || area > 1000) {
errors.push('Укажите площадь под штукатурку — от 1 до 1000 м².');
markInvalid('smc-area');
}
L = num('smc-length2');
if (L === null || L < 0.5 || L > 200) {
errors.push('Укажите суммарную длину стен для расчёта маяков — от 0,5 до 200 м.');
markInvalid('smc-length2');
}
} else {
L = num('smc-length');
if (L === null || L < 0.5 || L > 200) {
errors.push('Укажите суммарную длину стен — от 0,5 до 200 м.');
markInvalid('smc-length');
}
H = num('smc-height');
if (H === null || H < 1 || H > 6) {
errors.push('Укажите высоту стен — от 1 до 6 м.');
markInvalid('smc-height');
}
openings = num('smc-openings');
if (openings === null || openings < 0 || openings > 500) {
errors.push('Площадь проёмов должна быть от 0 до 500 м².');
markInvalid('smc-openings');
}
if (L !== null && H !== null && openings !== null && L * H - openings < 1) {
errors.push('Площадь за вычетом проёмов получилась меньше 1 м² — проверьте размеры.');
markInvalid('smc-openings');
}
}
var devs = [];
var filled = 0;
for (var i = 1; i <= 5; i++) {
var id = 'smc-dev' + i;
var raw = $(id).value.trim();
if (raw === '') continue;
var v = parseFloat(raw.replace(',', '.'));
if (isNaN(v) || v < 0 || v > 100) {
errors.push('Отклонение в точке ' + i + ' должно быть числом от 0 до 100 мм.');
markInvalid(id);
} else {
devs.push(v);
filled++;
}
}
if (filled < 3) {
errors.push('Заполните отклонения минимум в 3 точках — иначе средняя толщина будет неточной.');
}
if (errors.length) {
errorsBox.innerHTML = errors.join('<br>');
errorsBox.classList.add('smc-visible');
return null;
}
errorsBox.classList.remove('smc-visible');
errorsBox.innerHTML = '';
return {
L: L,
area: manual ? area : (L * H - openings),
devs: devs
};
}
/* ---------- Расчёт ---------- */
function calculate(data) {
var mix = MIXES[$('smc-mix').value];
var avgDev = data.devs.reduce(function (a, b) { return a + b; }, 0) / data.devs.length;
var thickness = avgDev + MIN_LAYER; /* мм */
var kg = data.area * thickness * mix.q / 10; /* кг */
var bags = Math.ceil(kg / mix.bagKg); /* шт, вверх */
var primer = data.area * PRIMER_PER_M2 * PRIMER_PASSES; /* л */
var beacons = Math.ceil(data.L / BEACON_STEP); /* шт */
return {
mix: mix,
area: data.area,
avgDev: avgDev,
thickness: thickness,
kg: kg,
bags: bags,
primer: primer,
beacons: beacons
};
}
/* ---------- Отрисовка результатов ---------- */
function render(res) {
var rows = [
['Площадь под штукатурку', fmtNum(res.area, 1) + ' м²'],
['Среднее отклонение стены', fmtNum(res.avgDev, 1) + ' мм'],
['Средняя толщина слоя (отклонение + ' + MIN_LAYER + ' мм по маякам)', fmtNum(res.thickness, 1) + ' мм'],
['Смесь', res.mix.name + ' (расход ' + fmtNum(res.mix.q, 1) + ' кг/м² на 10 мм)'],
['Потребность в смеси', fmtNum(res.kg, 1) + ' кг'],
['Мешков по ' + res.mix.bagKg + ' кг', res.bags.toLocaleString('ru-RU') + ' шт'],
['Грунтовка (' + fmtNum(PRIMER_PER_M2, 1) + ' л/м² × ' + PRIMER_PASSES + ' прохода)', fmtNum(res.primer, 1) + ' л'],
['Маячковые профили 6 мм, 3 м (шаг ' + BEACON_STEP + ' м)', res.beacons.toLocaleString('ru-RU') + ' шт']
];
var html = '';
for (var i = 0; i < rows.length; i++) {
html += '<tr><th scope="row">' + rows[i][0] + '</th><td class="smc-num">' + rows[i][1] + '</td></tr>';
}
$('smc-calc-rows').innerHTML = html;
var est = $('smc-estimate-rows');
est.innerHTML =
'<tr>' +
'<td>Штукатурная смесь, мешки ' + res.mix.bagKg + ' кг</td>' +
'<td class="smc-num">' + res.bags.toLocaleString('ru-RU') + ' шт</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-mix" min="0" max="100000" step="10" value="' + res.mix.price + '"></td>' +
'<td class="smc-num" id="smc-sum-mix">—</td>' +
'</tr>' +
'<tr>' +
'<td>Грунтовка глубокого проникновения</td>' +
'<td class="smc-num">' + fmtNum(res.primer, 1) + ' л</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-primer" min="0" max="10000" step="5" value="' + PRIMER_PRICE + '"></td>' +
'<td class="smc-num" id="smc-sum-primer">—</td>' +
'</tr>' +
'<tr>' +
'<td>Профиль маячковый 6 мм, 3 м</td>' +
'<td class="smc-num">' + res.beacons.toLocaleString('ru-RU') + ' шт</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-beacon" min="0" max="10000" step="5" value="' + BEACON_PRICE + '"></td>' +
'<td class="smc-num" id="smc-sum-beacon">—</td>' +
'</tr>';
['smc-price-mix', 'smc-price-primer', 'smc-price-beacon'].forEach(function (id) {
$(id).addEventListener('input', updateTotals);
});
updateTotals();
}
function priceOf(id) {
var v = parseFloat(String($(id).value).replace(',', '.'));
if (isNaN(v) || v < 0) return 0;
return v;
}
function updateTotals() {
if (!state) return;
var pMix = priceOf('smc-price-mix');
var pPrimer = priceOf('smc-price-primer');
var pBeacon = priceOf('smc-price-beacon');
var sumMix = state.bags * pMix;
var sumPrimer = state.primer * pPrimer;
var sumBeacon = state.beacons * pBeacon;
var total = sumMix + sumPrimer + sumBeacon;
$('smc-sum-mix').textContent = fmtMoney(sumMix);
$('smc-sum-primer').textContent = fmtMoney(sumPrimer);
$('smc-sum-beacon').textContent = fmtMoney(sumBeacon);
$('smc-total').textContent = fmtMoney(total);
}
/* ---------- Копирование сметы ---------- */
function buildEstimateText() {
if (!state) return '';
var pMix = priceOf('smc-price-mix');
var pPrimer = priceOf('smc-price-primer');
var pBeacon = priceOf('smc-price-beacon');
var total = state.bags * pMix + state.primer * pPrimer + state.beacons * pBeacon;
return [
'Смета: штукатурка стен (расчёт с сайта «Сметач», ориентировочно)',
'Площадь: ' + fmtNum(state.area, 1) + ' м²',
'Средняя толщина слоя: ' + fmtNum(state.thickness, 1) + ' мм (среднее отклонение ' + fmtNum(state.avgDev, 1) + ' мм + 6 мм минимальный слой по маякам)',
'',
'1. ' + state.mix.name + ': ' + fmtNum(state.kg, 1) + ' кг → ' + state.bags.toLocaleString('ru-RU') + ' мешк. × ' + fmtMoney(pMix) + ' = ' + fmtMoney(state.bags * pMix),
'2. Грунтовка: ' + fmtNum(state.primer, 1) + ' л × ' + fmtMoney(pPrimer) + ' = ' + fmtMoney(state.primer * pPrimer),
'3. Маяки 6 мм (3 м): ' + state.beacons.toLocaleString('ru-RU') + ' шт × ' + fmtMoney(pBeacon) + ' = ' + fmtMoney(state.beacons * pBeacon),
'',
'ИТОГО: ' + fmtMoney(total),
'Расчёт ориентировочный, не является офертой. Рекомендуется запас 5–10 %.'
].join('\n');
}
$('smc-copy').addEventListener('click', function () {
var text = buildEstimateText();
var status = $('smc-copy-status');
function done(msg) {
status.textContent = msg;
setTimeout(function () { status.textContent = ''; }, 4000);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
done('Смета скопирована в буфер обмена.');
}, function () {
fallbackCopy(text, done);
});
} else {
fallbackCopy(text, done);
}
});
function fallbackCopy(text, done) {
var ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
try {
document.execCommand('copy');
done('Смета скопирована в буфер обмена.');
} catch (e) {
done('Не удалось скопировать автоматически — выделите текст сметы вручную.');
}
document.body.removeChild(ta);
}
/* ---------- Отправка формы ---------- */
form.addEventListener('submit', function (e) {
e.preventDefault();
var manual = form.querySelector('input[name="smc-area-mode"]:checked').value === 'manual';
var data = validate(manual);
if (!data) {
resultsBox.classList.remove('smc-visible');
return;
}
state = calculate(data);
render(state);
resultsBox.classList.add('smc-visible');
resultsBox.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
syncAreaMode();
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Калькулятор штукатурки с учётом кривизны стен — Сметач</title>
<!--
================================================================================
КАЛЬКУЛЯТОР №3. «ШТУКАТУРКА С УЧЁТОМ КРИВИЗНЫ СТЕН» (smetach.ru)
Самодостаточный модуль: ванильный JS, без внешних библиотек и сетевых запросов.
Все CSS-классы с префиксом smc- (безопасное встраивание в WordPress-тему).
Данные и формулы проверены поиском в июле 2026 г.
ИСПОЛЬЗОВАННЫЕ ФОРМУЛЫ И ИСТОЧНИКИ
--------------------------------------------------------------------------------
1. Площадь оштукатуриваемой поверхности:
S = L × H − S_проёмов (либо ручной ввод площади)
Источник: общепринятая методика сметного расчёта (ГЭСН 81-02-15,
площадь отделки стен — за вычетом проёмов).
2. Средняя толщина штукатурного слоя:
d̄ = (d1 + d2 + … + dn) / n — среднее отклонение от плоскости (3–5 точек)
t = d̄ + 6 мм — 6 мм = высота маячкового профиля,
т.е. минимально возможный слой по маякам
Источники: технология оштукатуривания по маякам — профиль 6 мм задаёт
минимальную толщину слоя (inner.su/articles/mayaki-shtukaturnye…, 2025;
aplaster.ru/shtukaturka-sten-po-mayakam, 2026); методика усреднения
отклонений по контрольным точкам — ilmax.by/sovety/…/raskhod-shtukaturki.
СП 71.13330.2017 (Изоляционные и отделочные покрытия) регламентирует
допуски качества, но не нормирует этот расчётный приём — это
общепринятая практическая технология.
3. Масса сухой смеси:
M = S × t × q / 10, кг
где q — расход смеси, кг/м² при слое 10 мм (нормируется производителем):
• Knauf Ротбанд (гипсовая) q = 8,5 — официальные ТХ Кнауф
(knauf… Rotband.pdf: «при слое 10 мм ~ 8,5 кг/м²»)
• Цементная универсальная (ЦПС) q = 17 — отраслевой типовой показатель
1,7 кг/м²/мм (st-par.ru; ilmax 6800: 16–18 кг/м² при 10 мм)
• ВОЛМА-Слой (гипсовая) q = 9 — volmatech.ru (офиц.):
«8–9 кг на 1 кв.м при толщине 10 мм», ГОСТ Р 58279-2018
• Основит Стартвэлл Т-21 (гипс.) q = 10 — паспорт производителя
(расход ~1,0 кг/м²/мм; осн. Т-21 гипсовая)
4. Количество мешков (30 кг): N = ⌈M / 30⌉ — округление вверх.
5. Грунтовка глубокого проникновения:
G = S × 0,2 л/м² × 2 прохода = S × 0,4 л
Источник: типовой расход акриловой грунтовки глубокого проникновения
0,1–0,2 л/м² за проход (тех. листы Knauf-Тифенгрунд, Литокол и др.);
принят верхний безопасный ориентир 0,2 л/м².
6. Маячковые профили 6 мм:
B = ⌈L / 1,0⌉ шт — 1 маяк на метр длины стены (шаг 1 м)
Источник: рекомендуемый шаг маяков 1,0–1,5 м (меньше длины правила),
inner.su (2025), aplaster.ru (2026); принят консервативный шаг 1 м.
Длина профиля — стандартная 3 м.
7. Смета: ИТОГО = N×Цена_мешка + G×Цена_литра + B×Цена_маяка.
Цены — дефолты середины 2026 г., ориентировочные, все редактируемые.
ТЕСТОВЫЕ ВЕКТОРА (вход → ожидаемый выход)
--------------------------------------------------------------------------------
Вектор 1: L=10 м, H=2,7 м, проёмы=0, отклонения [10,20,30], Ротбанд.
S=27 м²; d̄=20 мм; t=26 мм; M=27×26×8,5/10=596,7 кг; N=⌈596,7/30⌉=20 мешков;
G=10,8 л; B=10 шт; смета при дефолтах: 20×680+10,8×65+10×75 = 15 052 ₽.
Вектор 2: ручной ввод S=20 м², L=8 м, отклонения [5,15,25,35,45], Цементная.
d̄=25 мм; t=31 мм; M=20×31×17/10=1 054 кг; N=⌈1054/30⌉=36 мешков;
G=8 л; B=8 шт; смета: 36×520+8×65+8×75 = 19 840 ₽.
Вектор 3: L=5 м, H=2,5 м, проёмы=2 м², отклонения [0,0,0], Волма-Слой.
S=10,5 м²; d̄=0 мм; t=6 мм; M=10,5×6×9/10=56,7 кг; N=⌈56,7/30⌉=2 мешка;
G=4,2 л; B=5 шт; смета: 2×620+4,2×65+5×75 = 1 888 ₽.
Вектор 4 (граничный): L=12 м, H=3 м, проёмы=3,5, отклонения [40,50,60,70],
Стартвэлл.
S=32,5 м²; d̄=55 мм; t=61 мм; M=32,5×61×10/10=1 982,5 кг; N=67 мешков;
G=13 л; B=12 шт; смета: 67×580+13×65+12×75 = 40 605 ₽.
================================================================================
-->
<style>
.smc-calc {
--smc-accent: #b0603a;
--smc-accent-hover: #95502f;
--smc-bg: #faf8f5;
--smc-panel: #ffffff;
--smc-border: #e3ddd4;
--smc-text: #2f2b26;
--smc-muted: #7a7268;
--smc-error: #b23b3b;
--smc-ok: #3e7a4e;
--smc-radius: 10px;
box-sizing: border-box;
max-width: 780px;
margin: 0 auto;
padding: 24px 20px;
background: var(--smc-bg);
border: 1px solid var(--smc-border);
border-radius: var(--smc-radius);
font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
font-size: 15px;
line-height: 1.5;
color: var(--smc-text);
}
.smc-calc *, .smc-calc *::before, .smc-calc *::after { box-sizing: border-box; }
.smc-calc h2.smc-title {
margin: 0 0 6px;
font-size: 22px;
line-height: 1.3;
color: var(--smc-text);
}
.smc-subtitle { margin: 0 0 18px; font-size: 13px; color: var(--smc-muted); }
.smc-fieldset {
margin: 0 0 16px;
padding: 14px 14px 6px;
background: var(--smc-panel);
border: 1px solid var(--smc-border);
border-radius: var(--smc-radius);
}
.smc-fieldset legend {
padding: 0 8px;
font-size: 13px;
font-weight: 600;
color: var(--smc-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.smc-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 12px;
}
.smc-field { margin-bottom: 12px; }
.smc-field label {
display: block;
margin-bottom: 4px;
font-size: 13px;
font-weight: 600;
}
.smc-field label .smc-unit { font-weight: 400; color: var(--smc-muted); }
.smc-hint { display: block; margin-top: 3px; font-size: 12px; color: var(--smc-muted); }
.smc-input, .smc-select {
width: 100%;
padding: 9px 10px;
border: 1px solid var(--smc-border);
border-radius: 7px;
background: #fff;
color: var(--smc-text);
font-size: 15px;
font-family: inherit;
}
.smc-input:focus, .smc-select:focus {
outline: 2px solid var(--smc-accent);
outline-offset: 0;
border-color: var(--smc-accent);
}
.smc-input.smc-invalid { border-color: var(--smc-error); }
.smc-deviations {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
gap: 10px;
}
.smc-radio-row { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 12px; }
.smc-radio-row label { display: flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.smc-btn {
display: inline-block;
width: 100%;
padding: 13px 20px;
border: 0;
border-radius: 8px;
background: var(--smc-accent);
color: #fff;
font-size: 16px;
font-weight: 700;
font-family: inherit;
cursor: pointer;
transition: background 0.15s ease;
}
.smc-btn:hover { background: var(--smc-accent-hover); }
.smc-btn-secondary {
background: transparent;
color: var(--smc-accent);
border: 1px solid var(--smc-accent);
font-size: 14px;
font-weight: 600;
padding: 10px 16px;
}
.smc-btn-secondary:hover { background: rgba(176, 96, 58, 0.08); }
.smc-error-box {
display: none;
margin: 0 0 14px;
padding: 10px 14px;
border: 1px solid var(--smc-error);
border-radius: 8px;
background: #fdf3f2;
color: var(--smc-error);
font-size: 14px;
}
.smc-error-box.smc-visible { display: block; }
.smc-results { display: none; margin-top: 20px; }
.smc-results.smc-visible { display: block; }
.smc-table-wrap { overflow-x: auto; margin-bottom: 16px; }
.smc-table {
width: 100%;
border-collapse: collapse;
background: var(--smc-panel);
font-size: 14px;
}
.smc-table th, .smc-table td {
padding: 9px 10px;
border: 1px solid var(--smc-border);
text-align: left;
vertical-align: middle;
}
.smc-table th {
background: #f2ede6;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--smc-muted);
}
.smc-table td.smc-num { text-align: right; white-space: nowrap; }
.smc-table tfoot td { font-weight: 700; background: #f2ede6; }
.smc-table .smc-price-input { width: 100px; padding: 6px 8px; font-size: 14px; }
.smc-total-row td { font-size: 16px; }
.smc-copy-status { margin-top: 8px; font-size: 13px; color: var(--smc-ok); min-height: 18px; }
.smc-disclaimer {
margin-top: 16px;
padding: 10px 14px;
border-left: 3px solid var(--smc-accent);
background: #f5f1ea;
font-size: 12.5px;
color: var(--smc-muted);
}
@media (max-width: 560px) {
.smc-calc { padding: 16px 12px; }
.smc-calc h2.smc-title { font-size: 19px; }
.smc-table { font-size: 13px; }
.smc-table .smc-price-input { width: 84px; }
}
</style>
</head>
<div class="smc-calc" id="smc-plaster-calc">
<h2 class="smc-title">Калькулятор штукатурки с учётом кривизны стен</h2>
<p class="smc-subtitle">Расчёт толщины слоя по отклонениям стены, расхода смеси, грунтовки, маяков и ориентировочной сметы.</p>
<form id="smc-form" novalidate>
<fieldset class="smc-fieldset">
<legend>Геометрия стен</legend>
<div class="smc-radio-row">
<label><input type="radio" name="smc-area-mode" value="auto" checked> По размерам стен</label>
<label><input type="radio" name="smc-area-mode" value="manual"> Задать площадь вручную</label>
</div>
<div class="smc-grid">
<div class="smc-field" id="smc-wrap-length">
<label for="smc-length">Суммарная длина стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-length" min="0.5" max="200" step="0.1" value="10" inputmode="decimal">
<span class="smc-hint">Периметр всех штукатуримых стен</span>
</div>
<div class="smc-field" id="smc-wrap-height">
<label for="smc-height">Высота стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-height" min="1" max="6" step="0.05" value="2.7" inputmode="decimal">
</div>
<div class="smc-field" id="smc-wrap-openings">
<label for="smc-openings">Площадь проёмов <span class="smc-unit">(м²)</span></label>
<input class="smc-input" type="number" id="smc-openings" min="0" max="500" step="0.1" value="0" inputmode="decimal">
<span class="smc-hint">Окна и двери — вычитаются из площади</span>
</div>
<div class="smc-field" id="smc-wrap-area" style="display:none;">
<label for="smc-area">Площадь под штукатурку <span class="smc-unit">(м²)</span></label>
<input class="smc-input" type="number" id="smc-area" min="1" max="1000" step="0.1" value="20" inputmode="decimal">
</div>
</div>
<div class="smc-field" id="smc-wrap-length2" style="display:none;">
<label for="smc-length2">Суммарная длина стен <span class="smc-unit">(м)</span></label>
<input class="smc-input" type="number" id="smc-length2" min="0.5" max="200" step="0.1" value="8" inputmode="decimal">
<span class="smc-hint">Нужна только для подсчёта маяков (шаг 1 м)</span>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Кривизна стены</legend>
<p class="smc-hint" style="margin:0 0 10px;">Измерьте отклонение стены от вертикальной плоскости (правилом/уровнем) в 3–5 точках и впишите значения. Минимум 3 точки.</p>
<div class="smc-deviations">
<div class="smc-field">
<label for="smc-dev1">Точка 1 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev1" min="0" max="100" step="1" value="10" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev2">Точка 2 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev2" min="0" max="100" step="1" value="20" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev3">Точка 3 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev3" min="0" max="100" step="1" value="30" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev4">Точка 4 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev4" min="0" max="100" step="1" placeholder="—" inputmode="decimal">
</div>
<div class="smc-field">
<label for="smc-dev5">Точка 5 <span class="smc-unit">(мм)</span></label>
<input class="smc-input smc-dev" type="number" id="smc-dev5" min="0" max="100" step="1" placeholder="—" inputmode="decimal">
</div>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Штукатурная смесь</legend>
<div class="smc-grid">
<div class="smc-field">
<label for="smc-mix">Смесь</label>
<select class="smc-select" id="smc-mix">
<option value="rotband" selected>Knauf Ротбанд (гипсовая) — 8,5 кг/м² на 10 мм</option>
<option value="cement">Цементная универсальная (ЦПС) — 17 кг/м² на 10 мм</option>
<option value="volma">ВОЛМА-Слой (гипсовая) — 9 кг/м² на 10 мм</option>
<option value="startwell">Основит Стартвэлл Т-21 (гипсовая) — 10 кг/м² на 10 мм</option>
</select>
<span class="smc-hint">Расход указан производителем для слоя 10 мм</span>
</div>
</div>
</fieldset>
<div class="smc-error-box" id="smc-errors" role="alert"></div>
<button type="submit" class="smc-btn">Рассчитать</button>
</form>
<div class="smc-results" id="smc-results" aria-live="polite">
<fieldset class="smc-fieldset">
<legend>Результаты расчёта</legend>
<div class="smc-table-wrap">
<table class="smc-table">
<tbody id="smc-calc-rows"></tbody>
</table>
</div>
</fieldset>
<fieldset class="smc-fieldset">
<legend>Смета на материалы</legend>
<div class="smc-table-wrap">
<table class="smc-table">
<thead>
<tr>
<th>Материал</th>
<th>Кол-во</th>
<th>Цена, ₽ *</th>
<th>Сумма, ₽</th>
</tr>
</thead>
<tbody id="smc-estimate-rows"></tbody>
<tfoot>
<tr class="smc-total-row">
<td colspan="3">Итого по смете</td>
<td class="smc-num" id="smc-total">—</td>
</tr>
</tfoot>
</table>
</div>
<span class="smc-hint">* Цены ориентировочные (середина 2026 г.), редактируйте под свой регион и магазин — смета пересчитается автоматически.</span>
</fieldset>
<button type="button" class="smc-btn smc-btn-secondary" id="smc-copy">Скопировать смету</button>
<div class="smc-copy-status" id="smc-copy-status"></div>
<div class="smc-disclaimer">
Расчёт ориентировочный, не является офертой. Фактический расход зависит от основания, технологии нанесения и квалификации мастера; рекомендуется запас материала 5–10 %. Перед закупкой сверьтесь с паспортом выбранной смеси.
</div>
</div>
</div>
<script>
(function () {
'use strict';
/* База смесей: q — расход кг/м² при слое 10 мм (по данным производителей),
bagKg — вес мешка, price — ориентировочная цена мешка на середину 2026 г. */
var MIXES = {
rotband: { name: 'Knauf Ротбанд (гипсовая)', q: 8.5, bagKg: 30, price: 680 },
cement: { name: 'Цементная универсальная (ЦПС)', q: 17, bagKg: 30, price: 520 },
volma: { name: 'ВОЛМА-Слой (гипсовая)', q: 9, bagKg: 30, price: 620 },
startwell: { name: 'Основит Стартвэлл Т-21 (гипс.)', q: 10, bagKg: 30, price: 580 }
};
/* Нормы по сопутствующим материалам */
var PRIMER_PER_M2 = 0.2; /* л/м² за один проход */
var PRIMER_PASSES = 2; /* число проходов */
var BEACON_STEP = 1; /* м — шаг маячковых профилей */
var MIN_LAYER = 6; /* мм — минимальный слой по маяку 6 мм */
/* Ориентировочные цены по умолчанию (середина 2026 г.) */
var PRIMER_PRICE = 65; /* ₽/л грунтовки глубокого проникновения */
var BEACON_PRICE = 75; /* ₽/шт маяк 6 мм, 3 м */
var $ = function (id) { return document.getElementById(id); };
var form = $('smc-form');
var errorsBox = $('smc-errors');
var resultsBox = $('smc-results');
var state = null; /* последний успешный расчёт */
/* ---------- Переключение способа задания площади ---------- */
var modeRadios = form.querySelectorAll('input[name="smc-area-mode"]');
function syncAreaMode() {
var manual = form.querySelector('input[name="smc-area-mode"]:checked').value === 'manual';
$('smc-wrap-height').style.display = manual ? 'none' : '';
$('smc-wrap-openings').style.display = manual ? 'none' : '';
$('smc-wrap-area').style.display = manual ? '' : 'none';
$('smc-wrap-length').style.display = manual ? 'none' : '';
$('smc-wrap-length2').style.display = manual ? '' : 'none';
}
for (var r = 0; r < modeRadios.length; r++) {
modeRadios[r].addEventListener('change', syncAreaMode);
}
/* ---------- Утилиты ---------- */
function num(id) {
var el = $(id);
var v = parseFloat(String(el.value).replace(',', '.'));
return isNaN(v) ? null : v;
}
function markInvalid(id) { $(id).classList.add('smc-invalid'); }
function clearInvalid() {
var els = form.querySelectorAll('.smc-invalid');
for (var i = 0; i < els.length; i++) els[i].classList.remove('smc-invalid');
}
function fmtNum(v, digits) {
return v.toLocaleString('ru-RU', { minimumFractionDigits: digits, maximumFractionDigits: digits });
}
function fmtMoney(v) {
return v.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 }) + ' ₽';
}
/* ---------- Валидация ---------- */
function validate(manual) {
var errors = [];
clearInvalid();
var L, H, openings, area;
if (manual) {
area = num('smc-area');
if (area === null || area < 1 || area > 1000) {
errors.push('Укажите площадь под штукатурку — от 1 до 1000 м².');
markInvalid('smc-area');
}
L = num('smc-length2');
if (L === null || L < 0.5 || L > 200) {
errors.push('Укажите суммарную длину стен для расчёта маяков — от 0,5 до 200 м.');
markInvalid('smc-length2');
}
} else {
L = num('smc-length');
if (L === null || L < 0.5 || L > 200) {
errors.push('Укажите суммарную длину стен — от 0,5 до 200 м.');
markInvalid('smc-length');
}
H = num('smc-height');
if (H === null || H < 1 || H > 6) {
errors.push('Укажите высоту стен — от 1 до 6 м.');
markInvalid('smc-height');
}
openings = num('smc-openings');
if (openings === null || openings < 0 || openings > 500) {
errors.push('Площадь проёмов должна быть от 0 до 500 м².');
markInvalid('smc-openings');
}
if (L !== null && H !== null && openings !== null && L * H - openings < 1) {
errors.push('Площадь за вычетом проёмов получилась меньше 1 м² — проверьте размеры.');
markInvalid('smc-openings');
}
}
var devs = [];
var filled = 0;
for (var i = 1; i <= 5; i++) {
var id = 'smc-dev' + i;
var raw = $(id).value.trim();
if (raw === '') continue;
var v = parseFloat(raw.replace(',', '.'));
if (isNaN(v) || v < 0 || v > 100) {
errors.push('Отклонение в точке ' + i + ' должно быть числом от 0 до 100 мм.');
markInvalid(id);
} else {
devs.push(v);
filled++;
}
}
if (filled < 3) {
errors.push('Заполните отклонения минимум в 3 точках — иначе средняя толщина будет неточной.');
}
if (errors.length) {
errorsBox.innerHTML = errors.join('<br>');
errorsBox.classList.add('smc-visible');
return null;
}
errorsBox.classList.remove('smc-visible');
errorsBox.innerHTML = '';
return {
L: L,
area: manual ? area : (L * H - openings),
devs: devs
};
}
/* ---------- Расчёт ---------- */
function calculate(data) {
var mix = MIXES[$('smc-mix').value];
var avgDev = data.devs.reduce(function (a, b) { return a + b; }, 0) / data.devs.length;
var thickness = avgDev + MIN_LAYER; /* мм */
var kg = data.area * thickness * mix.q / 10; /* кг */
var bags = Math.ceil(kg / mix.bagKg); /* шт, вверх */
var primer = data.area * PRIMER_PER_M2 * PRIMER_PASSES; /* л */
var beacons = Math.ceil(data.L / BEACON_STEP); /* шт */
return {
mix: mix,
area: data.area,
avgDev: avgDev,
thickness: thickness,
kg: kg,
bags: bags,
primer: primer,
beacons: beacons
};
}
/* ---------- Отрисовка результатов ---------- */
function render(res) {
var rows = [
['Площадь под штукатурку', fmtNum(res.area, 1) + ' м²'],
['Среднее отклонение стены', fmtNum(res.avgDev, 1) + ' мм'],
['Средняя толщина слоя (отклонение + ' + MIN_LAYER + ' мм по маякам)', fmtNum(res.thickness, 1) + ' мм'],
['Смесь', res.mix.name + ' (расход ' + fmtNum(res.mix.q, 1) + ' кг/м² на 10 мм)'],
['Потребность в смеси', fmtNum(res.kg, 1) + ' кг'],
['Мешков по ' + res.mix.bagKg + ' кг', res.bags.toLocaleString('ru-RU') + ' шт'],
['Грунтовка (' + fmtNum(PRIMER_PER_M2, 1) + ' л/м² × ' + PRIMER_PASSES + ' прохода)', fmtNum(res.primer, 1) + ' л'],
['Маячковые профили 6 мм, 3 м (шаг ' + BEACON_STEP + ' м)', res.beacons.toLocaleString('ru-RU') + ' шт']
];
var html = '';
for (var i = 0; i < rows.length; i++) {
html += '<tr><th scope="row">' + rows[i][0] + '</th><td class="smc-num">' + rows[i][1] + '</td></tr>';
}
$('smc-calc-rows').innerHTML = html;
var est = $('smc-estimate-rows');
est.innerHTML =
'<tr>' +
'<td>Штукатурная смесь, мешки ' + res.mix.bagKg + ' кг</td>' +
'<td class="smc-num">' + res.bags.toLocaleString('ru-RU') + ' шт</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-mix" min="0" max="100000" step="10" value="' + res.mix.price + '"></td>' +
'<td class="smc-num" id="smc-sum-mix">—</td>' +
'</tr>' +
'<tr>' +
'<td>Грунтовка глубокого проникновения</td>' +
'<td class="smc-num">' + fmtNum(res.primer, 1) + ' л</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-primer" min="0" max="10000" step="5" value="' + PRIMER_PRICE + '"></td>' +
'<td class="smc-num" id="smc-sum-primer">—</td>' +
'</tr>' +
'<tr>' +
'<td>Профиль маячковый 6 мм, 3 м</td>' +
'<td class="smc-num">' + res.beacons.toLocaleString('ru-RU') + ' шт</td>' +
'<td><input class="smc-input smc-price-input" type="number" id="smc-price-beacon" min="0" max="10000" step="5" value="' + BEACON_PRICE + '"></td>' +
'<td class="smc-num" id="smc-sum-beacon">—</td>' +
'</tr>';
['smc-price-mix', 'smc-price-primer', 'smc-price-beacon'].forEach(function (id) {
$(id).addEventListener('input', updateTotals);
});
updateTotals();
}
function priceOf(id) {
var v = parseFloat(String($(id).value).replace(',', '.'));
if (isNaN(v) || v < 0) return 0;
return v;
}
function updateTotals() {
if (!state) return;
var pMix = priceOf('smc-price-mix');
var pPrimer = priceOf('smc-price-primer');
var pBeacon = priceOf('smc-price-beacon');
var sumMix = state.bags * pMix;
var sumPrimer = state.primer * pPrimer;
var sumBeacon = state.beacons * pBeacon;
var total = sumMix + sumPrimer + sumBeacon;
$('smc-sum-mix').textContent = fmtMoney(sumMix);
$('smc-sum-primer').textContent = fmtMoney(sumPrimer);
$('smc-sum-beacon').textContent = fmtMoney(sumBeacon);
$('smc-total').textContent = fmtMoney(total);
}
/* ---------- Копирование сметы ---------- */
function buildEstimateText() {
if (!state) return '';
var pMix = priceOf('smc-price-mix');
var pPrimer = priceOf('smc-price-primer');
var pBeacon = priceOf('smc-price-beacon');
var total = state.bags * pMix + state.primer * pPrimer + state.beacons * pBeacon;
return [
'Смета: штукатурка стен (расчёт с сайта «Сметач», ориентировочно)',
'Площадь: ' + fmtNum(state.area, 1) + ' м²',
'Средняя толщина слоя: ' + fmtNum(state.thickness, 1) + ' мм (среднее отклонение ' + fmtNum(state.avgDev, 1) + ' мм + 6 мм минимальный слой по маякам)',
'',
'1. ' + state.mix.name + ': ' + fmtNum(state.kg, 1) + ' кг → ' + state.bags.toLocaleString('ru-RU') + ' мешк. × ' + fmtMoney(pMix) + ' = ' + fmtMoney(state.bags * pMix),
'2. Грунтовка: ' + fmtNum(state.primer, 1) + ' л × ' + fmtMoney(pPrimer) + ' = ' + fmtMoney(state.primer * pPrimer),
'3. Маяки 6 мм (3 м): ' + state.beacons.toLocaleString('ru-RU') + ' шт × ' + fmtMoney(pBeacon) + ' = ' + fmtMoney(state.beacons * pBeacon),
'',
'ИТОГО: ' + fmtMoney(total),
'Расчёт ориентировочный, не является офертой. Рекомендуется запас 5–10 %.'
].join('\n');
}
$('smc-copy').addEventListener('click', function () {
var text = buildEstimateText();
var status = $('smc-copy-status');
function done(msg) {
status.textContent = msg;
setTimeout(function () { status.textContent = ''; }, 4000);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
done('Смета скопирована в буфер обмена.');
}, function () {
fallbackCopy(text, done);
});
} else {
fallbackCopy(text, done);
}
});
function fallbackCopy(text, done) {
var ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
try {
document.execCommand('copy');
done('Смета скопирована в буфер обмена.');
} catch (e) {
done('Не удалось скопировать автоматически — выделите текст сметы вручную.');
}
document.body.removeChild(ta);
}
/* ---------- Отправка формы ---------- */
form.addEventListener('submit', function (e) {
e.preventDefault();
var manual = form.querySelector('input[name="smc-area-mode"]:checked').value === 'manual';
var data = validate(manual);
if (!data) {
resultsBox.classList.remove('smc-visible');
return;
}
state = calculate(data);
render(state);
resultsBox.classList.add('smc-visible');
resultsBox.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
syncAreaMode();
})();
</script>
</html>