如何计算外接矩形的圆的大小?
How can I calculate the size of a circle which is circumscribing a rectangle?
我正在尝试重新创建此处显示的 Material 涟漪效应:https://material.angular.io/components/ripple/examples
我创建了一个按钮(一个带有 height: 36px;
和 padding: 0 16px;
的元素(其中也有一些文本)并实现了一种算法来根据用户的点击位置计算涟漪的位置,以及另一种算法,用于找到波纹效应的最小可能尺寸(矩形的对角线长度。如果用户直接单击按钮的中心,则会应用此测量)。
用户点击的位置被格式化为从左边开始的像素 (PosX) 和从顶部开始的像素 (PosY)。
PosX: 27
PosY: 16
我似乎无法弄清楚的是,当用户单击矩形内的任何给定点时,如何计算圆的直径。例如,假设我们有一个 30 像素 x 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?
我希望我在这里提供了足够的信息。如果您需要更多信息,请告诉我。
这是我目前的工作:https://codepen.io/BlackKnightNick/pen/abNmZbz
编辑: 我想象它看起来像某种从中心开始的径向渐变,它将决定圆的比例(最小尺寸,用户点击最中心的是 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
之间的结果。您需要计算点击与按钮中心之间的距离,这应该与您计算按钮对角线长度的方式类似。
或者,您可以使圆的半径等于按钮的对角线长度,这样就不必担心根据点击位置调整它的大小了。
正如@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));
我正在尝试重新创建此处显示的 Material 涟漪效应:https://material.angular.io/components/ripple/examples
我创建了一个按钮(一个带有 height: 36px;
和 padding: 0 16px;
的元素(其中也有一些文本)并实现了一种算法来根据用户的点击位置计算涟漪的位置,以及另一种算法,用于找到波纹效应的最小可能尺寸(矩形的对角线长度。如果用户直接单击按钮的中心,则会应用此测量)。
用户点击的位置被格式化为从左边开始的像素 (PosX) 和从顶部开始的像素 (PosY)。
PosX: 27
PosY: 16
我似乎无法弄清楚的是,当用户单击矩形内的任何给定点时,如何计算圆的直径。例如,假设我们有一个 30 像素 x 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?
我希望我在这里提供了足够的信息。如果您需要更多信息,请告诉我。
这是我目前的工作:https://codepen.io/BlackKnightNick/pen/abNmZbz
编辑: 我想象它看起来像某种从中心开始的径向渐变,它将决定圆的比例(最小尺寸,用户点击最中心的是 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
之间的结果。您需要计算点击与按钮中心之间的距离,这应该与您计算按钮对角线长度的方式类似。
或者,您可以使圆的半径等于按钮的对角线长度,这样就不必担心根据点击位置调整它的大小了。
正如@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));