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); }
// 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)); }
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; }
// 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); } } }