c# - Combining RotateTransform and TranslateTransform -
i using thumb class let user drag , drop image across canvas. when right button gets pressed, want user able rotate image. rotation based around center of image. have following xaml code
<grid> <canvas background="red" grid.rowspan="2" x:name="canvas" previewmouserightbuttonup="canvas_mouseup" previewmousemove="canvas_mousemove"> <usercontrol mouserightbuttondown="canvas_mousedown" rendertransformorigin="0.5,0.5"> <thumb name="myroot" dragdelta="myroot_dragdelta"> <thumb.template> <controltemplate> <grid> <image source="/wpfapplication1;component/someimage.png" /> <rectangle stroke="#ff0061ce" strokethickness="1" width="230" height="250" /> </grid> </controltemplate> </thumb.template> </thumb> <usercontrol.rendertransform> <transformgroup> <rotatetransform x:name="rotatetransform" /> <translatetransform x:name="translatetransform" /> </transformgroup> </usercontrol.rendertransform> </usercontrol> </canvas> </grid> and code behind
bool ismousedown = false; point pos; double lastangle = 0; private void canvas_mousedown(object sender, mousebuttoneventargs e) { ismousedown = true; lastangle = rotatetransform.angle; pos = mouse.getposition(canvas); } private void canvas_mouseup(object sender, mousebuttoneventargs e) { ismousedown = false; } private void canvas_mousemove(object sender, mouseeventargs e) { if (!ismousedown) return; var curpos = mouse.getposition(canvas); rotatetransform.angle = lastangle + (pos.y - curpos.y); } private void myroot_dragdelta(object sender, dragdeltaeventargs e) { translatetransform.x += e.horizontalchange; translatetransform.y += e.verticalchange; } it works if drag , drop image around screen , rotate image small amount (50 degrees in direction seems ok). manipulating more , image starts move around screen unpredictibly.
i have tried moving transformations different controls, not mix them have not received acceptable result.
how can code behave want?
update: driving crazy. have changed code , xaml use matrixtransformation instead
private void canvas_mousemove(object sender, mouseeventargs e) { if (!ismousedown) return; var curpos = mouse.getposition(canvas); angle = (lastangle + (pos.y - curpos.y)) % 360; updatematrixtransform(); } private void myroot_dragdelta(object sender, dragdeltaeventargs e) { posx += e.horizontalchange; posy += e.verticalchange; updatematrixtransform(); } void updatematrixtransform() { matrix m = new matrix(); m.rotate(angle); m.offsetx = posx; m.offsety = posy; matrixt.matrix = m; } in mind, should work: first, rotate graphic move offset. not work expect to. rotates image, moves strangely in spiral fashion outwards if keep moving mouse. no matter do, , in order execute transformations, wont work.
i'm not sure why you're using usercontrol wrap thumb since should able act root element here. here solution involes scrapping use of translatetransform , instead using canvas.left , canvas.top properties:
edit: updated answer
here's xaml:
<canvas x:name="canvas"> <thumb name="myroot" canvas.left="0" canvas.top="0" dragdelta="myroot_dragdelta" mousemove="myroot_mousemove" mousedown="myroot_mousedown" mouseup="myroot_mouseup"> <thumb.template> <controltemplate> <grid rendertransformorigin="0.5, 0.5"> <rectangle fill="aliceblue" stroke="#ff0061ce" strokethickness="1" width="100" height="100"/> <grid.rendertransform> <rotatetransform x:name="rotatetransform" /> </grid.rendertransform> </grid> </controltemplate> </thumb.template> </thumb> </canvas> and here's code behind:
public partial class testwindow : window { public testwindow() { initializecomponent(); } point? lastposition = null; rotatetransform rotatetransform; private void myroot_mousedown(object sender, mousebuttoneventargs e) { lastposition = null; if (e.changedbutton == mousebutton.right) myroot.capturemouse(); } private void myroot_mouseup(object sender, mousebuttoneventargs e) { if (e.changedbutton == mousebutton.right) myroot.releasemousecapture(); } private void myroot_mousemove(object sender, mouseeventargs e) { if (e.rightbutton == mousebuttonstate.pressed) { point curposition = mouse.getposition(myroot); if (lastposition != null) { point centerpoint = new point(myroot.actualwidth / 2, myroot.actualwidth / 2); if (rotatetransform == null) rotatetransform = (rotatetransform)myroot.template.findname("rotatetransform", myroot); rotatetransform.angle = math.atan2(curposition.y - centerpoint.y, curposition.x - centerpoint.x) * 100; } lastposition = curposition; e.handled = true; } } private void myroot_dragdelta(object sender, system.windows.controls.primitives.dragdeltaeventargs e) { canvas.setleft(myroot, canvas.getleft(myroot) + e.horizontalchange); canvas.settop(myroot, canvas.gettop(myroot) + e.verticalchange); } }
Comments
Post a Comment