图片/图形

基于滚动的超酷js图片动画特效

阿里云


这是一款基于滚动的超酷 js 图片动画特效。该特效在使用鼠标滚动屏幕时,根据屏幕的当前位置,屏幕上的图片做出相应的动画效果,非常炫酷。

HTML 结构

  1. <div class="container">
  2.   <div class="image"></div>
  3.   <div class="image"></div>
  4.   <div class="image"></div>
  5.   <div class="image"></div>
  6.   <div class="image"></div>
  7.   <div class="image"></div>
  8.   <div class="image"></div>
  9.   <div class="image"></div>
  10.   <div class="image"></div>
  11.   <div class="image"></div>
  12. </div>
也想出现在这里?联系我们
创客主机

CSS 样式

  1. // The container for all images
  2. .container {
  3.   // 2 columns grid
  4.   display: grid;
  5.   grid-template-columns: 1fr 1fr;
  6.   grid-gap: 0 10%;
  7.   justify-items: end; // This will align all items (images) to the right
  8.  
  9.   // Fixed positioned, so it won't be affected by default scroll
  10.   // It will be moved using `transform`, to achieve a custom scroll behavior
  11.   position: fixed;
  12.   top: 0;
  13.   left: 0;
  14.   width: 100%;
  15. }
  16. // Styles for image elements
  17. // Mainly positioning and background styles
  18. .image {
  19.   position: relative;
  20.   width: 300px;
  21.   height: 100vh;
  22.   background-repeat: no-repeat;
  23.   background-position: center;
  24.  
  25.   // This will align all even images to the left
  26.   // For getting centered positioned images, respect to the viewport
  27.   &:nth-child(2n) {
  28.     justify-self: start;
  29.   }
  30.  
  31.   // Set each `background-image` using a SCSS `for` loop
  32.   @for $i from 1 through 10 {
  33.     &:nth-child(#{$i}) {
  34.       background-image: url('../img/image#{$i}.jpg');
  35.     }
  36.   }
  37. }
  38. // Adjusting layout for small screens
  39. @media screen and (max-width: 760px) {
  40.   .container {
  41.     // 1 column grid
  42.     grid-template-columns: 1fr;
  43.     // Fix image centering
  44.     justify-items: center;
  45.   }
  46.  
  47.   // Fix image centering
  48.   .image:nth-child(2n) {
  49.     justify-self: center;
  50.   }
  51. }

javascript

  1. // Easing function used for `translateX` animation
  2. // From: https://gist.github.com/gre/1650294
  3. function easeOutQuad (t) {
  4.   return t *_ (2 - t)
  5. }
  6.  
  7. // Returns a random number (integer) between __`min`__ and __`max`__
  8. function random (min, max) {
  9.   return Math.floor(Math.random() * (max - min + 1)) + min_
  10. }
  11.  
  12. // Returns a random number as well, but it could be negative also
  13. function randomPositiveOrNegative (min, max) {
  14.   return random(min, max) * (Math.random() > 0.5 ? 1 : -1)
  15. }
  16.  
  17. // Set CSS `tranform` property for an element
  18. function setTransform (el, transform) {
  19.   el.style.transform = transform
  20.   el.style.WebkitTransform = transform
  21. }
  22. // Current scroll position
  23. var current = 0
  24. // Target scroll position
  25. var target = 0
  26. // Ease or speed for moving from `current` to `target`
  27. var ease = 0.075
  28. // Utility variables for `requestAnimationFrame`
  29. var rafId = undefined
  30. var rafActive = false
  31. // Container element
  32. var container = document.querySelector('.container')
  33. // Array with `.image` elements
  34. var images = Array.prototype.slice.call(document.querySelectorAll('.image'))
  35. // Variables for storing dimmensions
  36. var windowWidth, containerHeight, imageHeight
  37.  
  38. // Variables for specifying transform parameters (max limits)
  39. var rotateXMaxList = []
  40. var rotateYMaxList = []
  41. var translateXMax = -200
  42.  
  43. // Popullating the `rotateXMaxList` and `rotateYMaxList` with random values
  44. images.forEach(function () {
  45.   rotateXMaxList.push(randomPositiveOrNegative(20, 40))
  46.   rotateYMaxList.push(randomPositiveOrNegative(20, 60))
  47. })
  48. // The `fakeScroll` is an element to make the page scrollable
  49. // Here we are creating it and appending it to the `body`
  50. var fakeScroll = document.createElement('div')
  51. fakeScroll.className = 'fake-scroll'
  52. document.body.appendChild(fakeScroll)
  53. // In the `setupAnimation` function (below) we will set the `height` properly
  54. // The styles for a `div` element (inserted with Javascript)
  55. // Used to make the page scrollable
  56. // Will be setted a proper `height` value using Javascript
  57. .fake-scroll {
  58.   position: absolute;
  59.   top: 0;
  60.   width: 1px;
  61. }
  62. // Geeting dimmensions and setting up all for animation
  63. function setupAnimation () {
  64.   // Updating dimmensions
  65.   windowWidth = window.innerWidth
  66.   containerHeight = container.getBoundingClientRect().height
  67.   imageHeight = containerHeight / (windowWidth > 760 ? images.length / 2 : images.length)
  68.   // Set `height` for the fake scroll element
  69.   fakeScroll.style.height = containerHeight + 'px'
  70.   // Start the animation, if it is not running already
  71.   startAnimation()
  72. }
  73. // Update scroll `target`, and start the animation if it is not running already
  74. function updateScroll () {
  75.   target = window.scrollY || window.pageYOffset
  76.   startAnimation()
  77. }
  78.  
  79. // Listen for `scroll` event to update `target` scroll position
  80. window.addEventListener('scroll', updateScroll)
  81. // Start the animation, if it is not running already
  82. function startAnimation () {
  83.   if (!rafActive) {
  84.     rafActive = true
  85.     rafId = requestAnimationFrame(updateAnimation)
  86.   }
  87. }
  88. // Do calculations and apply CSS `transform`s accordingly
  89. function updateAnimation () {
  90.   // Difference between `target` and `current` scroll position
  91.   var diff = target - current
  92.   // `delta` is the value for adding to the `current` scroll position
  93.   // If `diff < 0.1`, make `delta = 0`, so the animation would not be endless
  94.   var delta = Math.abs(diff) < 0.1 ? 0 : diff * ease
  95.  
  96.   if (delta) { // If `delta !== 0`
  97.     // Update `current` scroll position
  98.     current += delta
  99.     // Round value for better performance
  100.     current = parseFloat(current.toFixed(2))
  101.     // Call `update` again, using `requestAnimationFrame`
  102.     rafId = requestAnimationFrame(updateAnimation)
  103.   } else { // If `delta === 0`
  104.     // Update `current`, and finish the animation loop
  105.     current = target
  106.     rafActive = false
  107.     cancelAnimationFrame(rafId)
  108.   }
  109.  
  110.   // Update images (explained below)
  111.   updateAnimationImages()
  112.  
  113.   // Set the CSS `transform` corresponding to the custom scroll effect
  114.   setTransform(container, 'translateY('+ -current +'px)')
  115. }
  116. // Calculate the CSS `transform` values for each `image`, given the `current` scroll position
  117. function updateAnimationImages () {
  118.   // This value is the `ratio` between `current` scroll position and images `height`
  119.   var ratio = current / imageHeight
  120.   // Some variables for using in the loop
  121.   var intersectionRatioIndex, intersectionRatioValue, intersectionRatio
  122.   var rotateX, rotateXMax, rotateY, rotateYMax, translateX
  123.  
  124.   // For each `image` element, make calculations and set CSS `transform` accordingly
  125.   images.forEach(function (image, index) {
  126.     // Calculating the `intersectionRatio`, similar to the value provided by
  127.     // the IntersectionObserver API
  128.     intersectionRatioIndex = windowWidth > 760 ? parseInt(index / 2) : index
  129.     intersectionRatioValue = ratio - intersectionRatioIndex
  130.     intersectionRatio = Math.max(0, 1 - Math.abs(intersectionRatioValue))
  131.     // Calculate the `rotateX` value for the current `image`
  132.     rotateXMax = rotateXMaxList[index]
  133.     rotateX = rotateXMax - (rotateXMax _ intersectionRatio)
  134.     rotateX = rotateX.toFixed(2)
  135.     // Calculate the _`rotateY`_ value for the current _`image`_
  136.     rotateYMax = rotateYMaxList_[_index]
  137.     rotateY = rotateYMax - (rotateYMax _ intersectionRatio)
  138.     rotateY = rotateY.toFixed(2)
  139.     // Calculate the `translateX` value for the current `image`
  140.     if (windowWidth > 760) {
  141.       translateX = translateXMax - (translateXMax * easeOutQuad(intersectionRatio))
  142.       translateX = translateX.toFixed(2)
  143.     } else {
  144.       translateX = 0
  145.     }
  146.     // Invert `rotateX` and `rotateY` values in case the image is below the center of the viewport
  147.     // Also update `translateX` value, to achieve an alternating effect
  148.     if (intersectionRatioValue < 0) {
  149.       rotateX = -rotateX
  150.       rotateY = -rotateY
  151.       translateX = index % 2 ? -translateX : 0
  152.     } else {
  153.       translateX = index % 2 ? 0 : translateX
  154.     }
  155.     // Set the CSS `transform`, using calculated values
  156.     setTransform(image, 'perspective(500px) translateX('+ translateX +'px) rotateX('+ rotateX +'deg) rotateY('+ rotateY +'deg)')
  157.   })
  158. }
  159. // Listen for `resize` event to recalculate dimmensions
  160. window.addEventListener('resize', setupAnimation)
  161.  
  162. // Initial setup
  163. setupAnimation()

Github 网址:https://github.com/lmgonzalves/scroll-based-animation

基于滚动的超酷 js 图片动画特效

已有 373 人购买
  • 9gmz
查看演示升级 VIP立刻购买

演示地址 下载地址
收藏
(1)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!