Android 는 cos 와 sin 을 사용 하여 복합 곡선 애니메이션 을 그립 니 다.
지난 2 주 동안 새로운 수 요 를 개발 할 때 이런 애니메이션 을 디자인 했다.
어렵 지 않 아 요.한 번 에 못 알 아 봐 도 헤헤,디자인 원고 가 있 잖 아 요.
평소에 애니메이션 을 거의 쓰 지 않 는 안 드 로 이 드 개발 자로 서 느 린 곡선 디자인 원 고 를 보 았 을 때 제 마음 은 이 렇 습 니 다.
Android 애니메이션 의 기본 플러그 인 AccelerateDecelerateInterpolator 는 이렇게 느 린 효과 가 있 지만:
나 는 애니메이션 전 체 를 4 단 애니메이션 으로 뜯 어서 쓸 수 없다.내 가 처음 쓴 코드 는 정말 이렇게 한 것 은 말 할 것 도 없다.
일차 분석
한 줄 을 적 게 쓸 수 있 고 한 글자 도 더 쓰 지 않 는 다 는 원칙 에 따라 사내 동료 들 의 의견 을 물 었 고 큰 손 으로 흔 들 었 다.Path Interpolator(나중에 문제 가 있 음 이 확인 되 었 다).
사용법 을 간단히 살 펴 보 니 Path 를 사용 해 야 겠 어 요.다시 한 번 봤 어 요.녀석,베 세 르 곡선 을 사용 할 수도 있어 요.포기 하 세 요~
문 제 를 신속하게 해결 하기 위해 위 에서 언급 한 방안 을 사용 했다.
private fun animateTagView(tagView: TextView) {
// [0,200]
val valueAnimatorOne = ValueAnimator.ofInt(0, 200)
valueAnimatorOne.addUpdateListener {
val per = it.animatedValue as Int / 200f
tagView.rotation = 4 * per
tagView.scaleX = (1 - 0.1 * per).toFloat()
tagView.scaleY = (1 - 0.1 * per).toFloat()
}
valueAnimatorOne.duration = 200
// [200,560]
val valueAnimatorTwo = ValueAnimator.ofInt(200, 560)
valueAnimatorTwo.addUpdateListener {
val per = (it.animatedValue as Int - 200) / 360f
tagView.rotation = 3 - 11 * per
tagView.scaleX = (0.9 + 0.1 * per).toFloat()
tagView.scaleY = (0.9 + 0.1 * per).toFloat()
}
valueAnimatorTwo.duration = 360
// [560,840]
val valueAnimatorThree = ValueAnimator.ofInt(560, 840)
valueAnimatorThree.addUpdateListener {
val per = (it.animatedValue as Int - 560) / 280f
tagView.rotation = -8 + 12 * per
tagView.scaleX = (1 - 0.2 * per).toFloat()
tagView.scaleY = (1 - 0.2 * per).toFloat()
}
valueAnimatorThree.duration = 280
// [840,1000]
val valueAnimatorFour = ValueAnimator.ofInt(840, 1000)
valueAnimatorFour.addUpdateListener {
val per = (it.animatedValue as Int - 840) / 160f
tagView.rotation = 4 - 4 * per
tagView.scaleX = (0.8 + 0.2 * per).toFloat()
tagView.scaleY = (0.8 + 0.2 * per).toFloat()
}
valueAnimatorFour.duration = 160
// AnimatorSet
val animationSet = AnimatorSet()
animationSet.playSequentially(valueAnimatorOne, valueAnimatorTwo, valueAnimatorThree, valueAnimatorFour)
tagView.post {
tagView.pivotX = 0f
tagView.pivotY = ad_tag_two.measuredHeight.toFloat()
animationSet.start()
}
}
전체 애니메이션 은 저 에 게[0,200],[200,560],[560,840]과[840,1000]네 개의 속성 애니메이션 으로 분해 되 었 습 니 다.제품 은 한 번 만 재생 하면 된다 고 하기 때문에 Animator Set 을 사용 하여 애니메이션 을 조립 하면 문 제 를 해결 할 수 있 습 니 다.이차 분석
첫 번 째 로 얻 은 방안 은 문 제 를 해결 할 수 있 지만 순환 재생 에 부 딪 히 면 Animator Set 이 안 되 고 다른 방안 은 없 을 까?
주말 을 틈 타 Path Interpolator 를 배 웠 더 니 이 게임 도 문 제 를 해결 하지 못 하거나 문 제 를 해결 하지 못 한 다 는 것 을 알 게 되 었 다.3 단계 베 어 셀 곡선 으로 이 곡선 을 그 릴 수 있 지만 Path Interpolator 는 출발점 과 종점 이 각각(0,0)과(1,1)에 있 도록 요구 했다.
플러그 인 이 안 되 는 이상 평가 기 를 사용 해 보 세 요.하지만 하나의 평가 기 는 회전 과 크기 조정 두 가지 애니메이션 을 해결 할 수 없습니다.Animator UpdateListener 로 문 제 를 해결 해 야 할 것 같 습 니 다.
돌 이 켜 보면 플러그 인 은 균일 한 시간 부분 을 가속 또는 감속 하 는 행위 로 바 꾸 는 것 이다.우 리 는 균일 한 시간 부분 을 대응 하 는 곡선 으로 바 꿀 수 있다.두 가지 만 잘 하면 된다.
선형 플러그 인 LinearInterpolator 를 사용 합 니 다.
위의 곡선 을 나 누 어 서로 다른 sin 이나 cos 방법 으로 표현 합 니 다.
회전 애니메이션 을 예 로 들 면,분 리 된 sin 함수:
다른 애니메이션 의 함 수 는 코드 를 참고 할 수 있 습 니 다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tvContent = findViewById<TextView>(R.id.tv_content)
val valueAnimatorOne = ValueAnimator.ofFloat(0.0f, 1.5f)
valueAnimatorOne.addUpdateListener {
// sin cos rotation scale
val per = it.animatedValue as Float
var rotation: Float = 0f
var scale: Float = 0f
if(per >= 0 && per < 0.2f){
rotation = sin((per / 0.2f) * Math.PI.toFloat() - Math.PI.toFloat() / 2) * 1.5f + 1.5f
scale = cos(per / 0.2f * Math.PI.toFloat()) * 0.05f + 0.95f
}
if(per >= 0.2f && per < 0.56f){
rotation = sin(Math.PI.toFloat() / 2 + Math.PI.toFloat() * ( per - 0.2f) / 0.36f) * 5.5f - 2.5f
scale = cos((per - 0.2f) / 0.36f * Math.PI.toFloat() + Math.PI.toFloat()) * 0.05f + 0.95f
}
if(per >= 0.56f && per < 0.84f){
rotation = sin(Math.PI.toFloat() * (per - 0.56f) / 0.28f - Math.PI.toFloat() / 2) * 6f - 2f
scale = cos((per - 0.56f) / 0.28f * Math.PI.toFloat()) * 0.1f + 0.9f
}
if(per in 0.84f..1f){
rotation = sin(Math.PI.toFloat() / 2 + Math.PI.toFloat() * (per - 0.84f) / 0.16f ) * 2f + 2f
scale = cos((per - 0.84f) / 0.16f * Math.PI.toFloat() + Math.PI.toFloat()) * 0.1f + 0.9f
}
//
if(per > 1f && per <= 1.5f){
rotation = 0f
scale = 1.0f
}
tvContent.rotation = rotation
tvContent.scaleX = scale
tvContent.scaleY = scale
}
//
valueAnimatorOne.interpolator = LinearInterpolator()
//
valueAnimatorOne.duration = 1500
//
valueAnimatorOne.repeatCount = -1
tvContent.post {
//
tvContent.pivotX = 0f
tvContent.pivotY = tvContent.measuredHeight.toFloat()
valueAnimatorOne.start()
}
}
전체 코드 는 비교적 간단 합 니 다.회전 애니메이션 곡선 은 sin 에서 나 오고 크기 는 cos 에서 나 오 며 마지막 으로 중심 점 을 바 꿉 니 다.총결산
이번 애니메이션 사례 는 어렵 지 않 습 니 다.복합 적 으로 느 린 곡선 으로 들 어 가 는 상황 에서 우 리 는 한 단락 으로 뜯 어서 sin 이나 cos 로 설명 할 수 있 습 니 다.이런 장점 은 하나의 속성 애니메이션 만 사용 할 수 있 고 순환 적 으로 재생 할 수 있 습 니 다.
만약 당신 이 더 좋 은 방안 이 있다 면,평론 구역 의 교 류 를 환영 합 니 다.
이상 은 안 드 로 이 드 가 cos 와 sin 을 사용 하여 복합 곡선 애니메이션 을 그 리 는 상세 한 내용 입 니 다.안 드 로 이 드 가 복합 곡선 애니메이션 을 그 리 는 것 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.