为了账号安全,请及时绑定邮箱和手机立即绑定

计算与边界框相关的模拟时钟指针的动态长度

计算与边界框相关的模拟时钟指针的动态长度

素胚勾勒不出你 2021-10-21 11:03:25
我需要创建一个模拟时钟,动态调整一只或多只手的长度以达到边界框边界附近。时钟指针的起点不一定在边界框的中心。我需要获得起点和终点之间的距离 - 不仅仅是手与边界框边界处的 x,y。左上角的边界框内为 0,0盒子尺寸可以是例如 348x250时钟指针的起点可以位于中心 x:174, y:125 (50%,50%) 或偏离中心,例如 x:214, y:90由于手的实现方式,需要实际长度 - 不仅仅是手与边缘相交的 x,y理想情况下,我会有这样的功能:function getLength(angle) {// 0-360 degrees for rotating the hand with 0 in the top    let boxWidth = 348;//top left is 0,0    let boxHeight = 250;    let clockX = 214;// center X for the 'clock'    let clockY = 90;// center Y for the 'clock'    // start the magic here    let handlength;    ....    // end magic here    return handLength //return the actual max length for the hand}不知道如何计算。有什么帮助吗?
查看完整描述

2 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

如果要计算长度,可以使用以下函数:


// angle: 0-360. 0 = 12 o'clock, 90 = 3 o'clock, ...

// top: the distance of the center to the top side

// right: the distance of the center to the right side

// bottom: the distance of the center to the bottom side

// left: the distance of the center to the left side


function getLength(angle, top, right, bottom, left) {

    var sideToCompare1;

    var sideToCompare2;


    if (angle >= 0 && angle < 90) {

        sideToCompare1 = top;

        sideToCompare2 = right;

    }

    else if (angle >= 90 && angle < 180) {

        sideToCompare1 = right;

        sideToCompare2 = bottom;

        angle -= 90;

    }

    else if (angle >= 180 && angle < 270) {

        sideToCompare1 = bottom;

        sideToCompare2 = left;

        angle -= 180;

    }

    else {

        sideToCompare1 = left;

        sideToCompare2 = top;

        angle -= 270;

    }


    // change to radian

    angle = angle / 180 * Math.PI;


    return Math.min(sideToCompare1 / Math.cos(angle),

                    sideToCompare2 / Math.sin(angle)); //Math.cos(Math.PI / 2 - angle)

}

函数中的想法是取到时钟指针将穿过的垂直或水平边的最小距离。


通过旋转,四个象限的计算是相同的。这就是if.


注意cos(90-a) = sin(a)。这用于简化到每个象限第二边的距离。


如果你想要一个填充到盒子的边界,你可以考虑垂直于盒子侧面或手方向的填充。在第一种情况下,您只需通过所需的填充减少输入参数。在第二种情况下,只需从该函数的结果中减去填充。


查看完整回答
反对 回复 2021-10-21
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

你总是可以(从字面上)隐藏复杂性。


Math.random.between = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);


const createWeb = (el) => {

  const clock = {

    $canvas: el,

    logicalCenter: [Math.random.between(100, 400), Math.random.between(100, 400)],

    segments: 12,

  };

  clock.segmentSize = (Math.PI * 2) / clock.segments;

  clock.$canvas.width = 500;

  clock.$canvas.height = 500;

  clock.ctx = clock.$canvas.getContext('2d');

  clock.ctx.strokeStyle = 'orangered';

  clock.ctx.lineWidth = 5;

  clock.ctx.fillStyle = 'white';


  const draw = {

    arm: (atSegment) => {

      atSegment = atSegment % clock.segments;

      const degree = atSegment * clock.segmentSize;

      const handLength = clock.$canvas.width * 2;

      const [x, y] = [Math.cos(degree) * handLength, Math.sin(degree) * handLength];


      clock.ctx.beginPath();

      clock.ctx.moveTo(...clock.logicalCenter);

      clock.ctx.lineTo(x + clock.logicalCenter[0], y + clock.logicalCenter[1]);

      clock.ctx.stroke();

    },

    center: (radius) => {

      clock.ctx.beginPath();

      clock.ctx.arc(...clock.logicalCenter, radius, 0, Math.PI * 2);

      clock.ctx.stroke();

    },

    border: (thickness) => {

      const [w, h] = [clock.$canvas.width, clock.$canvas.height];

      clock.ctx.fillRect(0, 0, thickness, h);

      clock.ctx.fillRect(0, 0, w, thickness);

      clock.ctx.fillRect(0, h - thickness, w, thickness);

      clock.ctx.fillRect(w - thickness, 0, thickness, h);

    }

  };


  draw.center(10);

  Array(clock.segments).fill(0)

    .map((_, i) => i)

    .forEach(draw.arm);

  draw.border(20);

}


document.querySelectorAll('.clock').forEach(createWeb);

* {

  margin: 0;

  padding: 0;

}


.clock {

  position: relative;

  width: 200px;

  height: 200px;

  border: 3px orangered solid;

  box-sizing: border-box;

}

<canvas class="clock"></canvas>

<canvas class="clock"></canvas>

<canvas class="clock"></canvas>


查看完整回答
反对 回复 2021-10-21
  • 2 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信