public PhotoTakerFormView() { _imgFrm = new HTMLFormElement(); //TODO extract into stylesheet _img = new HTMLImageElement() .With(x => x.Style.Display = Display.None) .With(x => x.Style.Position = Position.Absolute) .With(x => x.Style.MaxWidth = "100vw") .With(x => x.Style.MaxHeight = "100vh") .With(x => x.Style.Margin = "auto") .With(x => x.Style.Left = "0") .With(x => x.Style.Top = "0") .With(x => x.Style.Right = "0") .With(x => x.Style.Bottom = "0"); _imgFrm.AppendChild(InputFile); _photoActions = new HTMLDivElement(); _photoActions.AppendAllChildren(TakePhoto.Widget, RetryPhoto.Widget, AcceptPhoto.Widget); //TODO extract into stylesheet _photoActions.Style.Display = Display.Flex; _photoActions.Style.ZIndex = "100"; _photoActions.Style.BackgroundColor = "white"; _photoActions.Style.Position = Position.Fixed; _photoActions.Style.Bottom = "0"; _photoActions.Style.Width = "100vw"; _photoActions.Style.JustifyContent = "flex-end"; _photoActions.Style.PaddingTop = "10px"; _photoActions.Style.BackgroundColor = "#f4f4f4"; _img.OnTouchStart += evs => { Logger.Debug(GetType(), "OnTouchStart count={0}", evs.Touches.Length); evs.ChangedTouches.ForEachI((i, x) => { Logger.Debug(GetType(), "OnTouchStart el={0} pageX={1} pageY={2} id={3}", i, x.PageX, x.PageY, x.Identifier); _touches[x.Identifier] = Tuple.Create((double)x.PageX, (double)x.PageY); }); }; _img.OnTouchEnd += eve => { Logger.Debug(GetType(), "OnTouchEnd count={0}", eve.Touches.Length); eve.ChangedTouches.ForEachI((i, x) => { Logger.Debug(GetType(), "OnTouchEnd el={0} pageX={1} pageY={2} id={3}", i, x.PageX, x.PageY, x.Identifier); _touches.Remove(x.Identifier); }); }; _img.OnTouchMove += evm => { Logger.Debug(GetType(), "OnTouchMove count={0} known={1}", evm.Touches.Length, _touches.Count); _touches.ForEach(x => Logger.Debug(GetType(), "known pageX={0} pageY={1} id={2}", x.Value.Item1, x.Value.Item2, x.Key)); double?oldLength = null; Tuple <double, double> oldPos = null; if (_touches.Count == 1) { oldPos = Tuple.Create(_touches.First().Value.Item1, _touches.First().Value.Item2); } else if (_touches.Count == 2) { var x = _touches.ToList(); oldLength = Math.Sqrt( Math.Pow(x[0].Value.Item1 - x[1].Value.Item1, 2) + Math.Pow(x[0].Value.Item2 - x[1].Value.Item2, 2)); } evm.ChangedTouches.ForEachI((i, x) => { Logger.Debug(GetType(), "OnTouchMove el={0} pageX={1} pageY={2} id={3}", i, x.PageX, x.PageY, x.Identifier); _touches[x.Identifier] = Tuple.Create((double)x.PageX, (double)x.PageY); }); double?newLength = null; Tuple <double, double> newPos = null; if (_touches.Count == 1) { newPos = Tuple.Create(_touches.First().Value.Item1, _touches.First().Value.Item2); } if (_touches.Count == 2) { var x = _touches.ToList(); newLength = Math.Sqrt( Math.Pow(x[0].Value.Item1 - x[1].Value.Item1, 2) + Math.Pow(x[0].Value.Item2 - x[1].Value.Item2, 2)); } Logger.Debug(GetType(), "OnTouchMove oldLength={0} newLength={1}", oldLength, newLength); var updateStyle = false; if (oldLength != null && newLength != null) { var changeScaleBy = (double)((oldLength - newLength) * _touchScalingFactor); Logger.Debug(GetType(), "OnTouchMove changeScaleBy={0} oldScale={1}", changeScaleBy, _imgScale); _imgScale -= changeScaleBy; if (_imgScale < 0.5) { _imgScale = 0.5; } else if (_imgScale > 10) { _imgScale = 10; } updateStyle = true; } if (oldPos != null && newPos != null) { Logger.Debug(GetType(), "OnTouchMove oldPos=({0};{1}) newPos=({2};{3})", oldPos.Item1, oldPos.Item2, newPos.Item1, newPos.Item2); var changeTranslateXBy = (oldPos.Item1 - newPos.Item1) * _touchTranslateFactor; var changeTranslateYBy = (oldPos.Item2 - newPos.Item2) * _touchTranslateFactor; Logger.Debug(GetType(), "OnTouchMove translatedBy=({0}; {1}) oldTranslated=({2};{3})", changeTranslateXBy, changeTranslateYBy, _translateX, _translateY); _translateX -= changeTranslateXBy; _translateY -= changeTranslateYBy; updateStyle = true; } if (updateStyle) { UpdateStyle(true); } }; }