c# - UWP Manipulation with Rotation, Scale, and Pan -
we building c# universal windows app has drawings live-rendered overlays on it. need able rotate, zoom, , pan image of overlays following it. in future overlays should sizable , movable via screen's coordinate system.
we using viewbox
our control contains image , overlays. creating transformgroup
contains matrixtransform
, compositetransform
have seen in of samples. during each manipulation event on viewbox, resetting composite transform transform group's value, making composite transform delta transform.
we have rotation, scaling, , panning working. however, need able set zoom factor on matrix, seem unable do, can make sure doesn't go above or below our max/min zoom factor. need ensure viewbox doesn't "fly off" screen when reaches edge.
it great if didn't have reset transformmatrix every time, removing delta factor transform (we set zoom scale then). however, can't seem find center points rotation , zoom when this.
here sample app created shows doing:
xaml
<grid background="{themeresource applicationpagebackgroundthemebrush}" x:name="maingrid"> <viewbox manipulationmode="all" width="{binding elementname=maingrid, path=actualwidth}" height="{binding elementname=maingrid, path=actualheight}" rendertransform="{binding transformgroup}" manipulationdelta="viewbox_onmanipulationdelta"> <grid> <image source="pic.jpg" /> </grid> </viewbox> </grid>
code behind
public sealed partial class mainpage : page, inotifypropertychanged { public mainpage() { this.initializecomponent(); _previoustransform = new matrixtransform(); _deltatransform = new compositetransform(); transformgroup = new transformgroup(); transformgroup.children.add(_previoustransform); transformgroup.children.add(_deltatransform); datacontext = this; } readonly matrixtransform _previoustransform; readonly compositetransform _deltatransform; transformgroup _transformgroup; public transformgroup transformgroup { { return _transformgroup; } set { if (_transformgroup != value) { _transformgroup = value; onpropertychanged(); } } } void viewbox_onmanipulationdelta(object sender, manipulationdeltaroutedeventargs e) { _previoustransform.matrix = _transformgroup.value; var center = _previoustransform.transformpoint(e.position); _deltatransform.centerx = center.x; _deltatransform.centery = center.y; _deltatransform.rotation = e.delta.rotation; // check see if on our scale, reset scale max or min scale _deltatransform.scalex = e.delta.scale; _deltatransform.scaley = e.delta.scale; _deltatransform.translatex = e.delta.translation.x; _deltatransform.translatey = e.delta.translation.y; } #region propertychanged public event propertychangedeventhandler propertychanged; [notifypropertychangedinvocator] void onpropertychanged([callermembername] string propertyname = null) { propertychanged?.invoke(this, new propertychangedeventargs(propertyname)); } #endregion }
what best way go this? i'm not sure if going in right direction. thanks!
Comments
Post a Comment