Javascript 知道绿点的坐标后,使用输入在红点周围滚动它

Javascript 知道绿点的坐标后,使用输入在红点周围滚动它,javascript,html,css,svg,smil,Javascript,Html,Css,Svg,Smil,请告诉我如何实现围绕红点的旋转 我知道我需要计算坐标,但不幸的是我还不能实现它:( (角度/度) 让输入=文档查询选择器(“输入项”); 设circlePoint=()=>{ 如果(输入值>=0){ 设圆=文档查询选择器(“.\U 02\U-profile圆”), getValueCircleCX=(parseInt(“225”)+parseInt(input.value)).toString(), getValueCircleCY=(parseInt(“38.0”)+parseInt(inp

请告诉我如何实现围绕红点的旋转

我知道我需要计算坐标,但不幸的是我还不能实现它:(


(角度/度)
让输入=文档查询选择器(“输入项”);
设circlePoint=()=>{
如果(输入值>=0){
设圆=文档查询选择器(“.\U 02\U-profile圆”),
getValueCircleCX=(parseInt(“225”)+parseInt(input.value)).toString(),
getValueCircleCY=(parseInt(“38.0”)+parseInt(input.value)).toString();
circle.setAttribute(“cx”,getValueCircleCX);
circle.setAttribute(“cy”,getValueCircleCY);
控制台日志(“值>0”);

}else if(input.value如果您只想在用户每次更改输入值时触发一次事件,那么您只需要将事件侦听器附加到输入更改事件,并在每次发生时触发您的函数

input.addEventListener('change', circlePoint);
完整的演示和代码如下:

注:两个子功能取自:

有关路径字符串的详细信息:


更新-尝试在不使用setInterval的情况下仅使用SMIL进行更新

这是一个挑战,但我得到了-

HTML:


(角度/度)
JS:

const input=document.querySelector(“.input项”);
常量arc1=document.getElementById(“arc1”);
常量animate_arc=arc1.querySelector(“animate”);
const circle=document.querySelector(“.\U 02\U-profile circle”);
const animateM_circ=circle.querySelector(“animateMotion”);
常数圆点=(度=0)=>{
//console.log(“输入已更改”);
如果(度==360){
返回描述符c(2502502000359.9)。连接(“”);
}否则如果(度>=0){
返回描述符C(250,250,200,0,度)。连接(“”);
}否则,如果(度=0?1:-1;
如果(最终学位==0){
圆点(0);
}否则{
如果(方向==1和最终角度>360){
目标=最终_度-360;
}如果(方向==-1&&final_度<-360){
目标=(-360)-最终_度;
}否则{
目标=最终学位;
}  
//timeInterval=setInterval(myTimer,10);
circle.setAttribute(“cx”,0);
circle.setAttribute(“cy”,0);
如果(目标>0){
animateM_circ.setAttribute(“关键点”,“1;0”);
animateM_circ.setAttribute(“关键时刻”,“0;1”);
}否则{
animateM_circ.setAttribute(“关键点”、“0;1”);
animateM_circ.setAttribute(“关键时刻”,“0;1”);
}
const dur=Math.ceil(Math.abs(target)/100,1);
animateM_circ.setAttribute(“dur”,dur+“s”);
animateM_circ.setAttribute(“路径”,圆点(目标));
animateM_circ.beginElement();
动画_弧.setAttribute(“dur”,dur+“s”);
//动画_弧.setAttribute(“从”,圆圈点(0));
//动画_arc.setAttribute(“到”,圆圈点(目标));
让值_list=[];
for(设i=0;i<360;i++){
数值列表推送(圆点(i*(目标/360));
}
动画_弧.setAttribute(“值”,值_列表.join(“;”);
设置_arc.beginElement()的动画;
}
}
input.addEventListener('change',(e)=>myStartFunction(e.target.value));

如果这对您来说并不困难,请演示如何实现。仅在没有设定间隔的情况下在圆形轨道上从0旋转到360度。使用输入进行更改。更新了答案和演示:-我认为这就是您要求的,对吗?更新-尝试在没有设定间隔的情况下仅使用SMIL进行操作这有点困难ge但我明白了-嗨,Alex.M,我的回答解决了你的问题吗?-我们也可以使用SMIL或CSS动画来设置orbit/path.UPDATE的动画-尝试在不使用setInterval的情况下仅使用SMIL来实现这一点,这有点困难,但我明白了-
input.addEventListener('change', circlePoint);
const input = document.querySelector( ".input-item" );
const circlePoint = () => {
  console.log("input changed");
  if ( input.value >= 0 ) {

    let circle = document.querySelector("._02_U-Profil circle"),
        getValueCircleCX = ( parseInt( "225" ) + parseInt( input.value )).toString(),
        getValueCircleCY = ( parseInt( "38.0" ) + parseInt( input.value )).toString();
    circle.setAttribute( "cx", getValueCircleCX );
    circle.setAttribute( "cy", getValueCircleCY );
    console.log( "value > 0" );

  } else if ( input.value <= 0 ) {

    let circle = document.querySelector("._02_U-Profil circle"),
        getValueCircleCX = -parseInt( "225" ) - parseInt( input.value ),
        getValueCircleCY = -parseInt( "38.0" ) + parseInt( input.value );
    circle.setAttribute( "cx", getValueCircleCX.toString().split("-")[1] );
    circle.setAttribute( "cy", getValueCircleCY.toString().split("-")[1] );
    console.log( "value < 0" );

  }
};

input.addEventListener('change', circlePoint);
const input = document.querySelector( ".input-item" );
const circlePoint = (degree = 0) => {
  console.log("input changed");
  if ( degree >= 0 ) {
    const d = describeArc(250, 250, 200, 0, degree);
    let circle = document.querySelector("._02_U-Profil circle"),
        getValueCircleCX = d[1],
        getValueCircleCY = d[2];
    circle.setAttribute( "cx", getValueCircleCX );
    circle.setAttribute( "cy", getValueCircleCY );
    console.log( "value >= 0", d.join(" ") );
    document.getElementById("arc1").setAttribute("d", d.join(" "));

  } else if ( degree <= 0 ) {
    const d = describeArc(250, 250, 200, degree, 0);
    let circle = document.querySelector("._02_U-Profil circle"),
        getValueCircleCX = d[9],
        getValueCircleCY = d[10];
    circle.setAttribute( "cx", getValueCircleCX );
    circle.setAttribute( "cy", getValueCircleCY );
    console.log( "value < 0", d.join(" ") );
    document.getElementById("arc1").setAttribute("d", d.join(" "));

  }
};

//polarToCaresian taken from: https://stackoverflow.com/a/18473154/9792594
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

//describeArc taken from: https://stackoverflow.com/a/18473154/9792594
function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ]; //.join(" ");

    return d;       
}

var timeInterval; //to be started at a later time
var progress; //to track progress of the animation
var target; //to clearInterval at the end
var direction; //to track direction (clock- or anti-clockwise)
var speed = 1; //custom speed of the animation

function myStopFunction() {
  console.log("stop", progress);
  clearInterval(timeInterval);
}

function myStartFunction(final_degree) {
  progress = 0;
  direction = final_degree >= 0 ? 1 : -1;
  if (final_degree == 0) {
    circlePoint(0);
  } else {    
    if (direction == 1 && final_degree > 360){
      target = final_degree - 360;
    } else if (direction == -1 && final_degree < -360){    
      target = (-360) - final_degree;
    } else {
      target = final_degree;
    }  
    timeInterval = setInterval(myTimer, 10);
  }
}

function myTimer(){
  if ( Math.abs(progress) >= Math.abs(target) ) {
    myStopFunction();
  } else {
    progress += (speed * direction);
    circlePoint(progress);
  }  
}

input.addEventListener('change', (e) => myStartFunction(e.target.value));
<label class="label-input resize-width" style="width: 100%; margin: 0 0 30px;">
<span>( Angle / Degree )</span>
<input class="input-item" type="number" style="width: 100%;" value="0"/>
</label>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="500" width="500">
    <g id="_02_U-Profil" class="_02_U-Profil">
        <path id="arc1" fill="none" stroke="#446688" stroke-width="10">
          <animate attributeName="d" dur="5s" repeatCount="1" begin="indefinite" fill="freeze">
          </animate>
        </path>
        <circle cx="250" cy="50" r="5" fill="lightGreen">
          <animateMotion dur="5s" repeatCount="1" begin="indefinite" fill="freeze" keyPoints="1;0" keyTimes="0;1" calcMode=linear>
          </animateMotion>
        </circle>
        <circle cx="250" cy="250" r="5" fill="red">          
        </circle>
    </g>
</svg>
const input = document.querySelector( ".input-item" );
const arc1 = document.getElementById("arc1");
const animate_arc = arc1.querySelector( "animate" );
const circle = document.querySelector("._02_U-Profil circle");
const animateM_circ = circle.querySelector( "animateMotion" );
const circlePoint = (degree = 0) => {
  //console.log("input changed");
  if ( degree == 360 ) {
    return describeArc(250, 250, 200, 0, 359.9).join(' ');    
  } else if ( degree >= 0 ) {
    return describeArc(250, 250, 200, 0, degree).join(' ');    
  } else if ( degree <= 0 ) {
    return describeArc(250, 250, 200, degree, 0).join(' ');    
  }
};

function polarToCartesian(centerX, centerY, radius, angleInDegrees){
...
}
function describeArc(x, y, radius, startAngle, endAngle){
...
}

...

function myStartFunction(final_degree) {
  progress = 0;
  direction = final_degree >= 0 ? 1 : -1;
  if (final_degree == 0) {
    circlePoint(0);
  } else {    
    if (direction == 1 && final_degree > 360){
      target = final_degree - 360;
    } else if (direction == -1 && final_degree < -360){    
      target = (-360) - final_degree;
    } else {
      target = final_degree;
    }  
    //timeInterval = setInterval(myTimer, 10);
    circle.setAttribute("cx", 0);
    circle.setAttribute("cy", 0);
    if (target > 0){
      animateM_circ.setAttribute("keyPoints", "1;0");
      animateM_circ.setAttribute("keyTimes", "0;1");
    } else{
      animateM_circ.setAttribute("keyPoints", "0;1");
      animateM_circ.setAttribute("keyTimes", "0;1");     
    }
    const dur = Math.ceil(Math.abs(target)/100,1);
    animateM_circ.setAttribute("dur", dur + "s");
    animateM_circ.setAttribute("path", circlePoint(target));
    animateM_circ.beginElement();
    animate_arc.setAttribute("dur", dur + "s");
    // animate_arc.setAttribute("from", circlePoint(0));
    // animate_arc.setAttribute("to", circlePoint(target));
    let values_list = [];
    for (let i = 0; i < 360; i++){
      values_list.push(circlePoint(i * (target/360)));
    }
    animate_arc.setAttribute("values", values_list.join('; '));
    animate_arc.beginElement();    
  }
}

input.addEventListener('change', (e) => myStartFunction(e.target.value));