Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Анимация заливки термометра svg + jquery

#javascript #html #jquery #svg #svg_animation




Хочу сделать свг градусник и чтобы при нажатии на чекбоксы, заливка проводилась плавно
снизу вверх, включая деления термометра(следовательно когда галочки будут снимать то
заливка будет так же плавно спускаться). Интересует как сделать такую заливку и прикрутить
jquery для этого. (Чекбоксы работают по принципу toogleClass("check")).

Вот что я смог напортачить в Jquery

$(".analysis-li").click(function(){
    $(this).toggleClass("check");
    var firstStop = document.getElementById('F1gst1');
    percentage = '10%'; firstStop.setAttribute('offset',percentage);
});


Нужно сделать чтобы при каждом классе check процент увеличивался, а при убирание
этого класса, он опять уменьшался. Ниже html и css

  • li.analysis-li margin-bottom: 54px position: relative padding-left: 20px cursor: pointer &::before position: absolute content: '' width: 34px height: 34px left: -34px bottom: 3px border: #d3ad4b solid 3px background-color: transparent cursor: pointer background-image: url(../img/check.png) background-repeat: no-repeat background-position: center background-size: 0 &.check::before background-size: 30px &:hover::before border-color: #c29846 transition: .3s


    Ответы

    Ответ 1



    Вот собрал что-то подобное, извиняйте уж без жуквери, изменил верстку на программную, если это не надо можно скопировать готовый html из сниппета через отладчик let path = (y, d, extra) => `` let multi = (count, html) => Array(count).fill(0).map((e, i) => html(i)).join(''); let toggle = el => el.classList.toggle('on') | rect.setAttribute('y', 14.6*(7-document.querySelectorAll("path.on").length)+8) scale.innerHTML = multi(10, i => path(i*10, 'M60,10h10M65,12h5M65,14h5M65,16h5M65,18h5')); checks.innerHTML = multi(7, i => path(i*12, 'M10,10v8h8v-8z', 'class="on" onclick="toggle(this)"') + path(i*12, 'M12,14l2.2,2l2.2,-4')) g#scale path { stroke: white; stroke-width: 0.7; } #checks { position: absolute; top: 20px; left: 20px; } #checks path { fill: none; pointer-events: all; stroke: #f5b53a; cursor:pointer; stroke-linejoin:round; } #checks path.on + path { opacity:1; } #checks path:nth-child(2n) { opacity: 0; pointer-events: none; transition: 0.5s; stroke: white; }

    Ответ 2



    В общем вот так примерно Смотреть на полный экран let move = cb => rect.setAttribute('y', 400 - cb.textContent*50) document.querySelectorAll('.checkbox') .forEach(cb => cb.addEventListener('click', e => move(cb))) * { user-select: none; } html, body { height: 100%; margin: 0; padding: 0; } .text { font-size: 20px; fill: #fff; font-weight: 900; font-family: Georgia, 'Times New Roman', Times, serif; } .svg-event { width: 800px; position: relative; margin: 30px auto; } .panel { position: absolute; top: 30px; left: 30px; width: 100px; height: 500px; } .panel div { width: 50px; height: 50px; background: #fbfbfb; margin: 18px auto; display: flex; justify-content: center; align-items: center; font-family: 'Times New Roman', Times, serif; font-weight: 900; } #rect { transition: 0.68s cubic-bezier(0.05, 1.06, 0.71, 0.4); }
    7 6 5 4 3 2 1 Высокая темпиратура Средняя темпиратура Низкая темпиратура
    7
    6
    5
    4
    3
    2
    1


    Ответ 3



    Решение jQuery Вот как бы я это сделал. Для анимации градиента я использую requestAnimationFrame. Я анимирую второе смещение stop между 10% и 100%, но вы можете выбрать нужные значения. Пожалуйста, прочитайте комментарии в коде. // Второй stop градиента let laststop = document.getElementById('F1gst2'); // переменная, используемая для переключения анимации let n = 0; // целевое значение атрибута смещения let target; // фактическое значение атрибута смещения (offset) let val = 10; //идентификатор кадра анимации запроса let rid = null; $(".analysis-li").click(function(){ n++; // установить целевое значение if(n%2 == 1){ target = 100; }else{target = 10} // если есть анимация, то остановить if(rid){cancelAnimationFrame(rid); rid="null"} // вызвать функцию кадра frame() }); function frame(){ rid = requestAnimationFrame(frame); //расстояние между значением и целевым значением dist = target - val; //Увеличить значение val += dist/10; // установить значение offset laststop.setAttributeNS(null,"offset",`${val}%`) } svg{border:1px solid; width:30px} path{stroke:black;}

    click here

    Аналогичный вопрос был задан на EnSo. Источник ответа: @enxaneta Сделал перевод и размещаю его здесь для более полной картины возможностей решения. Чем больше ответов, тем полезнее для поиска нужного решения.

    Ответ 4



    Разобрался с помощью установки градиента. Не забудьте удалить тэг style в svg если он у вас есть. Градиент вставляется после открывающего тега svg перед path. Потом при помощи offset добился заливки в процентах. Потом идет сравнивание количество элементов и количество выбранных элементов. И после этого задается результат. var firstStop = document.getElementById('F1gst1'); percentage = '0%'; var CountAllCheckboxes = $('.analysis-li').length; var CountChecked = 0; $(".analysis-li").click(function(){ $(this).toggleClass("check"); CountChecked = $('.analysis-li.check').length; percentage = ((CountChecked / CountAllCheckboxes) * 100)+'%'; firstStop.setAttribute('offset',percentage); }); Решение с плавной анимацией https://stackoverflow.com/a/56836400/11707220

    Комментариев нет:

    Отправить комментарий