简体   繁体   English

使用动画将div飞到另一个DOM位置

[英]Make div fly with animation to another DOM position

动画2个位置和大小之间的图像

I am moving an <img> element (the octopus) from the large gray <div> above ( #large ) to the small orange <div> below ( #small ) using 我正在将<img>元素(章鱼)从上面的大灰色<div>#large )移动到下面的小橙色<div>#small

$(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 我尝试添加CSS转换

img { transition: all 3s; }

to my <img> , but that won't work as the image is readded to the DOM and not moved. 到我的<img> ,但这不起作用,因为图像被读取到DOM而不是移动。

How can such animation be established? 如何建立这样的动画?

JS Fiddle JS小提琴

Using the jQuery .append method won't allow you to animate the element between the 2 states. 使用jQuery .append方法将不允许您在2个状态之间设置元素的动画。

Here is an example with an animation using CSS transition and the scale() function. 这是一个使用CSS转换和scale()函数的动画示例。 This example also uses the transform-origin property to change the position the of the image on the "big" state. 此示例还使用transform-origin属性来更改“大”状态下图像的位置。 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. 可以使这个响应(使用宽度,边距和填充的百分比值),但它需要更多的计算。

i made a responsive solution ( so i think ) using JQ . 我使用JQ制作了一个响应式解决方案(我认为)。 check it out below or in jsFiddle 检查下面或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 -20是因为div { margin-top:20px }`我计算了两个div相对于文档的TOP偏移量,然后得到了小div的宽度和高度

in the click function first i got the image's top offset so i could compare that with the #small's offset . 在点击功能中我首先获得了图像的顶部偏移量,因此我可以将其与#small的偏移量进行比较。

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 ) 因此,如果图像到顶部的距离小于#small到顶部的距离,则意味着img位于#large div中,因此我使用transform移动它:translate给它一个Y轴值等于TOP偏移量#small Div,所以img offset.top(iOffset)将等于#small offset.top(sOffset)

also adding width and height of the #small div to the image 还将#small div的宽度和高度添加到图像中

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% else(如果iOffset =或大于sOffset)则表示图像不在大div中,因此我需要将其转换回#large div的偏移并添加宽度:100%和高度: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> 

You need to compute the current dimensions of the image, the target dimensions, and calculate the needed transform. 您需要计算图像的当前尺寸,目标尺寸,并计算所需的变换。

To make it easier, I will calculate the transform needed to make the new element (the cloned one) look like it is still at the current position. 为了更容易,我将计算使新元素(克隆的元素)看起来仍然处于当前位置所需的转换。

Later, a standard animation (that just resets scale and position) will do the trick. 之后,标准动画(仅重置比例和位置)将起到作用。

I avoided using jQuery so the solution is easier to port 我避免使用jQuery,因此解决方案更容易移植

 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> 

appendto do not accept animations, but this question maybe helpful for you appendto不接受动画,但这个问题可能对你有所帮助

appendTo() animation appendTo()动画

Just add a transition and change the size and position to match the target. 只需添加转换并更改大小和位置以匹配目标。 On the transitionend event, append the image to the target element. transitionend事件上,将图像附加到目标元素。

 // 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM