Цитата:
Цитата:
Добавим единицами измерения и сантиметры. Это исключительно для примера, и можно не применять, думаю понятно будет как. Когда было две единицы, то было просто, а если три, то нужно запоминать текущие единицы, чтобы корректно преобразовывать значения в полях для выбранных единиц. Запоминание текущих единиц в переменную dir производится в момент нажатия мыши на копки выбора единиц (значения выбранной кнопки). В время смены единиц из запомненных единиц и выбранных формируется строка, по которой как свойству объекта mul получается множитель на который производится коррекция значений в полях ввода. Код кнопок управления такой: <label><input type="radio" name="unit" value="0" checked="" /> метры</label> <label><input type="radio" name="unit" value="1" /> сантиметры</label> <label><input type="radio" name="unit" value="2" /> миллиметры</label> Расчеты прямоугольников, треугольников и ... вынесены в функции. function rectangle(a, b) { return a * b } function triangle(a, b) { return a * b * .5 } function trapeze(a, b, c) { return (a + b) * c * .5 } function calculate(g, v) { var a, b; switch(g) { case 'rectangle': a = rectangle(v[0], v[1]), b = rectangle(v[2], v[3]); return [a, b, a && b ? (a + b) * 2 : 0]; break; case 'triangle': a = triangle(v[0], v[1]), b = trapeze(v[2], v[3], v[4]); return [a, b, a && b ? (a + b) * 2 : 0]; break; case 'pyramid': a = triangle(v[0], v[1]), b = triangle(v[0], v[2]); return [a, b, rectangle(v[1], v[2]), a && b ? (a + b) * 2 : 0]; } } $(function() { var dir, //предыдущее состояние единиц измерения sqr = '²', //символ кдаратных значений mul = { //множетели единиц измерения для полей ввода в зависимости от предыдущего и нового состояния '01': 100, '12': 10, '02': 1000, '10': .01, '21': .1, '20': .001 }, dim = [{unt: 'м', dec: 2, mul: 1}, {unt: 'см', dec: 0, mul: .0001}, {unt: 'мм', dec: 0, mul: .000001}], side = $('input:text') .on('keyup', function() { this.value = this.value.replace(/[,\.]+/,'.').replace(/[^\d.]/,''); var u = unit.filter(':checked').val(); //расчет площадей для всех заполненных полей $('[data-area]').each(function() { //группу определяет атрибут data-area var group = $(this).data('area'), values = $.map(side.filter('.'+group), function(e) { var v = parseFloat(e.value); return v || 0 }), area = calculate(group, values); $(this).find('.area').each(function(i, e) { $(e).text( //вывод площадей в метрах area[i] ? (area[i] * dim[u].mul).toFixed(2) + ' м' + sqr : '' ) }) }) }), unit = $('input:radio') .change(function() { var u = this.value, //выбранные единицы измерения d = dir + u; //множитель единиц в зависимоти от прежнего их состояния $('.unit').text(dim[u].unt); side.val(function() { var v = parseFloat(this.value); if(v) return (v * mul[d]).toFixed(dim[u].dec) }).trigger('keyup'); }) .parent() //получить родителей - label .mousedown(function() { //запомнить текущие единицы измерения при нажатии мыши на label dir = unit.filter(':checked').val() }).end(); //вернуться к кнопкам radio }); Интересная комната, на крышу похожа. :) Может быть для такой конфигурации иметь высоту до конька и высоты для сторон рассчитывать, а не вводить для каждой? Ведь "на глазок" ввести значение чтобы все срослось не трудно ли будет? |
Да, Вы правильно поняли - это крыша. Я в 28-ом посте делал примечание что для удобства понимания заменил крышу комнатами (чтобы не распугать помощь форума). Теперь я понял что коньками с ендовыми вас не запугать : )
Навсяк случай скажу что проект некоммерческий и в калькуляторе НИКОГДА НЕ БУДЕТ денежных единиц измерений. Я не коммерс, крыши моё хобби. Что касается высот, то пока такой расчёт не намечается. Через высоты можно отдельный собрать калькулятор для создания проекта крыши, где за исходные данные брать коробку дома и высоты. Возможно через года два у меня будут знания чтобы реализовать подобное с визуализацией проекта. А пока первая цель - площади для типовых крыш. В размерах я делаю варианты отталкиваясь не только от высот скатов, но и просто по сторонам скатов крыши (более удобно для обывателя), где вся арифметика идёт через полупириметры. Изначально я себе ставил срок сделать калькулятор до Нового Года, но Вы мне всю логику собрали. Осталось малость - внести формулы, сделать раскладки скатов с указаниями для вводимых размеров и общие планы крыш + вёрстку оформить, чтобы удобно было под все типы устройств. Второй целью стоит расчёт кровельных материалов согласно выбранного покрытия. Там уже сложность в том что их очень много и у каждого свои модели, размеры, вес, комплектующие и т.д. и т.п. Собрать их все и вбить - очень нудноватая работа. Но зато я эту тематику знаю достаточно хорошо и знаю все ньюансы. Поэтому вторая цель вполне достижима и почему бы не прийти к ней. Спасибо за новую версию с функциями - я в ней понимаю куда добавлять новые фигуры и как делать расчёт. Сейчас начну собирать всё в единый калькулятор. |
Цитата:
А вообще при сложной конфигурации крыши такой калькулятор будет неудобен, слишком длинная портянка получится. Тут нужен интерактивный - щелкнули мышью по любому скату, появились поля ввода его параметров. Ввели параметры, расчет, и скат подсвечивается, при этом подсвечивается и противоположный равный ему скат. При наведении мыши на такие скаты форма появляется с ранее введенными параметрами и расчетом. Для смежных скатов, у которых стороны при этом будут рассчитываться автоматически, форма будет так же отображать автоматом рассчитанные параметры, останется ввести оставшиеся. Примерно так, иначе сложно будет охватить сразу все. |
Я с вами согласен полностью и по смежным сторонам и во всём остальном. Я прекрасно понимаю эту логику. Но я адекватно отталкиваюсь от своих возможностей и знаний в программировании. На данный момент они у меня самые минимальные: я только начинаю осмысленно читать код, но ещё не могу его писать. А то что Вы предложили - это цель ради которой я изучаю javascript.
Как написано в вступлении сайта - жаль что времени очень мало... Я сутками напролёт неотрываясь сижу и буду сидеть ещё несколько месяцев только за javascript. Вот нашёл хорошую поляну для обучения и форум. Здесь в учебнике лучше чем на ютубе. Сейчас решаю самые простые задания из учебника сайта - мне нужно научиться начать писать код, а не только читать. Вы мне и так помогли во многом уделив на меня своё время. А злоупотреблять вашим вниманием на свои просьбы сделать вместо меня это и то, для меня сейчас неуместно. К вам как к профи можно будет в будущем обратиться, если у меня возникнут проблемы. А попадать к вам в игнор из за постоянных просьб с решениями я не хочу. Вы мне и так очень сильно помогли и я этим дорожу. |
Цитата:
Есть онлайн редакторы image map, добавить для изображения карту будет не сложно. |
Круто Вы меня пнули в image map, а главное во время. Признаюсь - не знал. Для меня это будет очень полезно не только в плане калькулятора. Я бегло ознакомился, теперь постараюсь нагуглить толковый работающий онлайн редактор и изучить более подробно сам принцип.
С геометрией у меня всё отлично - ручаюсь. Что такое высоты и как их применять я знаю. Вы уж простите, но пока я их в расчёты не беру. А вот построить луч (угол) на их значениях, чтобы он прорисовывался с нужным градусом - буду реализовывать как только натолкнусь на решение. Догадываюсь что это линии нужно рисовать в css и при помощи javascript задавать координаты. Но это пока только мИсли : ) Ещё сегодня успел бегло ознакомиться с библиотекой jQuery UI. Есть в ней Droggable и Droppable. Может подскажите - можно ли на их основе реализовать задумку "онлайн конструктор", чтобы имея шаблонные макеты скатов пользователь из них собирал свой произвольный комплект. Допустим если нет типового калькулятора, чтобы можно было произвольно из шаблончиков (заданных форм) собрать свой комплект. Или это я протупил с такой идеей? |
Цитата:
Тем более такой подход "без рисования" как раз и вписывается в концепцию конструирования по заданным шаблонам. Что конечно можно сделать, причем и без jQuery UI в современных браузерах. Но если меньше парится, то jQuery UI. |
Я извиняюсь, совсем мутно написал. Я имел в виду отдельный калькулятор вычисляющий уклон крыши. По сути это прямоугольный треугольник который лежит на одном катете (горизонтально) - это заложение. Второй катет (вертикально) - это высота крыши (или разность высот между коньком и карнизом). Гипотенуза - это луч (скат крыши) определяющая уклон.
Размеры катетов задаются в инпутах пользователем. В результате выдаются: угол, наклон (i) и подходящие кровельные покрытия для этого уклона. В посте выше я имел в виду визуализацию угла, чтобы отобразить его на мониторе. Толковый редактор image map нашёл. Как снимать координаты понял. Сейчас определюсь как связку делать и буду тестить. |
Цитата:
То есть, по уму на плане крыши должны быть области, размеры которых нужно обязательно задать, все остальное будет рассчитываться автоматически. Это похоже на 3D моделирование, в котором изначальная модель, это треугольный брус с дополнительными вершинами на вертикальных сторонах, например если нужна будет "горбатая" крыша. Двигая вершины и грани этой модели можно создавать более сложные. При этом все параметры модели будут рассчитываться автоматически, тут уж чистая геометрия. |
Где то накосячил, не пойму в чём. Ошибки в консоле нет, но результата площади тоже нет.
Теперь изменился тип фигуры: четыре разные трапеции. В функцию calculate(g, v) добавил две новые переменные: c, d; В case 'g_roof' прописал через обращение к function trapeze(a, b, c) <div class="row plos g_roof"> <div class="col-sm-4"> <h4>Скат 1</h4> <div class="st1">Основание (карниз):</div> <div class="st2"><input class="g_roof" /><span class="unit"> м</span></div> <div class="st1">Верх:</div> <div class="st2"><input class="g_roof" /><span class="unit"> м</span></div> <div class="st1">Бок (высота):</div> <div class="st2"><input class="g_roof" /><span class="unit"> м</span></div> </div> </body> Так же с image map тёмный лес. Перерыл через поиск весь форум и учебник - инфы минимально, только скользкие упоминания. Гугл тоже уводит в ненужном направлении. Может подскажите по каким поисковым запросам нужно рыть? Так как для меня это новое, все мои построения поисковых фраз приводят к одним и тем же результатам. Пока у меня только картинки с координатами есть. Координаты для скатов: <img src="https://goo.gl/6pD9hJ" alt="Фигура" usemap="#Map" /> <map name="Map" id="Map"> <area alt="скат 1" title="" href="#" shape="poly" coords="13,10,238,9,239,55,60,55" /> <area alt="скат 2" title="" href="#" shape="poly" coords="60,55,239,54,239,100,104,100" /> <area alt="скат 3" title="" href="#" shape="poly" coords="60,55,103,97,104,160,60,160" /> <area alt="скат 4" title="" href="#" shape="poly" coords="13,10,60,55,60,160,13,160" /> </map> |
Я же в коде писал комментарии к тем частям его, которые были изменены. И было написано, что родительский блок групп полей ввода связывается со своей группой теперь не по классу, а по атрибуту data-area, так как ваши DIV имеют не одно имя класса. По этому атрибуту как селектору и находятся данные DIV в строке 044 кода, и из этого атрибута получается и имя группы в строке 045 кода. А вы имя группы прописали в класс DIV, поэтому и не работает. Заменить
<div class="row plos g_roof"> на <div class="row plos" data-area="g_roof"> и все будет работать. |
Вот же блин, тупая моя голова... По другим фигурам делал правильно, а здесь пропустил. Я ещё умудрился ночью с ошибкой в консоли, указывающей на конкретную строку, просидеть два часа прежде чем осознал что пропустил закрывающую скобку в конце строки:
case 'triangle': a = triangle(v[0], v[1]), b = trapeze(v[2], v[3], v[4]); |
О карте изображения. Должна быть одна карта, та что показана первой, вторая это нечто.... У вас четыре ската на изображении, значит и столько же областей на карте:
<map name="Map" id="Map"> <area id="rect-1" title="скат 1" shape="poly" coords="13,10,238,9,239,55,60,55" /> <area id="rect-2" title="скат 2" shape="poly" coords="60,55,239,54,239,100,104,100" /> <area id="rect-3" title="скат 3" shape="poly" coords="60,55,103,97,104,160,60,160" /> <area id="rect-4" title="скат 4" shape="poly" coords="13,10,60,55,60,160,13,160" /> </map> Атрибут href им совсем не нужен, переходов по ним же вы не планируете. Имя ската нужно помещать в title, а не в alt, назначение alt иное. Если связывать области со скриптом (объектом описывающем введенные размеры и т.п.), то задать им идентификаторы. Добавьте в секцию $(function() { }); такой код: $('#Map area').click(function() { alert(this.id) }).mouseenter(function() { alert('Показать введенные размеры') }); и щелчок по области отобразит ее ID. А в реалии это показать форму и заполнить ее данными из связанного объекта, если размеры уже вводились, а также просчитать площадь (можно при вводе просчитанную запоминать, а не просчитывать постоянно). Сложнее будет с маркированием, то есть окрасить, так как это изображение (но сделать можно), но на первых порах (для освоения) достаточно при наведении на область отображать уже введенные значения (как показано в коде). Можно над областями такими их прописать, что и будет являться признаком заполнения параметров ската. Более гибкое решение, это SVG. |
Спасибо! Теперь я понял идею карты. Функцию подключил - работает. Пока её скрыл под комментарием. Чуть позже вернусь к её наполнению. Посмотрю jQuery, а там решу делать её на клике или mouseenter.
Скажите, я правильно понял что к сегментам карты нельзя прицепить стили? Думал hover задать, да не тут то было. Вопросы в теме пока прекращаю. Следующий мой вопрос только после того как заработаю первый плюс (помогу кому то другому). А пока буду рядом - читать форум и штудировать учебник сайта. |
Цитата:
Можно посредством canvas работать с копией изображения. |
Здравствуйте! Я снова к вам со своими глупыми вопросами : (
<head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <style> .st1 {display: inline-block;margin-top: 8px;width: 80px;text-align: right;} .st2 {display: inline-block;}h4 {color: #c3410d;}input {width: 110px;} input[type="radio"] {width: 25px;} .col-sm-4 {width:220px;display:inline-block;border:solid 1px #888;padding:5px;margin-left:10px;background:#eee;} .col-sm-6 {width:250px;display:inline-block;border:solid 1px #888;padding:5px;margin-left:10px;background:#eee;} </style> <script> function triangle(a, b) { return a * b * .5 } function trapeze(a, b, c) { return (a + b) * c * .5 } function calculate(g, v) { var a, b, c, d, e, f; switch(g) { case 'figura': a = trapeze(v[0], v[1], v[2]), b = triangle(v[3], v[4]), c = trapeze(v[5], v[6], v[7]), d = trapeze(v[8], v[9], v[10]), e = trapeze(v[11], v[12], v[13]); return [a, b, c, d, e, a && b && c && d && e ? (a + b + c + d + e) : 0]; break; } } $(function() { var dir, sqr = '²', mul = { '01': 100, '12': 10, '02': 1000, '10': .01, '21': .1, '20': .001 }, dim = [{unt: ' м', dec: 2, mul: 1}, {unt: ' см', dec: 0, mul: .0001}, {unt: ' мм', dec: 0, mul: .000001}], side = $('input:text') .on('keyup', function() { this.value = this.value.replace(/[,\.]+/,'.').replace(/[^\d.]/,''); var u = unit.filter(':checked').val(); $('[data-area]').each(function() { var group = $(this).data('area'), values = $.map(side.filter('.'+group), function(e) { var v = parseFloat(e.value); return v || 0 }), area = calculate(group, values); $(this).find('.area').each(function(i, e) { $(e).text( area[i] ? (area[i] * dim[u].mul).toFixed(2) + ' м' + sqr : '' ) }) }) }), unit = $('input:radio') .change(function() { var u = this.value, d = dir + u; $('.unit').text(dim[u].unt); side.val(function() { var v = parseFloat(this.value); if(v) return (v * mul[d]).toFixed(dim[u].dec) }).trigger('keyup'); }) .parent() .mousedown(function() { dir = unit.filter(':checked').val() }).end(); }); </script> </head> <label><input type="radio" name="unit" value="0" checked="" />В метрах</label> <label><input type="radio" name="unit" value="1" /> сантиметры</label> <label><input type="radio" name="unit" value="2" /> миллиметры</label> <h3>Площадь</h3> <div class="row plos" data-area="figura"> <div class="col-sm-4"> <h4>Сигмент 1</h4> <div class="st1">Сторона 1:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 2:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 3:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <h4>Сигмент 2</h4> <div class="st1">Сторона 1:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 2:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <h4>Сигмент 3</h4> <div class="st1">Сторона 1:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 2:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 3:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> </div> <div class="col-sm-4"> <h4>Сигмент 4</h4> <div class="st1">Сторона 1:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 2:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 3:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <h4>Сигмент 5</h4> <div class="st1">Сторона 1:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 2:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> <div class="st1">Сторона 3:</div> <div class="st2"><input class="figura" /><span class="unit"> м</span></div> </div> <div class="col-sm-6"> <img src="http://i.piccy.info/i9/5dc9e1044199780a5c682345c5e8e242/1503672360/7796/1170341/G_111.jpg" style="margin-bottom: 5px;" /><br> Площадь 1 сигмента: <span class="area"></span><br> Площадь 2 сигмента: <span class="area"></span><br> Площадь 3 сигмента: <span class="area"></span><br> Площадь 4 сигмента: <span class="area"></span><br> Площадь 5 сигмента: <span class="area"></span><br> <div class="rezultat ">ПЛОЩАДЬ всей фигуры = <span class="area"></span></div> </div> </div> В общем, не покидает меня мысль к калькулятору добавить автозаполнение значения для смежного размера. Есть у меня инпуты, которые по сути - это один и тот же размер. Можно ли реализовать чтобы при заполнении пользователем одного инпута, значение автоматически добавлялось в равный ему инпут? Например в этом варианте расчёта у меня: сиг1стор2 = сиг3стор2 сиг4стор2 = сиг5стор2 В другом варианте (расчёт по сторонам через полупериметры) - все стороны имеют дублёра кроме тех что являются контуром всей фигуры. Думаю первое с чего стоит начинать - это добавить уникальный класс к одинаковым инпутам, так как здесь дали совет не увлекаться с Id. Потом нужно отдельной функцией делать, где брать значение инпута и через if если оно > 0, то... вот здесь я и приплыл. Можно вообще такое реализовать? Если да, пните пожалуйста куда хоть смотреть, в JavaScript или в jQuery? |
Цитата:
Цитата:
Представим что крыша в основании квадрат и имеет форму правильно пирамиды. Значит все четыре ската будут равны. Чтобы рассчитать площадь скатов нужно ли запрашивать у пользователя ввод значений для каждого ската, то есть иметь "равнозначные инпуты"? О чем речь? |
У меня так и есть, для правильной пирамиды в одном случае ввод только двух размеров - основание и высота, во втором случае три размера - грани треугольника (расчёт через полуперимметр). Я первый от второго варианта планирую разделить табами.
А вот в таком варианте все скаты разные: ![]() Только каждый конёк нужно вводить по два раза. Получается инпут ската1стор2 = инпуту ската3стор2 и ск4стор2 = ск5стор2 Вся крыша разбита на скаты. Так же и запрос размеров разделён группами по скатам, чтобы не запутаться. Меня интересует, можно ли реализовать что при введении значения конька из ската 4 (Сторона 2), это же значение автоматически появлялось в поле ската 5 (сторона 2). Я это обозвал как равнозначный инпут. Убирать из ската5 сторону2 (повторяющийся размер) я не хочу, так как его отсутствие запутывает. Удобно когда видишь фигуру ската и есть поля под все размеры, так лучше восприятие и вдруг что удобно проверять правильность введённых размеров. Взять ту же раскладку из проекта крыши - там чертят скаты и при этом проставляют все размеры. Добавлю скрин. Можно ли сделать так, что если я ввожу в поле значение, чтобы оно автоматом появлялось и другом поле. Такое реализуемо на JavaScript или jQuery? ![]() |
Цитата:
Можно и иначе поступить - Сегмент 4 и Сегмент 5, это одна группа, у которой одно поле общее (Сторона 2). |
Спасибо за ответ! Думаю мне подойдёт вариант с добавлением ещё одного имени класса.
Извините меня за надоедливость и непонятную формулировку вопросов. Постараюсь больше не тупить и находить ответы в поиске и гугле. |
Цитата:
В код после строки 041 добавить обработчик (вернее условие): if(/pair/.test(this.className)) $('input.'+/pair.+/.exec(this.className)[0]).val(this.value); |
Я сдаюсь :agree:
Не знаю даже что сказать... |
Цитата:
if(~this.className.indexOf('pair')) side.not(this).filter('.'+/pair\S+/.exec(this.className)[0]).val(this.value); |
Спасибо вам!
Я имел в виду что первый вариант работал, проблем не вызывал и очень просто назначать нужные мне поля. |
Цитата:
Кроме того, в первом варианте шаблон рег. выражения будет корректно работать только в том случае, если имя класса описывающего парные поля ввода указано последним в списке, иначе будет возвращено все начиная с pair. Второй вариант лишен этого недостатка, имя класса парных полей может располагаться в начале, в середине, в конце списка. По поводу "калькулятор выдаёт результат после ввода двух значений". Перед передачей введенных значений в функцию расчета, значение пустого поля приравнивается к 0 (строка 049 кода). Исходным было то, что практически во всех расчетах присутствует умножение, и в случае пустых полей функция также вернет 0. При выводе рассчитанных площадей в строке 055 кода проверка - если функция вернула значение, значит вывод площади, в противном случае пустая строка. То есть нужно проверить логику расчета и наличие 0. Если нулевое значение поля на расчет не влияет (в любом случае будет значение), то требуется более расширенная проверка, например на заполнение всех полей. |
Я понял.
Думаю для моего уровня знаний этот баг будет несущественной проблемой. Главную задачу калькулятор делает. Пока оставлю так как есть, а через полгода, год - вернусь к редактированию этой функции. Мне ещё надо много учиться, чтобы лезть своими кривыми руками в правку такого скрипта : ) |
Здравствуйте! В виджете из архива на все поисковые поля назначена функция, которая заменяет некоторые введенные символы на другие, например, букву Ё на Е. Сокращенно функция выглядит так —
function fix(obj) { obj.value = obj.value.replace(/[ё]/g, 'е'); obj.value = obj.value.replace(/[áàâǎăãảạäåāąấầẫẩậắằẵẳặǻ]/g, 'а'); obj.value = obj.value.replace(/[éèêěĕẽẻėëēęếềễểẹệ]/g, 'е'); obj.value = obj.value.replace(/[óòŏôốồỗổǒöőõøǿōỏơớờỡởợọộ]/g, 'о'); } В коде виджета строк больше, и замечено, что на некоторых версиях андроида при вводе букв — ранее введенное дублируется в input-окне. Есть ли другой способ прописать подобный функционал на input onkeyup? |
Часовой пояс GMT +3, время: 11:54. |