Tengo una aplicación que está muy "basada en la conexión", es decir, múltiples entradas/salidas.¿Cómo puedo simular un cable colgante en WPF?
El concepto de interfaz de usuario de un "cable" es exactamente lo que estoy buscando para aclarar el concepto al usuario. Propellerhead tomó un enfoque similar en su software Reason para componentes de audio, ilustrado en this YouTube video (fast forward to 2m:50s).
Puedo hacer que este concepto funcione en GDI pintando una spline del punto A al punto B, tiene que haber una forma más elegante de usar Paths o algo en WPF para esto, pero ¿dónde empiezas? ¿Hay una buena manera de simular la animación del balanceo del cable cuando lo agarras y lo agitas?
También estoy abierto a bibliotecas de control (comerciales o de código abierto) si esta rueda ya se ha inventado para WPF.
Actualización: Gracias a los enlaces en las respuestas hasta el momento, estoy casi allí.
He creado un BezierCurve
mediante programación, con el punto 1 siendo (0, 0)
, punto 2, siendo la parte inferior "colgar" punto y el punto 3 es dondequiera que el cursor del ratón. Creé un PointAnimation
para el Punto 2 con una función de aceleración ElasticEase
aplicada para darle el efecto "Balanceo" (es decir, rebotar el punto medio alrededor de un bit).
El único problema es que la animación parece llegar un poco tarde. Estoy comenzando el Storyboard cada vez que se mueve el mouse, ¿hay una mejor manera de hacer esta animación? Mi solución hasta el momento se encuentra aquí:
Código:
private Path _path = null;
private BezierSegment _bs = null;
private PathFigure _pFigure = null;
private Storyboard _sb = null;
private PointAnimation _paPoint2 = null;
ElasticEase _eEase = null;
private void cvCanvas_MouseMove(object sender, MouseEventArgs e)
{
var position = e.GetPosition(cvCanvas);
AdjustPath(position.X, position.Y);
}
// basic idea: when mouse moves, call AdjustPath and draw line from (0,0) to mouse position with a "hang" in the middle
private void AdjustPath(double x, double y)
{
if (_path == null)
{
_path = new Path();
_path.Stroke = new SolidColorBrush(Colors.Blue);
_path.StrokeThickness = 2;
cvCanvas.Children.Add(_path);
_bs = new BezierSegment(new Point(0, 0), new Point(0, 0), new Point(0, 0), true);
PathSegmentCollection psCollection = new PathSegmentCollection();
psCollection.Add(_bs);
_pFigure = new PathFigure();
_pFigure.Segments = psCollection;
_pFigure.StartPoint = new Point(0, 0);
PathFigureCollection pfCollection = new PathFigureCollection();
pfCollection.Add(_pFigure);
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = pfCollection;
_path.Data = pathGeometry;
}
double bottomOfCurveX = ((x/2));
double bottomOfCurveY = (y + (x * 1.25));
_bs.Point3 = new Point(x, y);
if (_sb == null)
{
_paPoint2 = new PointAnimation();
_paPoint2.From = _bs.Point2;
_paPoint2.To = new Point(bottomOfCurveX, bottomOfCurveY);
_paPoint2.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
_eEase = new ElasticEase();
_paPoint2.EasingFunction = _eEase;
_sb = new Storyboard();
Storyboard.SetTarget(_paPoint2, _path);
Storyboard.SetTargetProperty(_paPoint2, new PropertyPath("Data.Figures[0].Segments[0].Point2"));
_sb.Children.Add(_paPoint2);
_sb.Begin(this);
}
_paPoint2.From = _bs.Point2;
_paPoint2.To = new Point(bottomOfCurveX, bottomOfCurveY);
_sb.Begin(this);
}
¿Estás tratando de dibujar una curva de catenaria? http://en.wikipedia.org/wiki/Catenary – Gabe
@Gabe, sí, ese parece ser el tipo de curva que estoy buscando – Brandon
¿Has visto http://www.tinaja.com/glib/bezcat. pdf? – Gabe