Svg Blazor服务器-鼠标偏移与JS Interop配合使用,但不使用MouseEventArgs.OffsetX/OffsetY(Firefox)
我创建了一个简单的Blazor服务器应用程序来探索这项技术,并决定是否将其用于一个特定的用例,该用例涉及到让用户能够在网页上绘图 我需要知道用户点击和/或拖动的位置,因此我查阅了一些关于如何使用java脚本计算鼠标偏移量x和y的参考资料,它的功能完全符合我的预期 我最近发现在.NET5中,API中添加了“OffsetX”和“OffsetY”,因此我删除了支持这一点的Java脚本调用,现在我曾经工作的代码不再工作了。问题在于MouseEventArgs对象返回的偏移值并不总是一致的,并且可能会导致绘制的直线捕捉到看似随机的坐标 我相信我所做的只是用.NETAPI替换JS调用,我不知道为什么会发生这种情况 [更新] 这只是Firefox中的一个问题,在Chrome中一切正常。既然我想同时支持这两种方法,有人对解决方法有什么想法吗? 从我所知道的任何时候鼠标光标进入线元素,偏移是不正确的 工作代码:Svg Blazor服务器-鼠标偏移与JS Interop配合使用,但不使用MouseEventArgs.OffsetX/OffsetY(Firefox),svg,blazor-server-side,.net-5,Svg,Blazor Server Side,.net 5,我创建了一个简单的Blazor服务器应用程序来探索这项技术,并决定是否将其用于一个特定的用例,该用例涉及到让用户能够在网页上绘图 我需要知道用户点击和/或拖动的位置,因此我查阅了一些关于如何使用java脚本计算鼠标偏移量x和y的参考资料,它的功能完全符合我的预期 我最近发现在.NET5中,API中添加了“OffsetX”和“OffsetY”,因此我删除了支持这一点的Java脚本调用,现在我曾经工作的代码不再工作了。问题在于MouseEventArgs对象返回的偏移值并不总是一致的,并且可能会导致
@page "/"
@using Microsoft.JSInterop
@inject IJSRuntime js
<svg @ref="svg" width="1920" height="1080" style="border:solid; border-color: black; border-width:3px"
@onmousedown="MouseDownHandler"
@onmouseup="MouseUpHandler"
@onmousemove="MouseMoveHandler">
@foreach (Line line in LineList)
{
<line @key="@line"
x1="@line.Start.X"
y1="@line.Start.Y"
x2="@line.End.X"
y2="@line.End.Y"
stroke="black"
stroke-width="2" />
}
</svg>
@code {
private ElementReference svg;
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public class Line
{
public Coordinate Start = new();
public Coordinate End = new();
}
private Coordinate Offset = new();
private List<Line> LineList = new();
private Line line;
private Coordinate lastClickPosition;
private bool isMouseDown = false;
private async Task MouseDownHandler(MouseEventArgs args)
{
Offset = await js.InvokeAsync<Coordinate>("eval", $"let e = document.querySelector('[_bl_{svg.Id}=\"\"]'); e = e.getBoundingClientRect(); e = {{ 'X': e.x, 'Y': e.y }}; e");
Coordinate mousePosition = new()
{
X = args.ClientX - Offset.X,
Y = args.ClientY - Offset.Y
};
line = new Line();
LineList.Add(line);
line.Start = mousePosition;
line.End = mousePosition;
isMouseDown = true;
}
private void MouseUpHandler(MouseEventArgs args)
{
isMouseDown = false;
}
private async Task MouseMoveHandler(MouseEventArgs args)
{
if (isMouseDown)
{
Offset = await js.InvokeAsync<Coordinate>("eval", $"let e = document.querySelector('[_bl_{svg.Id}=\"\"]'); e = e.getBoundingClientRect(); e = {{ 'X': e.x, 'Y': e.y }}; e"); Coordinate mousePosition = new()
{
X = args.ClientX - Offset.X,
Y = args.ClientY - Offset.Y
};
line.End = mousePosition;
}
}
@page "/"
@using Microsoft.JSInterop
@inject IJSRuntime js
<svg @ref="svg" width="1920" height="1080" style="border:solid; border-color: black; border-width:3px"
@onmousedown="MouseDownHandler"
@onmouseup="MouseUpHandler"
@onmousemove="MouseMoveHandler">
@foreach (Line line in LineList)
{
<line @key="@line"
x1="@line.Start.X"
y1="@line.Start.Y"
x2="@line.End.X"
y2="@line.End.Y"
stroke="black"
stroke-width="2" />
}
</svg>
@code {
private ElementReference svg;
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public class Line
{
public Coordinate Start = new();
public Coordinate End = new();
}
private Coordinate Offset = new();
private List<Line> LineList = new();
private Line line;
private Coordinate lastClickPosition;
private bool isMouseDown = false;
private void MouseDownHandler(MouseEventArgs args)
{
Coordinate mousePosition = new()
{
X = args.OffsetX,
Y = args.OffsetY
};
line = new Line();
LineList.Add(line);
line.Start = mousePosition;
line.End = mousePosition;
isMouseDown = true;
}
private void MouseUpHandler(MouseEventArgs args)
{
isMouseDown = false;
}
private void MouseMoveHandler(MouseEventArgs args)
{
if (isMouseDown)
{
Coordinate mousePosition = new()
{
X = args.OffsetX,
Y = args.OffsetY
};
line.End = mousePosition;
}
}
}
@page/“
@使用Microsoft.JSInterop
@注入IJSRuntime js
@foreach(行列表中的行)
{
}
@代码{
私有元素引用svg;
公共类坐标
{
公共双X{get;set;}
公共双Y{get;set;}
}
公共班级线
{
公共坐标开始=新建();
公共坐标结束=新建();
}
专用坐标偏移=新();
私有列表LineList=new();
专线;
私人坐标位置;
private bool isMouseDown=false;
专用异步任务MouseDownHandler(MouseEventArgs args)
{
Offset=wait js.InvokeAsync(“eval”,$”让e=document.querySelector('[\u bl{svg.Id}=\“\”);e=e.getBoundingClientRect();e={{'X':e.X,'Y':e.Y};e”);
坐标鼠标位置=新()
{
X=args.ClientX-Offset.X,
Y=args.ClientY-Offset.Y
};
行=新行();
LineList.Add(行);
line.Start=鼠标位置;
line.End=鼠标位置;
isMouseDown=真;
}
专用void mouseuphhandler(MouseEventArgs args)
{
isMouseDown=错误;
}
专用异步任务MouseMoveHandler(MouseEventArgs args)
{
如果(isMouseDown)
{
Offset=wait js.InvokeAsync(“eval”,$”让e=document.querySelector('[\u bl{svg.Id}=\“\”);e=e.getBoundingClientRect();e={{X':e.X,'Y':e.Y};e”);坐标鼠标位置=new()
{
X=args.ClientX-Offset.X,
Y=args.ClientY-Offset.Y
};
line.End=鼠标位置;
}
}
非工作代码:
@page "/"
@using Microsoft.JSInterop
@inject IJSRuntime js
<svg @ref="svg" width="1920" height="1080" style="border:solid; border-color: black; border-width:3px"
@onmousedown="MouseDownHandler"
@onmouseup="MouseUpHandler"
@onmousemove="MouseMoveHandler">
@foreach (Line line in LineList)
{
<line @key="@line"
x1="@line.Start.X"
y1="@line.Start.Y"
x2="@line.End.X"
y2="@line.End.Y"
stroke="black"
stroke-width="2" />
}
</svg>
@code {
private ElementReference svg;
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public class Line
{
public Coordinate Start = new();
public Coordinate End = new();
}
private Coordinate Offset = new();
private List<Line> LineList = new();
private Line line;
private Coordinate lastClickPosition;
private bool isMouseDown = false;
private async Task MouseDownHandler(MouseEventArgs args)
{
Offset = await js.InvokeAsync<Coordinate>("eval", $"let e = document.querySelector('[_bl_{svg.Id}=\"\"]'); e = e.getBoundingClientRect(); e = {{ 'X': e.x, 'Y': e.y }}; e");
Coordinate mousePosition = new()
{
X = args.ClientX - Offset.X,
Y = args.ClientY - Offset.Y
};
line = new Line();
LineList.Add(line);
line.Start = mousePosition;
line.End = mousePosition;
isMouseDown = true;
}
private void MouseUpHandler(MouseEventArgs args)
{
isMouseDown = false;
}
private async Task MouseMoveHandler(MouseEventArgs args)
{
if (isMouseDown)
{
Offset = await js.InvokeAsync<Coordinate>("eval", $"let e = document.querySelector('[_bl_{svg.Id}=\"\"]'); e = e.getBoundingClientRect(); e = {{ 'X': e.x, 'Y': e.y }}; e"); Coordinate mousePosition = new()
{
X = args.ClientX - Offset.X,
Y = args.ClientY - Offset.Y
};
line.End = mousePosition;
}
}
@page "/"
@using Microsoft.JSInterop
@inject IJSRuntime js
<svg @ref="svg" width="1920" height="1080" style="border:solid; border-color: black; border-width:3px"
@onmousedown="MouseDownHandler"
@onmouseup="MouseUpHandler"
@onmousemove="MouseMoveHandler">
@foreach (Line line in LineList)
{
<line @key="@line"
x1="@line.Start.X"
y1="@line.Start.Y"
x2="@line.End.X"
y2="@line.End.Y"
stroke="black"
stroke-width="2" />
}
</svg>
@code {
private ElementReference svg;
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public class Line
{
public Coordinate Start = new();
public Coordinate End = new();
}
private Coordinate Offset = new();
private List<Line> LineList = new();
private Line line;
private Coordinate lastClickPosition;
private bool isMouseDown = false;
private void MouseDownHandler(MouseEventArgs args)
{
Coordinate mousePosition = new()
{
X = args.OffsetX,
Y = args.OffsetY
};
line = new Line();
LineList.Add(line);
line.Start = mousePosition;
line.End = mousePosition;
isMouseDown = true;
}
private void MouseUpHandler(MouseEventArgs args)
{
isMouseDown = false;
}
private void MouseMoveHandler(MouseEventArgs args)
{
if (isMouseDown)
{
Coordinate mousePosition = new()
{
X = args.OffsetX,
Y = args.OffsetY
};
line.End = mousePosition;
}
}
}
@page/“
@使用Microsoft.JSInterop
@注入IJSRuntime js
@foreach(行列表中的行)
{
}
@代码{
私有元素引用svg;
公共类坐标
{
公共双X{get;set;}
公共双Y{get;set;}
}
公共班级线
{
公共坐标开始=新建();
公共坐标结束=新建();
}
专用坐标偏移=新();
私有列表LineList=new();
专线;
私人坐标位置;
private bool isMouseDown=false;
私有void MouseDownHandler(MouseEventArgs args)
{
坐标鼠标位置=新()
{
X=args.OffsetX,
Y=args.OffsetY
};
行=新行();
LineList.Add(行);
line.Start=鼠标位置;
line.End=鼠标位置;
isMouseDown=真;
}
专用void mouseuphhandler(MouseEventArgs args)
{
isMouseDown=错误;
}
私有void MouseMoveHandler(MouseEventArgs args)
{
如果(isMouseDown)
{
坐标鼠标位置=新()
{
X=args.OffsetX,
Y=args.OffsetY
};
line.End=鼠标位置;
}
}
}