Area/Volume Calculator Development for 1C-Bitrix
An area and volume calculator is a fundamental tool for websites of construction, finishing, cleaning companies and materials manufacturers. The task looks straightforward at first glance: the user enters dimensions and gets an area or volume. In practice it is more complex: different room types are needed, deductions for openings, non-standard shapes, summation of multiple rooms and automatic transition to cost calculation.
Geometric Formulas
A complete set of formulas for construction calculations:
namespace MyProject\Services\Calculators;
class GeometryCalculator
{
// Room areas
public static function rectangleArea(float $width, float $length): float
{
return $width * $length;
}
public static function lShapeArea(float $w1, float $l1, float $w2, float $l2): float
{
// L-shaped room: two rectangles
return self::rectangleArea($w1, $l1) + self::rectangleArea($w2, $l2);
}
public static function circleArea(float $radius): float
{
return M_PI * $radius * $radius;
}
public static function triangleArea(float $base, float $height): float
{
return 0.5 * $base * $height;
}
// Wall area of a room (with deduction for openings)
public static function wallArea(
float $perimeter,
float $height,
array $openings = [] // [{width, height}, ...]
): float {
$totalWall = $perimeter * $height;
$openingsArea = array_sum(array_map(fn($o) => $o['width'] * $o['height'], $openings));
return max(0, $totalWall - $openingsArea);
}
// Volumes
public static function boxVolume(float $width, float $length, float $height): float
{
return $width * $length * $height;
}
public static function cylinderVolume(float $radius, float $height): float
{
return M_PI * $radius * $radius * $height;
}
// Roof area accounting for slope
public static function roofArea(float $horizontalArea, float $slopeDegrees): float
{
$slopeRad = deg2rad($slopeDegrees);
return $horizontalArea / cos($slopeRad);
}
}
Multi-Room Calculator
Calculation for multiple rooms with accumulated totals:
class RoomCalculator {
constructor() {
this.rooms = [];
}
addRoom(params) {
const room = {
id: Date.now(),
name: params.name || `Room ${this.rooms.length + 1}`,
floor: params.width * params.length,
ceiling: params.width * params.length,
walls: this.calcWalls(params),
};
this.rooms.push(room);
return room;
}
calcWalls(params) {
const perimeter = 2 * (params.width + params.length);
const totalWall = perimeter * params.height;
const openingsArea = (params.doors || []).reduce((sum, d) => sum + d.width * d.height, 0)
+ (params.windows || []).reduce((sum, w) => sum + w.width * w.height, 0);
return totalWall - openingsArea;
}
getTotal() {
return {
totalFloor: this.rooms.reduce((s, r) => s + r.floor, 0),
totalCeiling: this.rooms.reduce((s, r) => s + r.ceiling, 0),
totalWalls: this.rooms.reduce((s, r) => s + r.walls, 0),
rooms: this.rooms,
};
}
removeRoom(id) {
this.rooms = this.rooms.filter(r => r.id !== id);
}
}
Visual Parameter Input
The challenge lies in UX. Users don't always know exact dimensions. Several approaches help:
Standard sizes. Selection from a reference guide: "standard panel apartment", "studio 25m²", "one-bedroom 38m²". Dimensions are auto-filled with the option to adjust.
SVG room diagram. An interactive drawing where the user clicks on a wall and enters a dimension. Implemented with SVG + JavaScript, no external dependencies.
Layout upload. The user uploads a photo or scanned floor plan; a manager processes it manually. A hybrid approach for complex objects.
Bitrix Catalog Integration
After calculating the area — automatic transition to material selection:
// AJAX handler: select the required quantity of products by area
public function suggestMaterialsAction(float $area, string $materialType): array
{
$norm = MaterialNormRepository::getByType($materialType);
$rawQuantity = $area * $norm['consumption_rate'] * $norm['waste_factor'];
$packages = ceil($rawQuantity / $norm['package_size']);
// Check stock availability
$product = \CCatalogProduct::GetByID($norm['product_id']);
$inStock = (int)($product['QUANTITY'] ?? 0);
return [
'product_id' => $norm['product_id'],
'product_name' => $norm['product_name'],
'packages' => $packages,
'in_stock' => $inStock,
'enough_stock' => $inStock >= $packages,
'can_order' => true,
];
}
Saving and Printing Results
For complex objects, users want to save their calculation. Implementations:
Link with parameters — the calculation is encoded into URL parameters, and the link is saved or shared:
const paramsStr = btoa(JSON.stringify(calcParams));
const shareUrl = `${window.location.origin}/calculator/?calc=${paramsStr}`;
PDF export — server-side generation via the TCPDF or mPDF library installed through Composer in /local/:
$pdf = new \TCPDF();
$pdf->AddPage();
$pdf->writeHTML($this->renderCalcHtml($calcResult));
$pdf->Output('calc_result.pdf', 'D'); // D = force download
Email with results — sent via \Bitrix\Main\Mail\Event::sendImmediate().
Timelines
| Task | Timeline |
|---|---|
| Simple area calculator (one room type, linear output) | 2–4 days |
| Multi-room calculator with multiple forms and a final estimate | 1.5–2 weeks |
| Calculator with visual input, catalog integration and PDF export | 3–5 weeks |
Calculation accuracy is paramount. An error of 10% on the low side means the client buys additional materials at a different (often higher) price and comes back dissatisfied. It is better to add an explicit 5% buffer than to underestimate and lose trust.







