我正在使用Silverlight 5进行缩放,
我的想法是根据画布上的鼠标位置进行缩放,以及拖动画布的能力,
我遇到的问题是当刻度小于1,大约0.6或0.5时,指向画布的一角并向上转动,画布将改变其位置或“跳跃”,有什么帮助吗?
这两张照片描述了之后的状态:
我有以下XAML:
<Grid x:Name="LayoutRoot" Background="White">
<ScrollViewer x:Name="sv" Margin="0,0,0,76" ScrollViewer.VerticalScrollBarVisibility="Disabled" Background="#FFE3E7F1">
<Canvas x:Name="grd" Height="394" Width="630">
<Canvas x:Name="cvs" Background="White" MouseWheel="cvs_MouseWheel" MouseLeftButtonDown="cvs_MouseLeftButtonDown" MouseLeftButtonUp="cvs_MouseLeftButtonUp" MouseMove="cvs_MouseMove" Height="391" Canvas.Left="2" Canvas.Top="1" Width="625">
<Canvas.Effect>
<DropShadowEffect ShadowDepth="0"/>
</Canvas.Effect>
<Rectangle Height="70" Canvas.Left="155" Canvas.Top="58" Width="79" Fill="#FFFFBFBF"/>
<Rectangle Height="70" Canvas.Left="544" Canvas.Top="126" Width="79" Fill="#FF8B92FF"/>
</Canvas>
</Canvas>
</ScrollViewer>
</Grid>
这是C#:
public partial class MainPage : UserControl
{
CompositeTransform canvasTransform = new CompositeTransform();
bool canDragCanvas;
double mouseRelatedPositionX = 0;
double mouseRelatedPositionY = 0;
public MainPage()
{
// Required to initialize variables
InitializeComponent();
}
private void cvs_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
var scaleFactor = 0.2*(e.Delta < 0?-1:1);
var centerX = e.GetPosition(cvs).X;
var centerY = e.GetPosition(cvs).Y;
if (centerX > cvs.ActualWidth * canvasTransform.ScaleX || centerX < 0 || centerY > cvs.ActualHeight * canvasTransform.ScaleY || centerY < 0)
{
centerX = cvs.ActualWidth/2;
centerY = cvs.ActualHeight/2;
}
canvasTransform.CenterX = centerX;
canvasTransform.CenterY = centerY;
canvasTransform.ScaleX += scaleFactor;
canvasTransform.ScaleY += scaleFactor;
cvs.RenderTransform = canvasTransform;
}
private void cvs_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
canDragCanvas = true;
mouseRelatedPositionX = e.GetPosition(cvs).X;
mouseRelatedPositionY = e.GetPosition(cvs).Y;
}
private void cvs_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
canDragCanvas = false;
}
private void cvs_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if(!canDragCanvas) return;
var leftValueToAdd = e.GetPosition(cvs).X - mouseRelatedPositionX;
var topValueToAdd = e.GetPosition(cvs).Y - mouseRelatedPositionY;
UpdateCanvasPosition(leftValueToAdd*canvasTransform.ScaleX, topValueToAdd*canvasTransform.ScaleX);
}
void UpdateCanvasPosition(double leftValueToAdd,double topValueToAdd)
{
var leftOffset = canvasTransform.CenterX - canvasTransform.CenterX * canvasTransform.ScaleX;
var rightOffset = (cvs.ActualWidth - canvasTransform.CenterX) - (cvs.ActualWidth - canvasTransform.CenterX) * canvasTransform.ScaleX;
var topOffset = canvasTransform.CenterY - canvasTransform.CenterY * canvasTransform.ScaleY;
var bottomOffset = (cvs.ActualHeight - canvasTransform.CenterY) - (cvs.ActualHeight - canvasTransform.CenterY) * canvasTransform.ScaleY;
var canvasLeftInBorders = Canvas.GetLeft(cvs)+ leftValueToAdd + leftOffset > 0;
var canvasRightInBorders = Canvas.GetLeft(cvs) + cvs.ActualWidth * canvasTransform.ScaleX + leftValueToAdd + leftOffset < grd.ActualWidth;
var canvasTopInBorders = Canvas.GetTop(cvs) + topValueToAdd + topOffset > 0;
var canvasBottomInBorders = Canvas.GetTop(cvs) + cvs.ActualHeight * canvasTransform.ScaleY + topValueToAdd + topOffset < grd.ActualHeight;
if (leftValueToAdd > 0)
{
if (canvasLeftInBorders)
leftValueToAdd = 0;
}
else if (leftValueToAdd < 0)
if (canvasRightInBorders)
leftValueToAdd = 0;
if (topValueToAdd > 0)
{
if (canvasTopInBorders)
topValueToAdd = 0;
}
else if (topValueToAdd < 0)
if (canvasBottomInBorders)
topValueToAdd = 0;
Canvas.SetLeft(cvs, Canvas.GetLeft(cvs) + leftValueToAdd);
Canvas.SetTop(cvs,Canvas.GetTop(cvs)+topValueToAdd);
}
}
答案 0 :(得分:2)
基本上,您将鼠标事件附加到正在缩放的表面,鼠标坐标也会被更改。 Silverlight设计为在旋转,缩放和倾斜时仍然是交互式的。
您希望在顶部放置一个透明图层(未放大),并将鼠标方法附加到该图层。
如果您打开该图层,则必须计算碰撞,但您可以进行此操作,以便图层仅在鼠标按下时出现并在鼠标移动时消失。