List of usage examples for android.view View animate
public ViewPropertyAnimator animate()
From source file:com.npi.muzeiflickr.ui.activities.SettingsActivity.java
private void populateFooter(View footerView) { final View footerButton = footerView.findViewById(R.id.list_footer_button); final Spinner footerModeChooser = (Spinner) footerView.findViewById(R.id.mode_chooser); final RelativeLayout addItemContainer = (RelativeLayout) footerView.findViewById(R.id.new_item_container); final ImageButton footerSearchButton = (ImageButton) footerView.findViewById(R.id.footer_search_button); final ProgressBar footerProgress = (ProgressBar) footerView.findViewById(R.id.footer_progress); final EditText footerTerm = (EditText) footerView.findViewById(R.id.footer_term); footerButton.setOnLongClickListener(new View.OnLongClickListener() { @Override/* w ww. j av a 2 s .co m*/ public boolean onLongClick(View v) { int[] pos = new int[2]; footerButton.getLocationInWindow(pos); String contentDesc = footerButton.getContentDescription().toString(); Toast t = Toast.makeText(SettingsActivity.this, contentDesc, Toast.LENGTH_SHORT); t.show(); t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, pos[1] + (footerButton.getHeight() / 2)); return true; } }); footerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addItemContainer.animate().alpha(1F); footerButton.animate().alpha(0F); } }); //Mode spinner management ArrayAdapter<CharSequence> adapter = new SourceSpinnerAdapter(this, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.modes)); footerModeChooser.setAdapter(adapter); footerSearchButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String searchString = footerTerm.getText().toString(); switch (footerModeChooser.getSelectedItemPosition()) { case 0: //It's a search //Looking for a same existing search List<Search> searchs = Search.listAll(Search.class); for (Search search : searchs) { if (search.getTitle().equals(searchString)) { Toast.makeText(SettingsActivity.this, getString(R.string.search_exists), Toast.LENGTH_LONG).show(); return; } } footerSearchButton.setVisibility(View.GONE); footerProgress.setVisibility(View.VISIBLE); getSearch(searchString, new UserInfoListener<Search>() { @Override public void onSuccess(Search search) { mRequestAdapter.add(search); mRequestAdapter.notifyDataSetChanged(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); footerTerm.setText(""); footerModeChooser.setSelection(0); addItemContainer.animate().alpha(0F); footerButton.animate().alpha(1F); } @Override public void onError(String reason) { Toast.makeText(SettingsActivity.this, reason, Toast.LENGTH_LONG).show(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); } }); break; case 1: //It's an user //Looking for a same existing search List<User> users = User.listAll(User.class); for (User user : users) { if (user.getTitle().equals(searchString)) { Toast.makeText(SettingsActivity.this, getString(R.string.user_exists), Toast.LENGTH_LONG).show(); return; } } footerSearchButton.setVisibility(View.GONE); footerProgress.setVisibility(View.VISIBLE); getUserId(searchString, new UserInfoListener<User>() { @Override public void onSuccess(User user) { mRequestAdapter.add(user); mRequestAdapter.notifyDataSetChanged(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); footerTerm.setText(""); footerModeChooser.setSelection(0); addItemContainer.animate().alpha(0F); footerButton.animate().alpha(1F); } @Override public void onError(String reason) { Toast.makeText(SettingsActivity.this, reason, Toast.LENGTH_LONG).show(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); } }); break; case 2: //It's a tag //Looking for a same existing search List<Tag> tags = Tag.listAll(Tag.class); for (Tag tag : tags) { if (tag.getTitle().equals(searchString)) { Toast.makeText(SettingsActivity.this, getString(R.string.user_exists), Toast.LENGTH_LONG).show(); return; } } footerSearchButton.setVisibility(View.GONE); footerProgress.setVisibility(View.VISIBLE); getTag(searchString, new UserInfoListener<Tag>() { @Override public void onSuccess(Tag tag) { mRequestAdapter.add(tag); mRequestAdapter.notifyDataSetChanged(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); footerTerm.setText(""); footerModeChooser.setSelection(0); addItemContainer.animate().alpha(0F); footerButton.animate().alpha(1F); } @Override public void onError(String reason) { Toast.makeText(SettingsActivity.this, reason, Toast.LENGTH_LONG).show(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); } }); break; case 3: //It's an user //Looking for a same existing search List<FGroup> groups = FGroup.listAll(FGroup.class); for (FGroup group : groups) { if (group.getTitle().equals(searchString)) { Toast.makeText(SettingsActivity.this, getString(R.string.group_exists), Toast.LENGTH_LONG).show(); return; } } footerSearchButton.setVisibility(View.GONE); footerProgress.setVisibility(View.VISIBLE); getGroupId(searchString, new UserInfoListener<FGroup>() { @Override public void onSuccess(FGroup group) { mRequestAdapter.add(group); mRequestAdapter.notifyDataSetChanged(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); footerTerm.setText(""); footerModeChooser.setSelection(0); addItemContainer.animate().alpha(0F); footerButton.animate().alpha(1F); } @Override public void onError(String reason) { Toast.makeText(SettingsActivity.this, reason, Toast.LENGTH_LONG).show(); footerSearchButton.setVisibility(View.VISIBLE); footerProgress.setVisibility(View.GONE); } }); break; } } }); }
From source file:ru.gkpromtech.exhibition.media.FullImageActivity.java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_full_image); Bundle extras = getIntent().getExtras(); items = (List<Media>) extras.getSerializable("items"); files = (List<String>) extras.getSerializable("files"); int index = extras.getInt("index"); if (items != null) mode = SHOW_ITEMS_MODE;/*from w ww. ja v a 2 s.c o m*/ else if (files != null) mode = SHOW_FILES_MODE; final View controlsView = findViewById(R.id.fullscreen_content_controls); final ViewPager pager = (ViewPager) findViewById(R.id.pager); appDirectoryName = getResources().getString(R.string.app_name); imageRoot = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appDirectoryName); // ViewPager and its adapters use support library // fragments, so use getSupportFragmentManager. pager.setAdapter(new FullImagePagerAdapter(getSupportFragmentManager())); pager.setCurrentItem(index); if (mode == SHOW_ITEMS_MODE) setTitle(items.get(index).name); else if (mode == SHOW_FILES_MODE) setTitle(new File(files.get(index)).getName()); else setTitle("Photo"); // Set up an instance of SystemUiHider to control the system UI for // this activity. mSystemUiHider = SystemUiHider.getInstance(this, pager, HIDER_FLAGS); mSystemUiHider.setup(); mSystemUiHider.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() { // Cached values. int mControlsHeight; int mShortAnimTime; @Override public void onVisibilityChange(boolean visible) { // If the ViewPropertyAnimator API is available // (Honeycomb MR2 and later), use it to animate the // in-layout UI controls at the bottom of the // screen. if (mControlsHeight == 0) { mControlsHeight = controlsView.getHeight(); } if (mShortAnimTime == 0) { mShortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); } controlsView.animate().translationY(visible ? 0 : mControlsHeight).setDuration(mShortAnimTime); if (visible && AUTO_HIDE) { // Schedule a hide(). delayedHide(AUTO_HIDE_DELAY_MILLIS); } } }); pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i2) { } @Override public void onPageSelected(int index) { if (mode == SHOW_ITEMS_MODE) setTitle(items.get(index).name); else if (mode == SHOW_FILES_MODE) setTitle(new File(files.get(index)).getName()); else setTitle("Photo"); } @Override public void onPageScrollStateChanged(int i) { } }); // Upon interacting with UI controls, delay any scheduled hide() // operations to prevent the jarring behavior of controls going away // while interacting with the UI. pager.setOnTouchListener(mDelayHideTouchListener); }
From source file:com.evandroid.musica.fragment.LocalLyricsFragment.java
public void animateUndo(Lyrics[] lyricsArray) { final HashMap<Long, Integer> itemIdTopMap = new HashMap<>(); int firstVisiblePosition = megaListView.getFirstVisiblePosition(); for (int i = 0; i < megaListView.getChildCount(); ++i) { View child = megaListView.getChildAt(i); int position = firstVisiblePosition + i; long itemId = megaListView.getAdapter().getItemId(position); itemIdTopMap.put(itemId, child.getTop()); }//from ww w.j av a2s . c o m final boolean[] firstAnimation = { true }; // Delete the item from the adapter final int groupPosition = ((LocalAdapter) getExpandableListAdapter()).add(lyricsArray[0]); megaListView.setAdapter(getExpandableListAdapter()); megaListView.post(new Runnable() { @Override public void run() { megaListView.expandGroupWithAnimation(groupPosition); } }); new WriteToDatabaseTask(LocalLyricsFragment.this).execute(LocalLyricsFragment.this, null, lyricsArray); final ViewTreeObserver[] observer = { megaListView.getViewTreeObserver() }; observer[0].addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { observer[0].removeOnPreDrawListener(this); firstAnimation[0] = true; int firstVisiblePosition = megaListView.getFirstVisiblePosition(); for (int i = 0; i < megaListView.getChildCount(); ++i) { final View child = megaListView.getChildAt(i); int position = firstVisiblePosition + i; long itemId = getListView().getAdapter().getItemId(position); Integer formerTop = itemIdTopMap.get(itemId); int newTop = child.getTop(); if (formerTop != null) { if (formerTop != newTop) { int delta = formerTop - newTop; child.setTranslationY(delta); int MOVE_DURATION = 500; child.animate().setDuration(MOVE_DURATION).translationY(0); if (firstAnimation[0]) { child.animate().setListener(new AnimatorActionListener(new Runnable() { public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; getListView().setEnabled(true); } }, AnimatorActionListener.ActionType.END)); firstAnimation[0] = false; } } } else { // Animate new views along with the others. The catch is that they did not // exist in the start state, so we must calculate their starting position // based on neighboring views. int childHeight = child.getHeight() + megaListView.getDividerHeight(); formerTop = newTop - childHeight; int delta = formerTop - newTop; final float z = ((CardView) child).getCardElevation(); ((CardView) child).setCardElevation(0f); child.setTranslationY(delta); final int MOVE_DURATION = 500; child.animate().setDuration(MOVE_DURATION).translationY(0); child.animate().setListener(new AnimatorActionListener(new Runnable() { public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; getListView().setEnabled(true); ObjectAnimator anim = ObjectAnimator.ofFloat(child, "cardElevation", 0f, z); anim.setDuration(200); anim.setInterpolator(new AccelerateInterpolator()); anim.start(); } }, AnimatorActionListener.ActionType.END)); firstAnimation[0] = false; } } if (firstAnimation[0]) { mBackgroundContainer.hideBackground(); mSwiping = false; getListView().setEnabled(true); firstAnimation[0] = false; } itemIdTopMap.clear(); return true; } }); }
From source file:com.google.android.apps.muzei.settings.ChooseSourceFragment.java
@Override public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) { // Ensure we have the latest insets view.requestFitSystemWindows();//w w w. j a v a 2 s. co m mScrollbar = view.findViewById(R.id.source_scrollbar); mSourceScrollerView = view.findViewById(R.id.source_scroller); mSourceScrollerView.setCallbacks(new ObservableHorizontalScrollView.Callbacks() { @Override public void onScrollChanged(int scrollX) { showScrollbar(); } @Override public void onDownMotionEvent() { if (mCurrentScroller != null) { mCurrentScroller.cancel(); mCurrentScroller = null; } } }); mSourceContainerView = view.findViewById(R.id.source_container); redrawSources(); view.setVisibility(View.INVISIBLE); view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { int mPass = 0; @Override public void onGlobalLayout() { if (mPass == 0) { // First pass updatePadding(); ++mPass; } else if (mPass == 1 & mSelectedSourceIndex >= 0) { // Second pass mSourceScrollerView.setScrollX(mItemWidth * mSelectedSourceIndex); showScrollbar(); view.setVisibility(View.VISIBLE); ++mPass; } else { // Last pass, remove the listener view.getViewTreeObserver().removeOnGlobalLayoutListener(this); } } }); view.setAlpha(0); view.animate().alpha(1f).setDuration(500); }
From source file:com.irccloud.android.fragment.MessageViewFragment.java
private void hideView(final View v) { if (v.getVisibility() != View.GONE) { if (Build.VERSION.SDK_INT >= 16) { v.animate().alpha(0).setDuration(100).withEndAction(new Runnable() { @Override//from ww w .jav a 2 s . co m public void run() { v.setVisibility(View.GONE); } }); } else { v.setVisibility(View.GONE); } } }
From source file:com.waz.zclient.pages.main.conversation.ConversationFragment.java
private void openPreview(View containerPreview) { isPreviewShown = true;/*from w ww .jav a2s . c o m*/ getControllerFactory().getNavigationController().setPagerEnabled(false); containerPreview.setTranslationY(getView().getMeasuredHeight()); containerPreview.animate().translationY(0) .setDuration(getResources().getInteger(R.integer.animation_duration_medium)) .setInterpolator(new Expo.EaseOut()); }
From source file:com.irccloud.android.fragment.MessageViewFragment.java
private void showView(final View v) { if (v.getVisibility() != View.VISIBLE) { if (Build.VERSION.SDK_INT >= 16) { v.setAlpha(0);//from www .j ava2s . c o m v.animate().alpha(1).setDuration(100); } v.setVisibility(View.VISIBLE); } }
From source file:com.fastbootmobile.encore.app.fragments.PlaybackQueueFragment.java
public PlaybackQueueFragment() { mHandler = new PlaybackQueueHandler(new WeakReference<>(this)); mPlayFabClickListener = new View.OnClickListener() { @Override// w ww. ja v a2 s. co m public void onClick(View v) { switch (PlaybackProxy.getState()) { case PlaybackService.STATE_PAUSED: case PlaybackService.STATE_STOPPED: case PlaybackService.STATE_PAUSING: PlaybackProxy.play(); break; case PlaybackService.STATE_BUFFERING: case PlaybackService.STATE_PLAYING: PlaybackProxy.pause(); break; } } }; mNextClickListener = new View.OnClickListener() { @Override public void onClick(View v) { PlaybackProxy.next(); } }; mPreviousClickListener = new View.OnClickListener() { @Override public void onClick(View v) { PlaybackProxy.previous(); } }; mSeekListener = new SeekBar.OnSeekBarChangeListener() { private int mStartProgress; @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { mLockSeekBarUpdate = true; mStartProgress = seekBar.getProgress(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { mLockSeekBarUpdate = false; int endProgress = seekBar.getProgress(); if (endProgress != mStartProgress) { PlaybackProxy.seek(endProgress); } } }; mRepeatClickListener = new View.OnClickListener() { @Override public void onClick(View v) { boolean currentMode = PlaybackProxy.isRepeatMode(); boolean newMode = !currentMode; PlaybackProxy.setRepeatMode(newMode); v.animate().rotationBy(-360).setDuration(600).start(); if (newMode) { ((ImageView) v).setImageResource(R.drawable.ic_replay); } else { ((ImageView) v).setImageResource(R.drawable.ic_replay_gray); } } }; mShuffleClickListener = new View.OnClickListener() { @Override public void onClick(View v) { boolean currentMode = PlaybackProxy.isShuffleMode(); boolean newMode = !currentMode; PlaybackProxy.setShuffleMode(newMode); if (newMode) { ((ImageView) v).setImageResource(R.drawable.ic_shuffle); } else { ((ImageView) v).setImageResource(R.drawable.ic_shuffle_gray); } } }; mLikeClickListener = new View.OnClickListener() { @Override public void onClick(View v) { ListenLogger logger = new ListenLogger(getActivity()); PlaybackQueueAdapter.ViewHolder tag = (PlaybackQueueAdapter.ViewHolder) v.getTag(); boolean isLiked = logger.isLiked(tag.song.getRef()); if (isLiked) { logger.removeLike(tag.song); ((ImageView) v).setImageResource(R.drawable.ic_thumbs_up_gray); } else { logger.addLike(tag.song); final AutoMixBucket bucket = AutoMixManager.getDefault().getCurrentPlayingBucket(); if (bucket != null) { new Thread() { public void run() { try { bucket.notifyLike(); } catch (EchoNestException e) { Log.e(TAG, "Unable to notify like event to EchoNest"); } } }.start(); } ((ImageView) v).setImageResource(R.drawable.ic_thumbs_up); } } }; mDislikeClickListener = new View.OnClickListener() { @Override public void onClick(View v) { ListenLogger logger = new ListenLogger(getActivity()); PlaybackQueueAdapter.ViewHolder tag = (PlaybackQueueAdapter.ViewHolder) v.getTag(); boolean isDisliked = logger.isDisliked(tag.song.getRef()); if (isDisliked) { logger.removeDislike(tag.song); ((ImageView) v).setImageResource(R.drawable.ic_thumb_down_gray); } else { logger.addDislike(tag.song); final AutoMixBucket bucket = AutoMixManager.getDefault().getCurrentPlayingBucket(); if (bucket != null) { new Thread() { public void run() { try { bucket.notifyDislike(); } catch (EchoNestException e) { Log.e(TAG, "Unable to notify dislike event to EchoNest"); } } }.start(); } ((ImageView) v).setImageResource(R.drawable.ic_thumb_down); } } }; mAlbumArtClickListener = new View.OnClickListener() { @Override @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void onClick(View v) { PlaybackQueueAdapter.ViewHolder tag = (PlaybackQueueAdapter.ViewHolder) v.getTag(); if (tag.song.getAlbum() != null) { Bitmap hero = ((MaterialTransitionDrawable) tag.ivAlbumArt.getDrawable()).getFinalDrawable() .getBitmap(); Intent intent = AlbumActivity.craftIntent(getActivity(), hero, tag.song.getAlbum(), tag.song.getProvider(), 0xFF333333); if (Utils.hasLollipop()) { ActivityOptions opts = ActivityOptions.makeSceneTransitionAnimation(getActivity(), v, "itemImage"); getActivity().startActivity(intent, opts.toBundle()); } else { startActivity(intent); } } else { Toast.makeText(getActivity(), R.string.toast_song_no_album, Toast.LENGTH_SHORT).show(); } } }; }
From source file:com.android.incallui.CallCardFragment.java
/** * Sets the visibility of the primary call card. * Ensures that when the primary call card is hidden, the video surface slides over to fill the * entire screen.//from ww w. ja v a 2 s. c o m * * @param visible {@code True} if the primary call card should be visible. */ @Override public void setCallCardVisible(final boolean visible) { Log.v(this, "setCallCardVisible : isVisible = " + visible); // When animating the hide/show of the views in a landscape layout, we need to take into // account whether we are in a left-to-right locale or a right-to-left locale and adjust // the animations accordingly. final boolean isLayoutRtl = InCallPresenter.isRtl(); // Retrieve here since at fragment creation time the incoming video view is not inflated. final View videoView = getView().findViewById(R.id.incomingVideo); if (videoView == null) { return; } // Determine how much space there is below or to the side of the call card. final float spaceBesideCallCard = getSpaceBesideCallCard(); // We need to translate the video surface, but we need to know its position after the layout // has occurred so use a {@code ViewTreeObserver}. final ViewTreeObserver observer = getView().getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // We don't want to continue getting called. getView().getViewTreeObserver().removeOnPreDrawListener(this); float videoViewTranslation = 0f; // Translate the call card to its pre-animation state. if (!mIsLandscape) { mPrimaryCallCardContainer.setTranslationY(visible ? -mPrimaryCallCardContainer.getHeight() : 0); ViewGroup.LayoutParams p = videoView.getLayoutParams(); videoViewTranslation = p.height / 2 - spaceBesideCallCard / 2; } // Perform animation of video view. ViewPropertyAnimator videoViewAnimator = videoView.animate() .setInterpolator(AnimUtils.EASE_OUT_EASE_IN).setDuration(mVideoAnimationDuration); if (mIsLandscape) { videoViewAnimator.translationX(visible ? videoViewTranslation : 0); } else { videoViewAnimator.translationY(visible ? videoViewTranslation : 0); } videoViewAnimator.start(); // Animate the call card sliding. ViewPropertyAnimator callCardAnimator = mPrimaryCallCardContainer.animate() .setInterpolator(AnimUtils.EASE_OUT_EASE_IN).setDuration(mVideoAnimationDuration) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (!visible) { mPrimaryCallCardContainer.setVisibility(View.GONE); } } @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); if (visible) { mPrimaryCallCardContainer.setVisibility(View.VISIBLE); } } }); if (mIsLandscape) { float translationX = mPrimaryCallCardContainer.getWidth(); translationX *= isLayoutRtl ? 1 : -1; callCardAnimator.translationX(visible ? 0 : translationX).start(); } else { callCardAnimator.translationY(visible ? 0 : -mPrimaryCallCardContainer.getHeight()).start(); } return true; } }); }
From source file:com.app.afteryou.ui.staggered.StaggeredGridView.java
private void performAnimation() { if (!mViewCacheForAnim.isEmpty()) { isAnimating = true;//from w w w . j a v a 2s.c o m int count = mViewCacheForAnim.size(); final View view = mViewCacheForAnim.remove(0); Rect rect = new Rect(); this.getGlobalVisibleRect(rect); int fly_distance = (int) (rect.height()); float top = view.getY(); float bottom = view.getY() + view.getMeasuredHeight(); float startTop = top + fly_distance; float startBottom = bottom + fly_distance; int bufferDis = rect.height() / 4; if (startBottom < 0) { Log.d(TAG, "No animation as the view is passed!!"); view.setVisibility(View.VISIBLE); performAnimation(); return; } else if (startTop < rect.height()) { fly_distance += (rect.height() - startTop + bufferDis); } if (fly_distance > rect.height() * 2) { Log.d(TAG, "No animation as the fly distance is too long!"); view.setVisibility(View.VISIBLE); performAnimation(); return; } else if (fly_distance < rect.height()) { fly_distance = rect.height(); } view.setTranslationY(fly_distance); long delay = FLY_IN_DELAY / count; long duration = delay > FLY_IN_DURATION ? FLY_IN_DURATION : delay; view.animate().setDuration(duration).setInterpolator(new DecelerateInterpolator()) .setListener(new AnimatorListenerAdapter() { public void onAnimationStart(Animator anim) { view.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animator anim) { view.clearAnimation(); view.setTranslationY(0f); performAnimation(); } }).translationY(0); } else { isAnimating = false; } }