javascript - 使用绿色 socks 将旋钮拖动到 360 度

标签 javascript jquery svg gsap

我正在尝试使用绿色 socks 库将圆形旋钮从 0 度拖动到 360 度。 在下面添加一个代码笔,其中我使用了 bounds 属性,该属性将拖动旋转从 0 度限制到 359 度,但是因此当我开始从最后一个象限(270 到 360 度之间)拖动时,拖动跳转到第一象限(0 度) ) 并从 0 度开始拖动。在第 1、2 和 3 象限中,阻力工作正常,但第 4 象限有一些问题。 我想保持边界,但如果我在 270 到 360 度之间拖动,我也想拖动。请查看代码笔并帮助我解决这个问题。谢谢。

重现步骤 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

* 已更新 * 如果将来有人来检查类似问题,我已经用工作解决方案更新了上面的代码笔链接。谢谢。

最佳答案

您使用 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()

关于javascript - 使用绿色 socks 将旋钮拖动到 360 度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55063586/

相关文章:

jquery - 当 jQuery 事件表达式中有一个点时,它的含义是什么

javascript - 我的内联 SVG 和嵌入式 SVG 存在问题

javascript - 将 div 直接放在页脚上方

javascript - 在javascript中真的需要提升来启用相互递归吗?

javascript - sails.js 模糊错误信息。使用 xmlHttpRequest()

javascript - 封装 jQuery 函数并将它们添加到全局命名空间

javascript - 随机幻灯片仅在超过两张幻灯片时才有效

svg - 在@font-face 中使用 SVG 字体而不是 TTF/EOT 有什么好处?

css - 可以在 SVG 属性上使用 CSS 转换吗?就像一条线上的 y2?

javascript - 如何测试表情符号在discord.js 中是否有动画