Make div fly with animation to another DOM position

animation of an image between two positions and sizes

I move the <img> (octopus) element 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 fine, but I want it to smoothly transition and fly so that it slowly interpolates its coordinates and size .

I tried adding CSS transition

 img { transition: all 3s; } 

for my <img> , but this will not work, as the image will be converted to the DOM and will not be moved.

How can I create such an animation?

Js fiddle

+5
source share
5 answers

Using jQuery's .append method .append not let you animate an element between two states.

Here's an example of an animation using a CSS transition and the scale() function. This example also uses the transform-origin property to reposition the image in the "large" state. Here is the script .

 $(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, conversion, and transformation-origin properties depending on the browsers you need to support.
  • This method is based on the fact that you use hard values ​​(in pixels). It would be possible to make this responsive (using percentages for width, margin, and padding), but this will require more calculations.
+6
source

I made a responsive decision (I think so) using JQ. check it below or in jsFiddle

First, I cached all the necessary selectors for cleaner and more concise code.

-20 is due to div { margin-top:20px } `there I calculated the upper offset of both divs relative to the document, and then got the width and height of the small div

in the click function, I first got the top offset of the image, so I could compare this to C # small offset.

so if the distance to the top is less than # a small distance to the top, this means that img is in the #large div, and therefore I move it with transform: translate, giving it the Y axis value equal to TOP offset #small Div, therefore img offset.top (iOffset) becomes equal to #small offset.top (sOffset)

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

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

I hope I understood this correctly and correctly explained. let me know if that 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> 
+2
source

You need to calculate the current image sizes, target sizes and calculate the necessary conversion.

To keep things simple, I calculated the transformation needed to create a new element (cloned), it looks like it is still in its current position.

Later, the standard animation (which simply resets the scale and position) will do the trick.

I avoided using jQuery, so the solution is easier to port

 function func (target) { var image = document.getElementById('image'); var current = image.parentNode; var rectImage = current.getBoundingClientRect(); var rectTarget = target.getBoundingClientRect(); evalRect (rectImage); evalRect (rectTarget); var scaleX = rectImage.width / rectTarget.width; var scaleY = rectImage.height / rectTarget.height; var translateX = rectImage.centerX - rectTarget.centerX; var translateY = rectImage.centerY - rectTarget.centerY; var dup = image.cloneNode(); var scale = 'scale(' + scaleX + ', ' + scaleY + ') '; var translate = 'translate(' + translateX + 'px, ' + translateY + 'px) '; target.appendChild(dup); dup.style.transform = translate + scale; current.removeChild(image); } function evalRect (rect) { rect.centerX = rect.left + rect.width * 0.5; rect.centerY = rect.top + rect.height * 0.5; } 
 .container { border: solid 1px black; position: relative; display: inline-block; } #container1 { width: 200px; height: 100px; } #container2 { width: 400px; height: 200px; } #container3 { width: 200px; height: 200px; } #image { background: linear-gradient(45deg, yellow, tomato); width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; animation: adjust 1s forwards; } @keyframes adjust { to {transform: translate(0px, 0px);} } 
 <div id="container1" class="container" onclick="func(this)">click me <div id="image"></div> </div> <div id="container2" class="container" onclick="func(this)">click me</div> <div id="container3" class="container" onclick="func(this)">click me</div> 
+2
source

appendto does not accept animations, but this question may be useful to you.

appendTo () animation

0
source

Just add a transition and resize and position them to fit the purpose. In the transitionend event, add the image to the target element.

 // when transition completes $('img').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){ // place in container $('#target').append($('img')); // set to corner of container $('img').css({ top: '0', left: '0' }); }); // position in corner of target and make size the same $('img').css({ position: 'absolute', top: $('#target').offset().top + 'px', left: $('#target').offset().left + 'px', height: $('#target').css('height'), width: $('#target').css('width') }); 
 #target { height: 150px; width: 150px; border: 1px solid grey; position: absolute; top: 350px; left: 5px; z-index: 1; } img { position: absolute; top: 0; left: 5px; transition: all 1s; height: 300px; width: 300px; z-index: 5; } 
 <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=300%C3%97300&w=300&h=300" /> <div id="target"> </div> 
-1
source

Source: https://habr.com/ru/post/1267281/


All Articles