首页 > 解决方案 > ScaleY 一个 svg,然后是下面的文本 div

问题描述

我需要在鼠标滚轮/滚动上更改 svg 的高度,但是当这个 svg 调整大小时,我需要使下面的文本跟随这个scaleY。我试过实现 aposition: relative但这不起作用。我怎样才能做到这一点?这是我试图实现的PS。

在此处输入图像描述

这是我现在拥有的 PS - 图像和文本只是占位符。

这是我的相关 HTML 代码:

    <div className="main_container">
        <div className="main_container_inner">
          <div className="img_container">
            <img src={img_link} />
          </div>
          <div className="text_container">
            <h1>fvdfv</h1>
            <p>fvdfv</p>
          </div>
        </div>
      </div>

这是我的相关 CSS 代码:

.main_container{
  display: block;
  position: fixed;
  width: 100vw;
}

body{
  height: 400vh;
}

.main_container .main_container_inner{
  display: inline-flex;
  width: 33.33%;
  flex-direction: column;
}

.main_container img{
  width: 100%;
  transform-origin: top;
}

这就是我现在所拥有的:

在此处输入图像描述

如您所见,当我更改scaleY图像的值时,文本不会调整到新的高度。

标签: css

解决方案


这里的问题是flex容器没有设置的height属性。

因此,当您缩放图像时,很难相应地设置其容器高度,因此它会“推动”下面的其他 div。图像只是溢出其容器。

反正我找到了办法!因为我坚持(也许太久了)那个奇怪的挑战。

它需要几个计算。
我假设您希望将图像的原始高度放大到视口高度的 100%。这个假设可能是错误的......在这种情况下,只是玩这些计算。您在下面对示例进行了很好的评论。

我注意到的另一件事是你似乎在使用 React。如果是这样,我想您应该将 img 高度及其容器高度存储在组件状态中。
   我把这个挑战留给你;)

// Get the elements
let main_container = document.querySelector(".main_container")
let imgContainer = document.querySelector(".img_container")
let img = document.querySelector(".img_container img")

// Some global variables to be filled when the image has fully loaded or on window resize
let viewportHeight, scrollHeight, scrollable, currentImgHeight, maxScale

// When the img has loaded...
function imgLoaded(){  
  // Get some dimentions
  viewportHeight = window.innerHeight
  scrollHeight = document.documentElement.scrollHeight
  scrollable = scrollHeight-viewportHeight

  // Calculate the maxScale for an img height == 100% of the viewport
  currentImgHeight = img.getBoundingClientRect().height
  maxScale = viewportHeight/currentImgHeight

  // Set an initial height to the .img_container - Same as the img.
  imgContainer.style.height = currentImgHeight+"px"
}

// If the image has already fully loaded (cache), else wait for the load event
if(img.complete){
  imgLoaded()
}else{
  img.addEventListener("load", imgLoaded)
}

// On window resize
window.onresize = function(){
  img.style.transform = "scale(1)"
  window.scrollTo(0,0)
  imgLoaded()
}


// Scroll handler
function scrollHandler(){
  
  // update the current img height value
  currentImgHeight = img.getBoundingClientRect().height

  // Calculate a new scale for the img -- The +1 is to avoid a negative value at the bottom of the page
  let newScale = scrollable/(scrollable + 1 - document.documentElement.scrollTop)
  
  // Apply the newScale if less or equal to maxScale
  let scale = (newScale>maxScale)?maxScale:newScale
  img.style.transform = `scaleY(${scale.toFixed(3)})`

  // Adjust the img_container, so it pushes the div below
  imgContainer.style.height = currentImgHeight+"px"
  
  // Just for this demo...
  console.log(imgContainer.style.height,scale.toFixed(3)+"%  ")
}

// Add the event listener
document.addEventListener("scroll", scrollHandler)
/* Just for this demo... Styling the SO console which is in the way! */
.as-console{
  background: transparent !important;
  text-align: right;
}
.as-console-wrapper{
  max-height: 1em !important;
  border-top: 0 !important;
}
.as-console-row-code{
  padding: 0 !important;
  border: 0 !important;
}

/* added to your CSS */
*{
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Your css unchanged */
.main_container {
  display: block;
  position: fixed;
  width: 100vw;
}

body {
  height: 400vh;
}

.main_container .main_container_inner {
  display: inline-flex;
  width: 33.33%;
  flex-direction: column;
}

.main_container img {
  width: 100%;
  transform-origin: top;
}
<div class="main_container">
  <div class="main_container_inner">
    <div class="img_container">
      <img src="https://via.placeholder.com/400" />
    </div>
    <div class="text_container">
      <h1>fvdfv</h1>
      <p>fvdfv</p>
    </div>
  </div>
</div>

以全屏模式运行!CodePen


推荐阅读