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