使用绿色袜子将旋钮拖动到360度

时间:2019-03-08 12:49:07

标签: javascript jquery svg greensock

我正在尝试使用绿色袜子库将圆形旋钮从0拖动到360度。 在下面添加一个codepen,在其中使用了bounds属性,该属性将拖动旋转从0限制到359度,但是由于这个原因,当我开始从最后一个象限(270到360度之间)拖动时,拖动会跳到第一个象限(0度) ),然后从0度开始拖动。在第一,第二和第三象限中,拖动正常工作,但第四象限存在一些问题。 我想保持边界,但是如果我在270至360度之间拖动,我也想拖动。请看一下Codepen,并帮我解决这个问题。谢谢。

复制步骤 1.拖动直到最后一个象限(介于270度到360度之间),类似于9-12点之间的时钟,然后离开鼠标。

  1. 从鼠标左键的最后一个象限按一下,在这里您可以看到拖动从0度开始。

var rotationOffset = 90, //in case the dial's "home" position isn't at 0 degrees (pointing right). In this case, we use 90 degrees.
  RAD2DEG = 180 / Math.PI, //for converting radians to degrees
  adjusting;

TweenLite.set("#spinner", {
  transformOrigin: "center"
});

Draggable.create("#spinner", {
  type: "rotation",
  sticky: true,
  bounds: {
    minRotation: 0,
    maxRotation: 359,
  },
  trigger: "#svg",
  onPress: function(e) {
    if (!adjusting) {
      //figure out the angle from the pointer to the rotational origin (in degrees)
      var rotation = Math.atan2(this.pointerY - this.rotationOrigin.y, this.pointerX - this.rotationOrigin.x) * RAD2DEG;
      //set the rotation (with any offset that's necessary)
      TweenLite.set(this.target, {
        rotation: rotation + rotationOffset
      });
      //now we'll end the drag and start it again from this new place, but when we start again, it'll call the onPress of course so to avoid an endless loop, we use the "adjusting" variable to skip it in the triggered onPress.
      adjusting = true;
      this.endDrag(e);
      this.startDrag(e);
      adjusting = false;
    }
  },
  onDrag: function() {
    var rotation = Math.atan2(this.pointerY - this.rotationOrigin.y, this.pointerX - this.rotationOrigin.x) * RAD2DEG;
    $("#percent").text(rotation.toFixed(2))
  }
});
#svg {
  position: fixed;
  width: 100%;
  height: 100%;
  touch-action: none;
}

#spinner {
  cursor: pointer;
}

.big-circle {
  fill: dodgerblue;
  stroke: black;
  stroke-width: 6;
}

.small-circle {
  fill: black;
}

.line {
  fill: none;
  stroke: black;
  stroke-width: 6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/utils/Draggable.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.min.js"></script>
<div id="percent">0</div>
<svg id="svg" viewBox="0 0 1000 1000">
  <g id="spinner">
    <circle class="big-circle" cx="500" cy="500" r="200" />
    <circle class="small-circle" cx="500" cy="500" r="12" />
    <polyline class="line" points="500,500 500,300" />
  </g>
</svg>

codepen of knob

*更新* 如果以后有人来检查类似的问题,我已经使用工作解决方案更新了上述Codepen链接。谢谢。

1 个答案:

答案 0 :(得分:0)

为什么使用boundstrigger参数? 如果删除它们,您的代码将相应地起作用。

var rotationOffset = 90, //in case the dial's "home" position isn't at 0 degrees (pointing right). In this case, we use 90 degrees.
	RAD2DEG = 180 / Math.PI, //for converting radians to degrees
	adjusting;

TweenLite.set("#spinner", {transformOrigin: "center"});

Draggable.create("#spinner", {
  type: "rotation",
  sticky: true,
  /*bounds: {
    minRotation: 0,
    maxRotation: 360,
  },
  trigger: "#svg",*/
	onPress: function(e) {
		if (!adjusting) {
			//figure out the angle from the pointer to the rotational origin (in degrees)
			var rotation = Math.atan2(this.pointerY - this.rotationOrigin.y, this.pointerX - this.rotationOrigin.x) * RAD2DEG;
			//set the rotation (with any offset that's necessary)
			TweenLite.set(this.target, {rotation:rotation + rotationOffset});
			//now we'll end the drag and start it again from this new place, but when we start again, it'll call the onPress of course so to avoid an endless loop, we use the "adjusting" variable to skip it in the triggered onPress.
			adjusting = true;
			this.endDrag(e);
			this.startDrag(e);
			adjusting = false;
		}
	},
  onDrag: function(){
    var rotation = Math.atan2(this.pointerY - this.rotationOrigin.y, this.pointerX - this.rotationOrigin.x) * RAD2DEG;
    
  }
});
#svg {
  position: fixed;
  width: 100%;
  height: 100%;
	touch-action: none;
  
}

#spinner {
  cursor: pointer;
}

.big-circle {
  fill: dodgerblue;
  stroke: black;
  stroke-width: 6;
}

.small-circle {
  fill: black;
}

.line {
  fill: none;
  stroke: black;
  stroke-width: 6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/utils/Draggable.min.js"></script>
<div id="percent">0</div>
<svg id="svg" viewBox="0 0 1000 1000">
  <g id="spinner">
    <circle class="big-circle" cx="500" cy="500" r="200" />
    <circle class="small-circle" cx="500" cy="500" r="12" />
    <polyline class="line" points="500,500 500,300" />
  </g>
</svg>

https://greensock.com/docs/Utilities/Draggable/static.create()