Анимируйте элементы svg с помощью Javascript и JQuery

Я пытаюсь анимировать следующие элементы html, чтобы реализовать функциональность, аналогичную колесику громкости.

<svg id="circle_svg" width="200" height="175">
<circle cx="100" cy="85" r="75" stroke="black" stroke-width="2" fill="lightgray"/>
<line id="line_alpha" x1="100" y1="85" x2="100" y2="160" style="stroke:rgb(0,0,255);stroke-width:2"/>
<circle id="dot_alpha" cx="100" cy="160" r="10" stroke="black" stroke-width="2" fill="red"/>
</svg>

Основная идея заключается в том, что щелчок по красной точке и перемещение мыши должны привести к следующему поведению:

  1. Красная точка перемещается по окружности (даже если мышь не остается точно на ней).
  2. Конечная точка линии на круге следует за красной точкой.
  3. Число, показанное где-то еще на странице, увеличивается или уменьшается в зависимости от величины углового смещения.

Я нашел в Интернете демонстрацию, которая позволяет перетаскивать круг svg по всей странице, связывая элементы интересующие события mousedown и mouseup и перезапись атрибута cx и cy круга в текущее положение мыши.

Однако при тестировании кода на jsfiddle с моим примером (или даже с исходным кодом) что-то не работает. Не могли бы вы посмотреть и дать мне совет, что может быть не так?


person Matteo    schedule 27.01.2016    source источник
comment
@Dominik - Спасибо за предложение, но по причинам, которые я не указал в вопросе, я не могу просто повернуть тег svg. Он должен следовать объясненным принципам.   -  person Matteo    schedule 27.01.2016


Ответы (1)


Мне удалось найти решение моего вопроса (благодаря другу) и опубликовать его в качестве ссылки для других:

Основная проблема со вставкой кода из этой демонстрации в Интернете в jsfiddle заключается в следующем. что порядок, в котором JavaScript библиотеки и функции, непредсказуем.

Таким образом, некоторая привязка может быть вызвана до того, как будет определена связанная функция. Кроме того, код из демо более сложен, чем мне нужно.

  • Вот решение кода на jsfiddle
  • Ниже приведен рабочий фрагмент для сайта SO.

var dragging = false

var updateGraphics = function (e) {
	if (dragging) {
  
    var parentOffset = $('#wheel').offset(); 
    var relX = e.pageX - parentOffset.left;
    var relY = e.pageY - parentOffset.top;
  
    var cx = +$('#circle').attr('cx')
    var cy = +$('#circle').attr('cy')
    var r = +$('#circle').attr('r')
    var dx = relX - cx
    var dy = relY - cy
    //var dx = e.clientX - cx
    //var dy = e.clientY - cy
 
    console.debug('cx: ' + cx);
    console.debug('cy: ' + cy);
    console.debug('dx: ' + dx);
    console.debug('dy: ' + dy);

    console.debug('clientX: ' + e.clientX);
    console.debug('clientY: ' + e.clientY);
  
    console.debug('relX: ' + relX);
    console.debug('relY: ' + relY);
  
    var a = Math.atan2(dy, dx)
    var dotX = cx + r * Math.cos(a)
    var dotY = cy + r * Math.sin(a)
    $('#dot').attr('cx', dotX);
    $('#dot').attr('cy', dotY);
    $('#line_2').attr('x2', dotX);
    $('#line_2').attr('y2', dotY);
  }
}

$('svg').on('mousedown', function (e) {
	dragging = true
	updateGraphics(e)
})

$('svg').on('mouseup', function (e) {
	dragging = false
})

$('svg').on('mousemove', updateGraphics)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg id="wheel" width="200" height="175" style="background-color:lightgreen;">
<circle id="circle" cx="100" cy="85" r="75" stroke="black" stroke-width="2" fill="lightgray"/>
<line id="line_1" x1="100" y1="85" x2="100" y2="160" stroke-dasharray="15,15" style="stroke:rgb(255,0,0);stroke-width:2"/>
<line id="line_2" x1="100" y1="85" x2="100" y2="160" style="stroke:rgb(0,0,255);stroke-width:2"/>
<circle id="dot" cx="100" cy="160" r="10" stroke="black" stroke-width="2" fill="red"/>
</svg>

person Matteo    schedule 29.01.2016