Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make div fly with animation to another DOM position

animating an image between 2 positions and sizes

I am moving an <img> element (the octopus) from the large gray <div> above (#large) to the small orange <div> below (#small) using

$(document).on("click", "#large > img", function() {
  $(this).appendTo("#small");
});

This works great but I want it to transition smoothly and to 'fly' over so it will slowly interpolate its coordinates and size.

I tried adding a CSS transition

img { transition: all 3s; }

to my <img>, but that won't work as the image is readded to the DOM and not moved.

How can such animation be established?

JS Fiddle

like image 747
Frithjof Avatar asked Apr 28 '17 12:04

Frithjof


2 Answers

Using the jQuery .append method won't allow you to animate the element between the 2 states.

Here is an example with an animation using CSS transition and the scale() function. This example also uses the transform-origin property to change the position the of the image on the "big" state. Fiddle here.

$(document).on("click", "img", function() {
  $(this).toggleClass("big");
});
div {
  margin: 20px;
  padding: 10px;
}

#large {
  width: 600px;
  height: 400px;
  background-color: gray;
}

#small {
  width: 120px;
  height: 90px;
  background-color: orange;
}

img {
  width: 100%;
  height: 100%;
  transition: transform .3s ease-out;
  transform-origin: 0 129px;
}

img.big {
  transform: scaleX(5) scaleY(4.4);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="large">

</div>
<div id="small">
  <img src="https://ak.picdn.net/assets/cms/5bb580387901a83212e3028ab5a2fa8fb1153d7b-img_offset_2x.jpg" />
</div>

Note that :

  • you will need to add vendor prefixes to the transition, transform and transform-origin properties depending on the browsers you need to support.
  • this technique relies on the fact you are using hard values (in pixels). It would be possible to make this responsive (using percent values for widths, margins and paddings) but it will need more calculations.
like image 199
web-tiki Avatar answered Sep 19 '22 01:09

web-tiki


i made a responsive solution ( so i think ) using JQ . check it out below or in jsFiddle

first i cached all the necessary selectors for cleaner and concise code .

the -20 is because of the div { margin-top:20px}` there i calculated the TOP offset of both divs in relation to the document, then got the width and height of the small div

in the click function first i got the image's top offset so i could compare that with the #small's offset .

so if the image's distance to top is smaller than the #small's distance to top, it means that the img is in the #large div and so i move it using transform:translate giving it an Y-axis value equal to the TOP offset of the #small Div, so the img offset.top ( iOffset ) will become equal to the #small offset.top ( sOffset )

also adding width and height of the #small div to the image

else ( if iOffset is = or bigger than sOffset ) then it means that the image is not in the large div, so i need to translate it back to the offset of the #large div and add width:100% and height:100%

hope i got it right and explained correctly. let me know if it helps

var Large = $("#large"),
  Small = $("#small"),
  lOffset = $(Large).offset().top - 20 + 'px',
  sOffset = $(Small).offset().top - 20 + 'px',
  sWidth = $(Small).width(),
  sHeight = $(Small).height()

$(document).on("click", "img", function() {
  var iOffset = $(this).offset().top + 'px'
  if (iOffset < sOffset) {
    $(this).css('transform', 'translate(0,' + sOffset + ')')
      .width(sWidth).height(sHeight)
  } else {
    $(this).css('transform', 'translate(0,' + lOffset + ')')
      .width("100%").height("100%")
  }
})
div {
  margin: 20px;
  padding: 10px;
}

#large {
  width: 600px;
  height: 400px;
  background-color: gray;
}

#small {
  width: 120px;
  height: 90px;
  background-color: orange;
}

img {
  width: 100%;
  height: 100%;
  transition: 5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="large">
  <img src="https://ak.picdn.net/assets/cms/5bb580387901a83212e3028ab5a2fa8fb1153d7b-img_offset_2x.jpg" />
</div>
<div id="small">
</div>
like image 33
Mihai T Avatar answered Sep 19 '22 01:09

Mihai T