public override void reset(long time) { base.reset(time); TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; if (type == ActionType.TO) { run_point0 = target.position; run_point1 = this.point1; run_point2 = this.point2; run_point3 = this.point3; } else if (type == ActionType.BY) { run_point0 = target.position; run_point1 = new PointF(target.position.X + this.point1.X, target.position.Y + this.point1.Y); run_point2 = new PointF(target.position.X + this.point2.X, target.position.Y + this.point2.Y); run_point3 = new PointF(target.position.X + this.point3.X, target.position.Y + this.point3.Y); } run_easingFunction = new TEasingFunction(); } }
public void setFinalData(TActor actor) { final.name = actor.name; final.draggable = actor.draggable; final.acceleratorSensibility = actor.acceleratorSensibility; final.anchor = actor.anchor; final.position = actor.position; final.scale = actor.scale; final.skew = actor.skew; final.rotation = actor.rotation; final.backgroundColor = actor.backgroundColor; final.alpha = actor.alpha; final.zIndex = actor.zIndex; final.interactionBound = actor.interactionBound; final.autoInteractionBound = actor.autoInteractionBound; final.puzzleArea = actor.puzzleArea; final.puzzle = actor.puzzle; if (actor is TTextActor) { TTextActor textActor = actor as TTextActor; final.text = textActor.text; final.font = textActor.font; final.color = textActor.color; final.boxSize = textActor.boxSize; } }
public override TActor actorAtPosition(Matrix m, PointF screenPos, bool withinInteraction) { if (run_extraActors != null) { for (int i = run_extraActors.Count - 1; i >= 0; i--) { TActor ret = run_extraActors[i].actorAtPosition(m, screenPos, withinInteraction); if (ret != null) { return(ret); } } } List <TActor> items = this.sortedChilds(); for (int i = items.Count - 1; i >= 0; i--) { TActor ret = items[i].actorAtPosition(m, screenPos, withinInteraction); if (ret != null) { return(ret); } } return(null); }
private void pnlDisplayBox_MouseDown(object sender, MouseEventArgs e) { if (currentScene == null) { return; } if (e.Button == MouseButtons.Left && transitionDelegate == null) { // matrix Matrix mat = matrixOfEmulator(); // set flag that mouse is pressed and store position MousePressed = true; MouseDownPos = new PointF(e.X, e.Y); // target item TActor selectedActor = currentScene.actorAtPosition(mat, e.Location, true); if (selectedActor != null) { // fire touch event MouseDownActor = selectedActor; MouseDownActor.fireEvent(Program.DEFAULT_EVENT_TOUCH, false); // fire drag event if (MouseDownActor.draggable || MouseDownActor.puzzle) { MouseDownActor.createBackup(); } } // redraw workspace this.pnlDisplayBox.Refresh(); } }
public TransferActorAction(TDocument doc, TActor actor, TLayer parent) { this.document = doc; this.actor = actor; this.oldData = new ActorMatrixData(); this.newData = new ActorMatrixData(); this.oldParent = actor.parent; this.newParent = parent; this.oldData.position = actor.position; this.oldData.scale = actor.scale; this.oldData.skew = actor.skew; this.oldData.rotation = actor.rotation; // actor's position based on new parent PointF pt = actor.parent.logicalToScreen(actor.position); pt = parent.screenToLogical(pt); // actor's rotation based on new parent float angle = actor.rotationOnScreen(); if (parent is TActor) { angle -= ((TActor)parent).rotationOnScreen(); } TUtil.normalizeDegreeAngle(angle); // for scale RectangleF bound = actor.bound(); PointF s = actor.logicalVectorToScreen(new PointF(bound.Width, bound.Height)); SizeF scale = new SizeF(1, 1); Matrix m2 = new Matrix(); m2.Translate(pt.X, pt.Y); m2.Rotate((float)(angle * 180 / Math.PI)); m2.Translate(-actor.anchor.X * actor.bound().Width, -actor.anchor.Y * actor.bound().Height); Matrix m = parent.matrixFromScreen(); m.Multiply(m2); if (m.IsInvertible) { PointF[] aPos = { s }; m.Invert(); m.TransformVectors(aPos); s = aPos[0]; scale = new SizeF(s.X / bound.Width, s.Y / bound.Height); } this.newData.position = pt; this.newData.scale = scale; this.newData.skew = actor.skew; this.newData.rotation = angle; oldIndex = actor.parent.childs.IndexOf(actor); }
public ModifyActorAction(TDocument doc, TActor actor) { this.document = doc; this.actor = actor; this.original = new ActorData(); this.final = new ActorData(); setOriginalData(actor); }
// scale the puzzle area of selected items the specified delta, parameters are based on real drawing canvas coordinates public void scalePuzzleArea(int part, float dx, float dy, bool fixedRatio) { for (int i = 0; i < selectedItems.Count; i++) { TActor item = this.selectedItems[i]; TActor origin = item.backupActor; PointF d = origin.ownerScene().screenVectorToLogical(new PointF(dx, dy)); RectangleF bound = origin.puzzleArea; if (fixedRatio) { float z; if (part == 1) { z = Math.Max(-d.X / bound.Width, -d.Y / bound.Height); d = new PointF(-z * bound.Width, -z * bound.Height); } else if (part == 2) { z = Math.Max(-d.X / bound.Width, d.Y / bound.Height); d = new PointF(-z * bound.Width, z * bound.Height); } else if (part == 3) { z = Math.Max(d.X / bound.Width, d.Y / bound.Height); d = new PointF(z * bound.Width, z * bound.Height); } else if (part == 4) { z = Math.Max(d.X / bound.Width, -d.Y / bound.Height); d = new PointF(z * bound.Width, -z * bound.Height); } } float x1 = bound.Left, y1 = bound.Top, x2 = bound.Right, y2 = bound.Bottom; if (part == 1 || part == 2 || part == 5) { x1 += d.X; } if (part == 3 || part == 4 || part == 7) { x2 += d.X; } if (part == 1 || part == 4 || part == 8) { y1 += d.Y; } if (part == 2 || part == 3 || part == 6) { y2 += d.Y; } item.puzzleArea = new RectangleF(x1, y1, x2 - x1, y2 - y1); } }
private void pnlDisplayBox_MouseUp(object sender, MouseEventArgs e) { if (currentScene == null) { return; } if (e.Button == MouseButtons.Left && MousePressed) { // fire drop event if (MouseDownActor != null) { MouseDownActor.fireEvent(Program.DEFAULT_EVENT_DROP, false); // check this actor is puzzle actor if (MouseDownActor.puzzle && !MouseDownActor.isMoving()) { PointF[] bound1 = MouseDownActor.interactionBoundOnScreen(); // check if the puzzle actor went the correct puzzle area if (TUtil.isPolygonsIntersect(bound1, MouseDownActor.puzzleAreaOnScreen())) { // turn off the puzzle function after success MouseDownActor.puzzle = false; // fire puzzle success event MouseDownActor.fireEvent(Program.DEFAULT_EVENT_PUZZLE_SUCCESS, false); } else { // if puzzle is failed, actor return to original position TAnimation animation = new TAnimation(MouseDownActor); TSequence sequence = animation.addSequence(); sequence.addAction(new TActionIntervalMove() { duration = 300, position = MouseDownActor.backupActor.position }); sequence.addAction(new TActionInstantDispatchEvent() { actor = MouseDownActor.name, eventu = Program.DEFAULT_EVENT_PUZZLE_FAIL, recursive = false }); animation.start(); extraAnimations.Add(animation); } } } MousePressed = false; MouseDownActor = null; // redraw workspace this.pnlDisplayBox.Refresh(); } }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { TActor targetActor = (TActor)emulator.currentScene.findLayer(actor); if (targetActor != null) { targetActor.stopAnimation(eventu, state); } return(base.step(emulator, time)); }
// move the anchor point of selected item the specified delta, parameters are based on real drawing canvas coordinates public void moveAnchorOfSelectedItem(float dx, float dy, bool fixedMove) { if (fixedMove) { double al = Math.Atan2(dy, dx) * 180 / Math.PI; float d = Math.Min(Math.Abs(dx), Math.Abs(dy)); if (al >= -22.5 && al < 22.5) { dy = 0; } else if (al >= 22.5 && al < 67.5) { dx = d; dy = d; } else if (al >= 67.5 && al < 112.5) { dx = 0; } else if (al >= 112.5 && al < 157.5) { dx = -d; dy = d; } else if (al >= 157.5 || al < -157.5) { dy = 0; } else if (al >= -157.5 && al < -112.5) { dx = -d; dy = -d; } else if (al >= -112.5 && al < -67.5) { dx = 0; } else if (al >= 67.5 && al < 22.5) { dx = d; dy = -d; } } for (int i = 0; i < selectedItems.Count; i++) { TActor item = this.selectedItems[i]; TActor origin = item.backupActor; PointF screenPos = origin.parent.logicalToScreen(origin.position); screenPos.X += dx; screenPos.Y += dy; PointF logicalPos = origin.screenToLogical(screenPos); RectangleF bound = origin.bound(); item.position = origin.parent.screenToLogical(screenPos); item.anchor = new PointF(logicalPos.X / bound.Width, logicalPos.Y / bound.Height); } }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { TActor targetActor = (TActor)emulator.currentScene.findLayer(actor); if (targetActor != null) { targetActor.run_state = state; } return(base.step(emulator, time)); }
public void toggleSelectedItem(TActor item) { if (this.selectedItems.Contains(item)) { this.selectedItems.Remove(item); } else { this.selectedItems.Add(item); } }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { TActor targetActor = (TActor)emulator.currentScene.findLayer(actor); if (targetActor != null) { targetActor.fireEvent(eventu, recursive); } return(base.step(emulator, time)); }
private void finishCurrentScene() { // free resources for old scene stopAllEffects(); stopAllVoices(); // free captured mouse MousePressed = false; MouseDownActor = null; // clear extra animations extraAnimations.Clear(); }
// move the selected items the specified delta, parameters are based on real drawing canvas coordinates public void moveSelectedItems(float dx, float dy, bool fixedMove) { if (fixedMove) { double al = Math.Atan2(dy, dx) * 180 / Math.PI; float d = Math.Min(Math.Abs(dx), Math.Abs(dy)); if (al >= -22.5 && al < 22.5) { dy = 0; } else if (al >= 22.5 && al < 67.5) { dx = d; dy = d; } else if (al >= 67.5 && al < 112.5) { dx = 0; } else if (al >= 112.5 && al < 157.5) { dx = -d; dy = d; } else if (al >= 157.5 || al < -157.5) { dy = 0; } else if (al >= -157.5 && al < -112.5) { dx = -d; dy = -d; } else if (al >= -112.5 && al < -67.5) { dx = 0; } else if (al >= 67.5 && al < 22.5) { dx = d; dy = -d; } } for (int i = 0; i < selectedItems.Count; i++) { TActor item = this.selectedItems[i]; TActor origin = item.backupActor; PointF p = origin.parent.logicalToScreen(origin.position); p.X += dx; p.Y += dy; item.position = origin.parent.screenToLogical(p); } }
// move the puzzle area of selected items the specified delta, parameters are based on real drawing canvas coordinates public void movePuzzleArea(float dx, float dy, bool fixedMove) { if (fixedMove) { double al = Math.Atan2(dy, dx) * 180 / Math.PI; float d = Math.Min(Math.Abs(dx), Math.Abs(dy)); if (al >= -22.5 && al < 22.5) { dy = 0; } else if (al >= 22.5 && al < 67.5) { dx = d; dy = d; } else if (al >= 67.5 && al < 112.5) { dx = 0; } else if (al >= 112.5 && al < 157.5) { dx = -d; dy = d; } else if (al >= 157.5 || al < -157.5) { dy = 0; } else if (al >= -157.5 && al < -112.5) { dx = -d; dy = -d; } else if (al >= -112.5 && al < -67.5) { dx = 0; } else if (al >= 67.5 && al < 22.5) { dx = d; dy = -d; } } for (int i = 0; i < selectedItems.Count; i++) { TActor item = this.selectedItems[i]; TActor origin = item.backupActor; PointF p = origin.ownerScene().logicalToScreen(origin.puzzleArea.Location); p.X += dx; p.Y += dy; item.puzzleArea = new RectangleF(origin.ownerScene().screenToLogical(p), origin.puzzleArea.Size); } }
protected override void UnExecuteCore() { for (int i = actorDatas.Count - 1; i >= 0; i--) { ActorData actorData = actorDatas[i]; actorData.parent.childs.Insert(actorData.index, actorData.actor); } if (actorList.Count > 0) { TActor actor = actorList[0]; TScene scene = actor.ownerScene(); document.sceneManager.updateThumbnail(scene); } }
// scale the selected text actor the specified delta, parameters are based on real drawing canvas coordinates public bool resizeSelectedTextActor(int part, float dx, float dy) { TActor actor = this.selectedActor(); if (actor != null && actor is TTextActor) { TTextActor item = (TTextActor)actor; PointF d = item.screenVectorToLogical(new PointF(dx, dy)); float w = item.boxSize.Width, h = item.boxSize.Height; float px = item.anchor.X * w, py = item.anchor.Y * h; if (part == 1 || part == 2 || part == 5) { w -= d.X; px = d.X + w * item.anchor.X; } if (part == 3 || part == 4 || part == 7) { w += d.X; px = item.anchor.X * w; } if (part == 1 || part == 4 || part == 8) { h -= d.Y; py = d.Y + h * item.anchor.Y; } if (part == 2 || part == 3 || part == 6) { h += d.Y; py = item.anchor.Y * h; } if (w > 0 && h > 0) { PointF[] p0 = { new PointF(px, py) }; item.matrix.TransformPoints(p0); item.position = p0[0]; item.boxSize = new SizeF(w, h); return(true); } } return(false); }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { float elapsed = time - run_startTime; if (elapsed > duration) { elapsed = duration; } TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; target.rotation = TUtil.normalizeDegreeAngle(run_easingFunction.ease(easingType, easingMode, duration, elapsed, run_startAngle, run_endAngle)); } return(base.step(emulator, time)); }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { float elapsed = time - run_startTime; if (elapsed > duration) { elapsed = duration; } TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; float t = run_easingFunction.ease(easingType, easingMode, duration, elapsed, 0, 1); target.position = bezier(t); } return(base.step(emulator, time)); }
public void transferLayer(TActor item, TLayer target) { // item's position based on new parent PointF pt = item.parent.logicalToScreen(item.position); pt = target.screenToLogical(pt); // item's rotation based on new parent float angle = item.rotationOnScreen(); if (target is TActor) { angle -= ((TActor)target).rotationOnScreen(); } TUtil.normalizeDegreeAngle(angle); // for scale RectangleF bound = item.bound(); PointF s = item.logicalVectorToScreen(new PointF(bound.Width, bound.Height)); // new properties item.position = pt; item.rotation = angle; item.scale = new Size(1, 1); Matrix m = target.matrixFromScreen(); m.Multiply(item.matrix); if (m.IsInvertible) { PointF[] aPos = { s }; m.Invert(); m.TransformVectors(aPos); s = aPos[0]; item.scale = new SizeF(s.X / bound.Width, s.Y / bound.Height); } item.parent.childs.Remove(item); target.childs.Add(item); item.parent = target; }
public override void reset(long time) { base.reset(time); TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; run_startAngle = target.rotation; if (type == ActionType.TO) { run_endAngle = this.angle; } else if (type == ActionType.BY) { run_endAngle = target.rotation + this.angle; } run_easingFunction = new TEasingFunction(); } }
public override void reset(long time) { base.reset(time); TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; run_startPos = target.position; if (type == ActionType.TO) { run_endPos = this.position; } else if (type == ActionType.BY) { run_endPos = new PointF(target.position.X + this.position.X, target.position.Y + this.position.Y); } run_easingFunction = new TEasingFunction(); } }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { float elapsed = time - run_startTime; if (elapsed > duration) { elapsed = duration; } TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; float width = run_easingFunction.ease(easingType, easingMode, duration, elapsed, run_startScale.Width, run_endScale.Width); float height = run_easingFunction.ease(easingType, easingMode, duration, elapsed, run_startScale.Height, run_endScale.Height); target.scale = new SizeF(width, height); } return(base.step(emulator, time)); }
public override void reset(long time) { base.reset(time); TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; run_startScale = target.scale; if (type == ActionType.TO) { run_endScale = this.scale; } else if (type == ActionType.BY) { run_endScale = new SizeF(target.scale.Width * this.scale.Width, target.scale.Height * this.scale.Height); } run_easingFunction = new TEasingFunction(); } }
// execute action for every frame // if action is finished, return true; public override bool step(FrmEmulator emulator, long time) { float elapsed = time - run_startTime; if (elapsed > duration) { elapsed = duration; } TLayer layer = sequence.animation.layer; if (layer is TActor) { TActor target = (TActor)layer; float x = run_easingFunction.ease(easingType, easingMode, duration, elapsed, run_startPos.X, run_endPos.X); float y = run_easingFunction.ease(easingType, easingMode, duration, elapsed, run_startPos.Y, run_endPos.Y); target.position = new PointF(x, y); } return(base.step(emulator, time)); }
// rotate the selected item the specified angle, the angle is degree public void rotateSelectedItems(float angle, bool fixedAngle) { if (selectedItems.Count == 0) { return; } if (fixedAngle) { angle = (float)(Math.Floor(angle / 15) + 1) * 15; } if (selectedItems.Count == 1) { TActor item = (TActor)this.selectedItems[0]; TActor origin = item.backupActor; item.rotation = TUtil.normalizeDegreeAngle(origin.rotation + angle); } else { // center of selection PointF[] bound = this.selectedBound(); PointF c = new PointF((bound[0].X + bound[2].X) / 2, (bound[0].Y + bound[2].Y) / 2); // rotate each selected item for (int i = 0; i < selectedItems.Count; i++) { // adjust rotation value TActor item = this.selectedItems[0]; TActor origin = item.backupActor; item.rotation = TUtil.normalizeDegreeAngle(origin.rotation + angle); // item position PointF p = item.parent.logicalToScreen(item.position); p = TUtil.rotatePositionAround(c, p, angle); item.position = item.parent.screenToLogical(p); } } }
protected override void ExecuteCore() { actorDatas.Clear(); document.selectedItems.Clear(); actorList.ForEach((actor) => { if (actor.parent != null) { actorDatas.Add(new ActorData { actor = actor, parent = actor.parent, index = actor.parent.childs.IndexOf(actor) }); actor.parent.childs.Remove(actor); } }); if (actorList.Count > 0) { TActor actor = actorList[0]; TScene scene = actor.ownerScene(); document.sceneManager.updateThumbnail(scene); } }
//============== return value ===============// // // -1 // 9 9 // ┌───────────────────────┐ // │ 1 8 4 │ // │ │ // -1 │ 5 0 7 │ -1 // │ │ // │ 2 6 3 │ // └───────────────────────┘ // 9 9 // -1 // // // Anchor Point : 10 //============================================// public int partOfSelection(float x, float y, out int cursor) { cursor = -1; if (selectedItems.Count == 0) { return(-1); } if (selectedItems.Count > 1) { return(containsInSelection(x, y) ? 0 : 9); } TActor actor = selectedItems[0]; if (currentTool == TDocument.TOOL_PUZZLE && !actor.puzzle) { return(-1); } PointF screenPos = new PointF(x, y); PointF logicalPos = currentTool != TDocument.TOOL_PUZZLE ? actor.screenToLogical(new PointF(x, y)) : actor.ownerScene().screenToLogical(new PointF(x, y)); RectangleF actorBound = actor.bound(); PointF anchorPosOnScreen = actor.logicalToScreen(new PointF(actorBound.Width * actor.anchor.X, actorBound.Height * actor.anchor.Y)); RectangleF bound; if (currentTool == TDocument.TOOL_BOUNDING) { bound = actor.interactionBound; } else if (currentTool == TDocument.TOOL_PUZZLE) { bound = actor.puzzleArea; } else { bound = actorBound; } PointF[] boundOnScreen; if (currentTool == TDocument.TOOL_BOUNDING) { boundOnScreen = actor.interactionBoundOnScreen(); } else if (currentTool == TDocument.TOOL_PUZZLE) { boundOnScreen = actor.puzzleAreaOnScreen(); } else { boundOnScreen = actor.boundOnScreen(); } int ctrl_size = 6; bool leftEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[0], boundOnScreen[1]) <= ctrl_size; bool bottomEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[1], boundOnScreen[2]) <= ctrl_size; bool rightEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[2], boundOnScreen[3]) <= ctrl_size; bool topEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[3], boundOnScreen[0]) <= ctrl_size; bool insideBound = bound.Contains(logicalPos); int first_cursor = 0; // cursor form part 5 double angle = -Math.Atan2(boundOnScreen[1].Y - boundOnScreen[0].Y, boundOnScreen[1].X - boundOnScreen[0].X) * 180 / Math.PI; if (angle < 0) { angle += 360; } first_cursor = (int)((angle + 22.5) / 45) % 4; int part = -1; if (leftEdge && topEdge) { part = 1; cursor = (first_cursor - 1) % 4; } else if (leftEdge && bottomEdge) { part = 2; cursor = (first_cursor + 1) % 4; } else if (rightEdge && bottomEdge) { part = 3; cursor = (first_cursor + 3) % 4; } else if (rightEdge && topEdge) { part = 4; cursor = (first_cursor + 5) % 4; } else if (leftEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[0], boundOnScreen[1])) { part = 5; cursor = (first_cursor + 0) % 4; } else if (bottomEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[1], boundOnScreen[2])) { part = 6; cursor = (first_cursor + 2) % 4; } else if (rightEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[2], boundOnScreen[3])) { part = 7; cursor = (first_cursor + 4) % 4; } else if (topEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[3], boundOnScreen[0])) { part = 8; cursor = (first_cursor + 6) % 4; } else if (TUtil.distanceBetweenPoints(screenPos, anchorPosOnScreen) <= ctrl_size) { part = 10; } else if (insideBound) { part = 0; } else if (currentTool != TDocument.TOOL_BOUNDING && currentTool != TDocument.TOOL_PUZZLE) { if (TUtil.distanceBetweenPoints(screenPos, boundOnScreen[0]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[1]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[2]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[3]) <= ctrl_size * 3) { part = 9; } } return(part); }
// scale the selected items the specified delta, parameters are based on real drawing canvas coordinates public void scaleSelectedItems(int part, float dx, float dy, bool fixedRatio) { for (int i = 0; i < selectedItems.Count; i++) { TActor item = this.selectedItems[i]; TActor origin = item.backupActor; PointF d = origin.screenVectorToLogical(new PointF(dx, dy)); float sx = origin.scale.Width, sy = origin.scale.Height; RectangleF bound = origin.bound(); float px = origin.anchor.X * bound.Width, py = origin.anchor.Y * bound.Height; if (fixedRatio) { float w = bound.Width * sx, h = bound.Height * sy; float z; if (part == 1) { z = Math.Max(-d.X / w, -d.Y / h); d = new PointF(-z * w, -z * h); } else if (part == 2) { z = Math.Max(-d.X / w, d.Y / h); d = new PointF(-z * w, z * h); } else if (part == 3) { z = Math.Max(d.X / w, d.Y / h); d = new PointF(z * w, z * h); } else if (part == 4) { z = Math.Max(d.X / w, -d.Y / h); d = new PointF(z * w, -z * h); } } if (part == 1 || part == 2 || part == 5) { sx -= sx * d.X / bound.Width; px = d.X + (bound.Width - d.X) * origin.anchor.X; } if (part == 3 || part == 4 || part == 7) { sx += sx * d.X / bound.Width; px = origin.anchor.X * (bound.Width + d.X); } if (part == 1 || part == 4 || part == 8) { sy -= sy * d.Y / bound.Height; py = d.Y + (bound.Height - d.Y) * origin.anchor.Y; } if (part == 2 || part == 3 || part == 6) { sy += sy * d.Y / bound.Height; py = origin.anchor.Y * (bound.Height + d.Y); } PointF[] p0 = { new PointF(px, py) }; origin.matrix.TransformPoints(p0); item.position = p0[0]; item.scale = new SizeF(sx, sy); // PointF p0 = item.logicalToScreen(new PointF(px, py)); // item.position = item.parent.screenToLogical(p0); // item.scale = new SizeF(sx, sy); } }