Javascript 如何计算外接矩形的圆的大小?

Javascript 如何计算外接矩形的圆的大小?,javascript,html,material-design,Javascript,Html,Material Design,我试图重现此处显示的材料涟漪效应: 我创建了一个按钮(一个高度为36px;和填充为0 16px;)的元素(其中也有一些文本),并实现了一个算法,根据用户的点击位置计算涟漪的位置,以及另一个算法,以找到涟漪效应的最小可能大小(矩形的对角线长度。如果用户直接单击按钮中心,则将应用此测量) 用户单击的位置格式为左侧像素(PosX)和顶部像素(PosY) 我似乎搞不懂的是,当用户点击矩形内的任何给定点时,如何计算圆的直径。例如,假设我们有一个30像素乘以40像素的矩形。如果用户直接点击矩形的中心(Pos

我试图重现此处显示的材料涟漪效应:

我创建了一个按钮(一个高度为36px;和
填充为0 16px;
)的元素(其中也有一些文本),并实现了一个算法,根据用户的点击位置计算涟漪的位置,以及另一个算法,以找到涟漪效应的最小可能大小(矩形的对角线长度。如果用户直接单击按钮中心,则将应用此测量)

用户单击的位置格式为左侧像素(PosX)和顶部像素(PosY)

我似乎搞不懂的是,当用户点击矩形内的任何给定点时,如何计算圆的直径。例如,假设我们有一个30像素乘以40像素的矩形。如果用户直接点击矩形的中心(
PosX:15
PosY:20
),创建的波纹将具有50px的高度和宽度,并且将位于矩形的中心,完美地覆盖整个形状

但是,如果用户点击向左和向上一点,比如说,用户点击
PosX:10
PosY:12
。找到涟漪中心的位置相当容易:

ripple.style.left = PosX - rippleSize / 2 + "px";
ripple.style.top = PosY - rippleSize / 2 + "px";
但是当用户单击
PosX:10
PosY:12
时,如何找到rippleSize?

我希望我在这里包含了足够的信息。如果你需要更多信息,请告诉我

以下是我迄今为止的工作:


编辑:我想象它看起来像某种径向梯度,从中心开始,将确定圆的比例(最小尺寸,用户在正中心单击,为
transform:scale(1)
,最大尺寸,用户单击其中一个角,为
transform:scale)(2) 
。我不确定这是否有帮助,但我决定添加它以防万一。

就整体公式而言,要获得比例因子,可以执行以下操作:

D = button diagonal length
C = distance from click to button center

scale = (((((D / 2) - C) / (D / 2)) - 1) * -1) + 1
这将产生一个介于
1
2
之间的结果。您需要计算单击与按钮中心之间的距离,该距离应与您计算按钮对角线长度的方式类似


或者,您可以使圆的半径等于按钮的对角线长度,然后不必担心根据单击位置调整其大小。

对于整个公式,要获得比例因子,您可以执行以下操作:

D = button diagonal length
C = distance from click to button center

scale = (((((D / 2) - C) / (D / 2)) - 1) * -1) + 1
这将产生一个介于
1
2
之间的结果。您需要计算单击与按钮中心之间的距离,该距离应与您计算按钮对角线长度的方式类似


或者,您可以使圆的半径等于按钮的对角线长度,然后不必担心根据单击位置调整其大小。

正如@Jonathan在评论中提到的,这可以通过为
rippleSize
设置一个常量值来实现。但这可能不会产生所需的效果这是一个简单的方法:

let x = PosX, y = PosY, h = buttonHeight, w = buttonWidth;
let rippleSize = Math.sqrt( Math.max( x*x + y*y , x*x + (h-y)*(h-y),
                                  (x-w)*(x-w) + (h-y)*(h-y), (w-x)*(w-x) + h*h));
这里我只计算每个角的距离,取其中最大的值。如果你愿意,这个逻辑可以很容易地抽象成一个函数

function distance(x1,y1,x2,y2){
    return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}

let rippleSize = Math.max(distance(0,0,x,y),distance(0,h,x,y),
                          distance(w,0,x,y),distance(w,h,x,y));

正如@Jonathan在评论中提到的,这可以通过为
rippleSize
设置一个常量值来实现。但这可能不会产生所需的效果。下面是一个简单的方法:

let x = PosX, y = PosY, h = buttonHeight, w = buttonWidth;
let rippleSize = Math.sqrt( Math.max( x*x + y*y , x*x + (h-y)*(h-y),
                                  (x-w)*(x-w) + (h-y)*(h-y), (w-x)*(w-x) + h*h));
这里我只计算每个角的距离,取其中最大的值。如果你愿意,这个逻辑可以很容易地抽象成一个函数

function distance(x1,y1,x2,y2){
    return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}

let rippleSize = Math.max(distance(0,0,x,y),distance(0,h,x,y),
                          distance(w,0,x,y),distance(w,h,x,y));

我看了材料波纹效应,在我看来,初始圆直径是恒定的,并且完全取决于矩形尺寸,而不是单击位置。我看了材料波纹效应,在我看来,初始圆直径是恒定的,并且完全取决于矩形尺寸,而不是单击位置假释。