gpt4 book ai didi

android - 如何在android中的 Canvas 上应用线条的旋转动画

转载 作者:太空狗 更新时间:2023-10-29 13:01:23 30 4
gpt4 key购买 nike

我已经完成了它的工作代码,但问题是每当我改变旋转角度时,它总是从第一个点开始,而不是从上次旋转结束的点开始。

我想要这样的动画。 https://drive.google.com/file/d/1Qx0MBu-77JIlQTByqGTyD-KtGKOB8naG/view?usp=sharing

我用canvas画了圆和线。我用了viewpager。如果我滑动 viewpager,饼图就会旋转

到目前为止我做了什么。动画时总是从零开始:https://drive.google.com/file/d/12mmAUOeY77jAlj_GmM3Ymcx5m34vli3X/view?usp=sharing我已经完成了以下代码:

public class PieView : View
{
int w, h, pl, pr, pt, pb, usableWidth, usableHeight, radius, cx, cy,
lineLenght;
Paint paint;
public Canvas canvas;
public float firstLineangle = 0;
public float secondLineangle = 40;
public float thirdLineangle = 120;
float currentAngle,maxAngle;

public override void Draw(Canvas canvas)
{
base.Draw(canvas);
w = Width;
h = Height;
pl = PaddingLeft;
pr = PaddingRight;
pt = PaddingTop;
pb = PaddingBottom;
this.canvas = canvas;
usableWidth = w - (pl + pr);
usableHeight = h - (pt + pb);

radius = Math.Min(usableWidth, usableHeight) / 2;
cx = pl + (usableWidth / 2);
cy = pt + (usableHeight / 2);

lineLenght = radius - (pl * 2) - (pr * 2);
paint = new Paint();
paint.Color = Android.Graphics.Color.White;
paint.SetStyle(Paint.Style.Stroke);
paint.StrokeWidth = 5;
canvas.DrawCircle(cx, cy, radius - 5, paint);

Drawline(canvas, firstLineangle);
Drawline(canvas, secondLineangle);
Drawline(canvas, thirdLineangle);

PostInvalidateDelayed(500);
Invalidate();
}

public void Drawline(Canvas canvas, float angle)
{
float displacedAngle = angle - 90;
float x = cx + ((float)Math.Cos(degreesToRadians(displacedAngle)) * (radius - 5)); //convert angle to radians for x and y coordinates
float y = cy + ((float)Math.Sin(degreesToRadians(displacedAngle)) * (radius - 5));
canvas.DrawLine(cx, cy, x, y, paint); //draw a line from center point back to the point
}

public double degreesToRadians(double degrees)
{
return (degrees * Math.PI) / 180;
}
}

public class PieAnimation : Android.Views.Animations.Animation
{
private PieView pieView;

private float firstLineangle;
private float secondLineangle;
private float thirdLineangle;

public PieAnimation(PieView pieView, float firstLineangle,float secondLineangle,float thirdLineangle)
{
this.pieView = pieView;
this.firstLineangle = firstLineangle;
this.secondLineangle = secondLineangle;
this.thirdLineangle = thirdLineangle;
}

protected override void ApplyTransformation(float interpolatedTime, Transformation t)
{
pieView.firstLineangle = 0 + ((firstLineangle) * interpolatedTime);
pieView.secondLineangle = 0 + ((secondLineangle) * interpolatedTime);
pieView.thirdLineangle = 0 + ((thirdLineangle) * interpolatedTime);
pieView.RequestLayout();
}
}

public class TourPager : Java.Lang.Object, ViewPager.IOnPageChangeListener, ViewPager.IPageTransformer
{

private ViewPager mViewPager;

private float mLastOffset;
public TourView _context;

public TourPager(ViewPager viewpager, TourView context)
{
mViewPager = viewpager;
viewpager.AddOnPageChangeListener(this);
_context = context;
}

public void OnPageSelected(int position)
{

if (position == 0)
{
PieAnimation animation = new PieAnimation(_context._pieView, 0, 40, 120);
animation.Duration = (1000);
_context._pieView.StartAnimation(animation);
}
if (position==1)
{
PieAnimation animation = new PieAnimation(_context._pieView, 100, 140, 200);
animation.Duration=(1000);
_context._pieView.StartAnimation(animation);
}
if(position==2)
{
PieAnimation animation = new PieAnimation(_context._pieView, 180, 270, 10);
animation.Duration = (1000);
_context._pieView.StartAnimation(animation);
}
}

最佳答案

我更新了 PieView 类,使其可以使用 SaveCurrentAngles() 函数保存当前角度。 PieAnimation 构造函数调用此函数来保存上一个动画结束时的角度(如果有的话)。我还更新了 PieAnimationApplyTransformation() 函数以进行准确计算。这样,即使您将直接目标角度作为动画的参数,您也应该能够实现累积动画。这是更新后的代码:

public class PieView : View
{
int w, h, pl, pr, pt, pb, usableWidth, usableHeight, radius, cx, cy, lineLenght;
Paint paint;
public Canvas canvas;
public float prevFirstLineAngle = 0;
public float prevSecondLineAngle = 0;
public float prevThirdLineAngle = 0;
public float firstLineAngle = 0;
public float secondLineAngle = 40;
public float thirdLineAngle = 120;
float currentAngle, maxAngle;

public override void Draw(Canvas canvas)
{
base.Draw(canvas);
w = Width;
h = Height;
pl = PaddingLeft;
pr = PaddingRight;
pt = PaddingTop;
pb = PaddingBottom;
this.canvas = canvas;
usableWidth = w - (pl + pr);
usableHeight = h - (pt + pb);

radius = Math.Min(usableWidth, usableHeight) / 2;
cx = pl + (usableWidth / 2);
cy = pt + (usableHeight / 2);

lineLenght = radius - (pl * 2) - (pr * 2);
paint = new Paint();
paint.Color = Android.Graphics.Color.White;
paint.SetStyle(Paint.Style.Stroke);
paint.StrokeWidth = 5;
canvas.DrawCircle(cx, cy, radius - 5, paint);

Drawline(canvas, firstLineAngle);
Drawline(canvas, secondLineAngle);
Drawline(canvas, thirdLineAngle);

PostInvalidateDelayed(500);
Invalidate();
}

public void SaveCurrentAngles()
{
prevFirstLineAngle = this.firstLineAngle;
prevSecondLineAngle = this.secondLineAngle;
prevThirdLineAngle = this.thirdLineAngle;
}

public void Drawline(Canvas canvas, float angle)
{
float displacedAngle = angle - 90;
float x = cx + ((float)Math.Cos(degreesToRadians(displacedAngle)) * (radius - 5)); //convert angle to radians for x and y coordinates
float y = cy + ((float)Math.Sin(degreesToRadians(displacedAngle)) * (radius - 5));
canvas.DrawLine(cx, cy, x, y, paint); //draw a line from center point back to the point
}

public double degreesToRadians(double degrees)
{
return (degrees * Math.PI) / 180;
}
}

public class PieAnimation : Android.Views.Animations.Animation
{
private PieView pieView;

private float firstLineAngle;
private float secondLineAngle;
private float thirdLineAngle;

public PieAnimation(PieView pieView, float firstLineAngle, float secondLineAngle, float thirdLineAngle)
{
this.pieView = pieView;
pieView.saveCurrentAngles();
this.firstLineAngle = firstLineAngle;
this.secondLineAngle = secondLineAngle;
this.thirdLineAngle = thirdLineAngle;
}

protected override void ApplyTransformation(float interpolatedTime, Transformation t)
{
pieView.firstLineAngle = pieView.prevFirstLineAngle +
((firstLineangle - pieView.prevFirstLineAngle) * interpolatedTime);
pieView.secondLineAngle = pieView.prevSecondLineAngle +
((secondLineangle - pieView.prevSecondLineAngle) * interpolatedTime);
pieView.thirdLineAngle = pieView.prevThirdLineAngle +
((thirdLineangle - pieView.prevThirdLineAngle) * interpolatedTime);
pieView.RequestLayout();
}
}

public class TourPager : Java.Lang.Object, ViewPager.IOnPageChangeListener, ViewPager.IPageTransformer
{
private ViewPager mViewPager;

private float mLastOffset;
public TourView _context;

public TourPager(ViewPager viewpager, TourView context)
{
mViewPager = viewpager;
viewpager.AddOnPageChangeListener(this);
_context = context;
}

public void OnPageSelected(int position)
{
if (position == 0)
{
PieAnimation animation = new PieAnimation(_context._pieView, 0, 40, 120);
animation.Duration = (1000);
_context._pieView.StartAnimation(animation);
}
if (position==1)
{
PieAnimation animation = new PieAnimation(_context._pieView, 100, 140, 200);
animation.Duration=(1000);
_context._pieView.StartAnimation(animation);
}
if(position==2)
{
PieAnimation animation = new PieAnimation(_context._pieView, 180, 270, 10);
animation.Duration = (1000);
_context._pieView.StartAnimation(animation);
}
}
}

关于android - 如何在android中的 Canvas 上应用线条的旋转动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56280934/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com