Javascript Paintcode和Snap-SVG

Javascript Paintcode和Snap-SVG,javascript,canvas,svg,snap.svg,paintcode,Javascript,Canvas,Svg,Snap.svg,Paintcode,我试图从和中找到一些例子 是一个简单的项目,当拖动滑块时,齿轮会旋转。这是伟大的,但我想做的互动与鼠标代替 这是齿轮作为svg的一个示例: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="h

我试图从和中找到一些例子

是一个简单的项目,当拖动滑块时,齿轮会旋转。这是伟大的,但我想做的互动与鼠标代替

这是齿轮作为svg的一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="240" height="200"  xml:space="preserve" id="gears">
    <!-- Generated by PaintCode - http://www.paintcodeapp.com -->
    <path id="gears-largeGear" stroke="none" fill="rgb(69, 131, 212)" d="M 2.78,-67.94 C 3.71,-63.88 4.74,-59.43 5.59,-55.72 7.73,-55.51 9.84,-55.18 11.9,-54.73 13.87,-58 16.21,-61.91 18.36,-65.49 20.15,-64.99 21.91,-64.42 23.64,-63.78 23.27,-59.62 22.87,-55.08 22.54,-51.28 24.5,-50.42 26.4,-49.45 28.23,-48.37 31.11,-50.87 34.55,-53.87 37.69,-56.6 39.24,-55.58 40.73,-54.49 42.18,-53.34 40.55,-49.5 38.77,-45.3 37.28,-41.79 38.87,-40.37 40.37,-38.87 41.79,-37.28 45.3,-38.77 49.5,-40.55 53.34,-42.18 54.49,-40.73 55.58,-39.24 56.6,-37.69 53.87,-34.55 50.87,-31.11 48.37,-28.23 49.45,-26.4 50.42,-24.5 51.28,-22.54 55.08,-22.87 59.62,-23.27 63.78,-23.64 64.42,-21.91 64.99,-20.15 65.49,-18.36 61.91,-16.21 58,-13.87 54.73,-11.9 55.18,-9.84 55.51,-7.73 55.72,-5.59 59.43,-4.74 63.88,-3.71 67.94,-2.78 67.98,-1.86 68,-0.93 68,0 68,0.93 67.98,1.86 67.94,2.78 63.88,3.71 59.43,4.74 55.72,5.59 55.51,7.73 55.18,9.84 54.73,11.9 58,13.87 61.91,16.21 65.49,18.36 64.99,20.15 64.42,21.91 63.78,23.64 59.62,23.27 55.08,22.87 51.28,22.54 50.42,24.5 49.45,26.4 48.37,28.23 50.87,31.11 53.87,34.55 56.6,37.69 55.58,39.24 54.49,40.73 53.34,42.18 49.5,40.55 45.3,38.77 41.79,37.28 40.37,38.87 38.87,40.37 37.28,41.79 38.77,45.3 40.55,49.5 42.18,53.34 40.73,54.49 39.24,55.58 37.69,56.6 34.55,53.87 31.11,50.87 28.23,48.37 26.4,49.45 24.5,50.42 22.54,51.28 22.87,55.08 23.27,59.62 23.64,63.78 21.91,64.42 20.15,64.99 18.36,65.49 16.21,61.91 13.87,58 11.9,54.73 9.84,55.18 7.73,55.51 5.59,55.72 4.74,59.43 3.71,63.88 2.78,67.94 1.86,67.98 0.93,68 -0,68 -0.93,68 -1.86,67.98 -2.78,67.94 -3.71,63.88 -4.74,59.43 -5.59,55.72 -7.73,55.51 -9.84,55.18 -11.9,54.73 -13.87,58 -16.21,61.91 -18.36,65.49 -20.15,64.99 -21.91,64.42 -23.64,63.78 -23.27,59.62 -22.87,55.08 -22.54,51.28 -24.5,50.42 -26.4,49.45 -28.23,48.37 -31.11,50.87 -34.55,53.87 -37.69,56.6 -39.24,55.58 -40.73,54.49 -42.18,53.34 -40.55,49.5 -38.77,45.3 -37.28,41.79 -38.87,40.37 -40.37,38.87 -41.79,37.28 -45.3,38.77 -49.5,40.55 -53.34,42.18 -54.49,40.73 -55.58,39.24 -56.6,37.69 -53.87,34.55 -50.87,31.11 -48.37,28.23 -49.45,26.4 -50.42,24.5 -51.28,22.54 -55.08,22.87 -59.62,23.27 -63.78,23.64 -64.42,21.91 -64.99,20.15 -65.49,18.36 -61.91,16.21 -58,13.87 -54.73,11.9 -55.18,9.84 -55.51,7.73 -55.72,5.59 -59.43,4.74 -63.88,3.71 -67.94,2.78 -67.98,1.86 -68,0.93 -68,-0 -68,-0.93 -67.98,-1.86 -67.94,-2.78 -63.88,-3.71 -59.43,-4.74 -55.72,-5.59 -55.51,-7.73 -55.18,-9.84 -54.73,-11.9 -58,-13.87 -61.91,-16.21 -65.49,-18.36 -64.99,-20.15 -64.42,-21.91 -63.78,-23.64 -59.62,-23.27 -55.08,-22.87 -51.28,-22.54 -50.42,-24.5 -49.45,-26.4 -48.37,-28.23 -50.87,-31.11 -53.87,-34.55 -56.6,-37.69 -55.58,-39.24 -54.49,-40.73 -53.34,-42.18 -49.5,-40.55 -45.3,-38.77 -41.79,-37.28 -40.37,-38.87 -38.87,-40.37 -37.28,-41.79 -38.77,-45.3 -40.55,-49.5 -42.18,-53.34 -41.55,-53.84 -40.91,-54.33 -40.26,-54.81 -39.42,-55.43 -38.56,-56.03 -37.69,-56.6 -34.55,-53.87 -31.11,-50.87 -28.23,-48.37 -26.4,-49.45 -24.5,-50.42 -22.54,-51.28 -22.87,-55.08 -23.27,-59.62 -23.64,-63.78 -21.91,-64.42 -20.15,-64.99 -18.36,-65.49 -16.21,-61.91 -13.87,-58 -11.9,-54.73 -9.84,-55.18 -7.73,-55.51 -5.59,-55.72 -4.74,-59.43 -3.71,-63.88 -2.78,-67.94 -1.93,-67.98 -1.08,-68 -0.23,-68 L 0,-68 C 0.93,-68 1.86,-67.98 2.78,-67.94 Z M 0,-36 C -6.22,-36 -12.07,-34.42 -17.18,-31.65 -28.39,-25.55 -36,-13.66 -36,-0 -36,19.88 -19.88,36 0,36 19.88,36 36,19.88 36,-0 36,-19.88 19.88,-36 0,-36 Z M 0,-36" transform="translate(150, 96) rotate(-0.5)"  />
    <path id="gears-smallGear" stroke="none" fill="rgb(115, 152, 218)" d="M 2.12,-37.94 L 2.45,-37.92 C 3.29,-34.48 4.2,-30.71 4.97,-27.56 6.23,-27.34 7.46,-27.03 8.65,-26.64 9.87,-26.24 11.04,-25.77 12.18,-25.22 14.65,-27.32 17.61,-29.83 20.31,-32.12 21.69,-31.25 23.02,-30.28 24.27,-29.24 22.92,-25.96 21.45,-22.37 20.22,-19.37 21.97,-17.55 23.47,-15.49 24.68,-13.24 27.91,-13.49 31.78,-13.78 35.32,-14.05 35.92,-12.54 36.42,-10.99 36.83,-9.39 33.81,-7.53 30.5,-5.49 27.75,-3.79 27.91,-2.55 28,-1.29 28,-0 28,1.29 27.91,2.55 27.75,3.79 30.51,5.49 33.81,7.53 36.83,9.39 36.42,10.99 35.92,12.54 35.32,14.05 31.78,13.78 27.91,13.49 24.68,13.24 23.47,15.49 21.97,17.55 20.22,19.37 21.45,22.37 22.92,25.96 24.27,29.24 23.02,30.28 21.69,31.25 20.31,32.12 17.61,29.83 14.65,27.32 12.18,25.22 9.93,26.31 7.51,27.11 4.97,27.56 4.2,30.71 3.29,34.48 2.45,37.92 1.64,37.97 0.82,38 -0,38 -0.82,38 -1.64,37.97 -2.45,37.92 -3.29,34.48 -4.2,30.71 -4.97,27.56 -7.51,27.11 -9.93,26.31 -12.18,25.22 -14.65,27.32 -17.61,29.83 -20.31,32.12 -21.69,31.25 -23.02,30.28 -24.27,29.24 -22.92,25.96 -21.45,22.37 -20.22,19.37 -21.97,17.55 -23.47,15.49 -24.68,13.24 -27.91,13.49 -31.78,13.78 -35.32,14.05 -35.92,12.54 -36.42,10.99 -36.83,9.39 -33.81,7.53 -30.5,5.49 -27.75,3.79 -27.91,2.55 -28,1.29 -28,-0 -28,-1.29 -27.91,-2.55 -27.75,-3.79 -30.51,-5.49 -33.81,-7.53 -36.83,-9.39 -36.42,-10.99 -35.92,-12.54 -35.32,-14.05 -31.78,-13.78 -27.91,-13.49 -24.68,-13.24 -23.47,-15.49 -21.97,-17.55 -20.22,-19.37 -21.45,-22.37 -22.92,-25.96 -24.27,-29.24 -23.02,-30.28 -21.69,-31.25 -20.31,-32.12 -17.61,-29.83 -14.65,-27.32 -12.18,-25.22 -9.93,-26.31 -7.51,-27.11 -4.97,-27.56 -4.2,-30.71 -3.29,-34.48 -2.45,-37.92 -1.64,-37.97 -0.82,-38 0,-38 0.71,-38 1.42,-37.98 2.12,-37.94 Z M 0,-14 C -7.73,-14 -14,-7.73 -14,-0 -14,7.73 -7.73,14 0,14 7.73,14 14,7.73 14,-0 14,-5.48 10.85,-10.22 6.27,-12.52 4.38,-13.47 2.25,-14 0,-14 Z M 0,-14" transform="translate(62, 137) rotate(1)"  />
</svg>
在Javascript中进行鼠标点击测试和交互是否比使用Snap更容易?

编辑:有关改进的方法,请参见下方

首先,将变换从第2个示例中的组移动到路径可能更容易。然后,可以将任何旋转变换添加到组中,而不会变得太混乱。例如

<g id="gears-largeGroup"  >
    <path transform="translate(149.59, 96.41)" id="gears-largeGear"..... 
现在我们有了装备,我们可以给它添加一个拖动处理程序

Snap.select('#gears-smallGroup').drag( dragRotate, dragStart )
所以我们只需要编写我们的处理程序。首先,我们希望将drag的开始部分存储在末尾,请参见更新后的解决方案,这样更好,这样我们就可以编写startRotate函数。这只是在元素旁边存储一个x,y对象

function dragRotateStart( x, y ) {
  this.data('oxy', { x: x, y: y })
}
function dragRotateStart(x, y) {
  this.data('startingAngle', Snap.angle(this.getBBox().cx, this.getBBox().cy, x, y));
  this.data('startingRotation', this.data('rotation')||10)
}
然后我们可以编写主拖动旋转处理程序。 这将获取上面存储的原始起始位置oxy,并将其添加到经过的阻力增量增量中

然后使用捕捉角度法计算两点之间的角度。一个是我们刚刚得到的x,y,另一个是元素的中心

现在我们有了角度,我们可以做一个旋转变换。“捕捉”可以对变换使用缩写形式r=旋转、t=平移、s=缩放,除非指定,否则使用“捕捉”的r&s将从其中心进行变换

这就变成了

function dragRotate( dx, dy, x, y ) {
  this.transform('r' + Snap.angle( this.getBBox().cx, this.getBBox().cy, dx + this.data('oxy').x, dy + this.data('oxy').y ) );
}
所以整个代码

Snap.select('#gears-smallGroup').drag( dragRotate, dragRotateStart )  
Snap.select('#gears-largeGroup').drag( dragRotate, dragRotateStart ) 

function dragRotate( dx, dy, x, y ) {
  this.transform('r' + Snap.angle( this.getBBox().cx, this.getBBox().cy, dx + this.data('oxy').x, dy + this.data('oxy').y ) );
}

function dragRotateStart( x, y ) {
  this.data('oxy', { x: x, y: y })
}
现在你有了这个,你可以摆弄它,这样一个可以旋转另一个。根据新拖动从何处开始,您可能还必须在重新绘制后检查起点

快速使较小的齿轮旋转较大的齿轮

更新和改进版本:

进一步扩展,您需要调整它,同时考虑开始旋转(如果它已预旋转)和拖动中的开始角度,我们只需要角度差异,因此不会重置

所以我们可以存储起始位。当图像点偏移约10度时,我将默认值设置为10,此时拖动的开始角度是多少。元素的旧旋转是什么

function dragRotateStart( x, y ) {
  this.data('oxy', { x: x, y: y })
}
function dragRotateStart(x, y) {
  this.data('startingAngle', Snap.angle(this.getBBox().cx, this.getBBox().cy, x, y));
  this.data('startingRotation', this.data('rotation')||10)
}
然后从开始旋转开始计算正确的旋转,加上角度差,在我们前进时存储它,所以如果我们稍后再次拖动,我们知道它最后的旋转是什么

function dragRotate(dx, dy, x, y) {
  var angleDiff = Snap.angle(this.getBBox().cx, this.getBBox().cy, x, y) - this.data('startingAngle')
  var newRotation = angleDiff + +this.data('startingRotation');
  this.data('rotation', newRotation)
  this.transform('r' + newRotation); 
} 

Awesome,我如何将SVG从HTML内容分离到它自己的文件中?这就是普通的Snap.load命令吗?我试过了,加载与您的示例代码配合得很好。我注意到,根据齿轮被单击的位置,旋转会有很大的跳跃。例如,如果从上一个释放点单击180度,齿轮将通过单像素拖动跳跃180度。我认为这与x,y最初是如何存储的,然后在初始拖动时应用于变换有关。是的,这是可能的,我还会再次检查一些事情,比如在360度线上进行第二次单击。这可能不相关,但通常旋转需要一些额外的检查,因为旋转在359->360->0时不是连续的。因此,基本上先检查第一个dragstart上的角度,然后检查下一个,看看是否有边缘情况使其绊倒。我只是想让你明白大部分的道理。我想你需要考虑一下你希望逻辑如何运作。例如,使用rect进行尝试可能更简单,以使其更明显。假设你把它拖45度。下一次拖动,您可能希望它是前一个角度45+拖动的一些变化,例如15。