div调整大小时背景图片抖动

4

我想使用HTML创建一个“层叠”的效果,其中一个在另一个上面。

经过一些研究,我找到了一种方法(请参见JSFiddle)。

现在我的问题是,当圆形调整大小时,背景图像会稍微移动。

有谁能帮我弄清楚如何使背景图像保持静止。

  1. 圆形中的图像需要在打开时保持相同的缩放级别。
  2. 圆形需要居中,底部一半需要超出窗口。

圆形CSS为:

.circle {
    width: 0px;
    height: 0px;
    z-index: 10;
    position: absolute;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto;
    left: 50%;
    -moz-transform: translate(-50%, 50%);
    -webkit-transform: translate(-50%, 50%);
    bottom: 0;
    -moz-transition: all 1.5s;
    -webkit-transition: all 1.5s;
}

JSFiddle: http://jsfiddle.net/GmvUQ/2/


更新说明

让我再解释一下。我发现我的问题不够清楚。以下是我想要创建的效果几张截图:

第一帧: 1st frame

第二帧: 2nd frame

整个效果已经可以工作了,但当过渡正在进行(圆圈中的图像变大或变小)时,圆圈内的图像会有一点移动。

这可能是因为需要通过Javascript/CSS定位进行计算。

我需要一些帮助来让这个图像在缩放过渡期间完全静止。

谢谢!


@cbuckley 我仍然看到那个有点晃动。 - Olly Hodgson
.circle-background2 使用固定位置吗? - chepe263
1
我怀疑这是因为浏览器在每一步转换时都必须重新计算背景大小和位置。如果您可以从固定点修复背景位置和转换,可能会更好? - Olly Hodgson
@OllyHodgson 是的,我也这么认为。但我看不到任何解决方法。 - Eelco
@Eelco 新的答案已添加。请告诉我您的想法! - gvee
显示剩余3条评论
3个回答

1
我知道这已经晚了5年,但我通过搜索引擎找到了这个帖子并想提供自己的想法。
这种效果也可以通过clip-path实现,它比jquery的动画更容易处理(如果你正在动画某些/足够的属性,仍然可能会导致图像抖动)。
如果你正在进行悬停而不是按钮点击,则clip-path还具有无需javascript的额外好处。 它还会导致HTML文件更简单。
我制作了原始问题jsfiddle的更新版本 http://jsfiddle.net/GmvUQ/13/,其中演示了使用clip-path来完成此操作。 它仍然使用jquery来处理按钮点击,但“魔法”全部通过CSS转换发生,而不是javascript动画。
JQuery:
function changeboleto(pix) {
    ...
    $('.circle-background').css('clip-path', 'circle(' + pix/2 + 'px at 50% 100%)');
}

CSS(包括原始fiddle中的原始CSS):

.circle-background {
    position: absolute;
    z-index: 10;
    clip-path: circle(0% at 50% 100%);
    background:url(http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg);
    background-size: cover;
    -webkit-transition: all 1.5s;
    -moz-transition: all 1.5s;
    bottom: 0%;
    left: 50%;
    -moz-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
}

这样做的作用是仅仅导致CSS在clip-path属性上进行过渡,从而使圆形扩展动画化。因为图像本身永远不会移动,只有它显示的边界会移动,所以它永远不会抖动。

1

演示:http://jsfiddle.net/GmvUQ/5/

更新后的HTML

<div>
    <div class="buttons">
        <button onclick="changeboleto(0)">Click here</button>
        <button onclick="changeboleto(500)">Click here</button>
        <button onclick="changeboleto(1000)">Click here</button>
    </div>
    <div class="circle girl">
    </div>
    <div class="circle lamborghini">
    </div>
</div>

请注意,我已经删除了每个 .circle 中嵌套的 </div> 元素。相反,我为每个元素添加了一个额外的类,设置了 background-image(如果需要,还设置了一些位置)。

更新后的 CSS

.circle {
    width: 250px;
    height: 250px;
    z-index: 10;
    position: absolute;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto;
    background-repeat: no-repeat;
    background-size: cover;
    background-origin: content-box;
    background-position: center center;
}
.lamborghini {
    background-image: url(http://www.hdwallpapers.in/walls/2013_wheelsandmore_lamborghini_aventador-wide.jpg);
}
.girl {
    background-image: url(http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg);
    top: 50%;
}

.buttons {
    position: relative;
    z-index: 5;
}

我已将大部分CSS移动到.circle类中,因为它适用于两个图像集。特别注意background-*属性的值。

更新的JQuery

function changeboleto(pix) {
    circleHeight = pix;
    circleWidth = pix;
    
    $('.circle').animate({
        'width' : circleWidth,
        'height': circleHeight
    }, 1500, 'linear');
    
    //css('width', circleWidth).css('height', circleHeight);
    changeCircleBackgroundToWindow();
}

function changeCircleBackgroundToWindow() {
    windowWidth = $(window).width();
    windowHeight = $(window).height();
    
    $(".circle > div").animate({
        'width' : windowWidth,
        'height': windowHeight
    }, 1500, 'linear');
    $(".circle > div").animate({
        'width' : windowWidth,
        'height': windowHeight
    }, 1500, 'linear');
    
    //$(".circle-background").css("width", windowWidth).css("height", windowHeight);
    //$(".circle-background2").css("width", windowWidth).css("height", windowHeight);
}

我没有混合使用JQuery和CSS过渡效果,而是将所有动画都放在了JQuery中。

我使用了animate()函数并指定了缓动方法。默认的缓动方法是swing,但我使用了linear,因为它可以以恒定的速度进行动画。

编辑

上面的解决方案包括CSS,它允许图像随动画缩放。然而,您要求图像在整个过程中保持相同的“缩放级别”。

要实现这一点,只需从CSS中删除一行,即这一行:

.circle {
    ...
    background-size: cover;
    ...
 }

0

全屏演示

JSFiddle: http://jsfiddle.net/7bP7Z/4/(点击查看效果)

好的,现在问题更加明确了,我重新审视了一下,并提出了更好的解决方案。

HTML

<div class="circle">
    <div class="circle-overlay"></div>
    <img src="http://www.hdwallpapers.in/walls/2013_wheelsandmore_lamborghini_aventador-wide.jpg" />
</div>

<div class="circle">
    <div class="circle-overlay"></div>
    <img src="http://www.hdwallpapers.in/walls/colorful_background_girl-normal5.4.jpg" />
</div>

注意结构的变化:

  • 一个包含元素
  • 一个“覆盖”元素
  • 一个</img>

CSS

.circle {
    position: relative;
    overflow: hidden;
}

.circle-overlay {
    position: absolute;
    left: 50%;
    margin-left: -150px;
    bottom: -150px;
    border-radius: 50%;
    width: 300px;
    height: 300px;
    box-shadow: 0px 0px 0px 3000px white;
}

很好又简单的 CSS!

大部分的代码用于定位我们的 .circle-overlay 类。这个类提供了一个透明的圆形(使用 border-radius),并使用我的最喜欢的新 CSS 特性之一 - box-shadow - 应用一个固定的、白色的“轮廓”,它可以覆盖下面的图像。试着玩一下 box-shadow 的颜色和大小(调整 300px 的值),看看它是如何工作的。

JQuery

$('.circle').click(function() {
    var c = $(this).children('.circle-overlay');
    var w = c.width() + 100;
    
    c.animate({
        'width' : w,
        'height': w,
        'bottom': (w*-0.5),
        'margin-left': (w*-0.5)
    }, 500, 'linear');
});

再次强调,保持简单明了!

上述 JQuery 执行了一个非常简单的任务。它增加了 circle-overlay 的大小,同时在每次点击时保持其底部中心位置。

这应该是一个非常平滑的动画,图像不应该出现 "抖动" 或 "摇晃",因为图像没有被操纵。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接