CSS硬件加速宽度? [英] CSS hardware accelerated width?

查看:156
本文介绍了CSS硬件加速宽度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一个Phonegap应用程序,允许用户通过移动中间分隔符来更改两列布局的大小。

I am attempting to build a Phonegap app that will allow the user to change the size of a two column layout by moving the middle divider.

我能够得到这个工作,但有一个巨大的UX问题:它是滞后。这不是可怕的,但在最新的iPad它甚至明显,这让我很担心。

I was able to get this working, but there is a huge UX problem: it's laggy. It's not terrible, but on the latest iPad it's even noticeable, which has me worrying.

这是我的JS调整大小:

Here's my JS that does the resizing:

$("div").on("touchmove", "#columnResizeIcon", function(e) {
    e.preventDefault();
    var left = e.originalEvent.touches[0].pageX;
    var right = $("#columnContainer").width() - left;

    $("#leftColumn").css({
       "width":left - 1 + "px",
       "right":"auto",
    });
    $("#rightColumn").css({
       "width":right - 1 + "px",
       "left":"auto",
    });
    $("#columnResize").css({
       "-webkit-transform":"translate3d(" + left  + "px" + ", 0, 0)",
       "left":"auto",
    });
    $("#columnResizeIcon").css({
       "-webkit-transform":"translate3d(" + left  + "px" + ", 0, 0)",
       "left":"auto",
    });
}); 

你会注意到我利用 translate3d c $ c>更改元素的左值,因为这是硬件加速的。我相信滞后是由改变左右列的宽度产生的,这是我需要硬件加速。

You'll notice that I take advantage of translate3d() to change the "left" value of the elements, as that is hardware accelerated. I believe the lag is being produced from changing the widths of the left and right column, which is what I need to be hardware accelerated.

我认为可能的解决方案工作将使用 -webkit-transform:translate3d(50%,0,0)将右侧列推过页面的一半,然后只是更改该值,希望它只会拉伸直到它到达父母。

A possible solution that I thought might work would be to use -webkit-transform:translate3d(50%, 0, 0) to push the right column over half the page, and then just changing that value, hoping that it would only stretch until it reached the parent. It continues, however, and goes 50% of the page, not 50% of the parent.

我的HTML标记看起来像这样:

My HTML markup looks like this:

<div id="columnContainer">
    <div id="columnResize"></div>
    <div id="columnResizeIcon"></div>

    <div id="leftColumn">
        <div class="header">Left Header</div>
        <div class="content"></div>

    </div>
    <div id="rightColumn">
        <div class="header">Right Header</div>
        <div class="content"></div>
    </div>
</div>

和我的CSS:

body{
    background-color:#000;
}

#columnContainer{
    position: absolute;
    bottom:0;
    top:0;
    right:0;
    left:0;
    background-color:#000;
}

#leftColumn{
    position: absolute;
    top:0;
    left:0;
    right:50%;
    bottom:0;
    -webkit-overflow-scrolling: touch;
    z-index: 1;
    margin-right: 1px;
}

#rightColumn{
    position: absolute;
    top:0;
    left:50%;
    right:0;
    bottom:0;
    -webkit-overflow-scrolling: touch;
    z-index: 1;
    margin-left: 1px;
}

.header{
    position: absolute;
    left:0;
    right:0;
    height:33px;
    z-index: 5;
    background: -webkit-linear-gradient(top, #f4f5f7 0%,#a7abb7 100%);
    box-shadow:  inset 0 1px 0 #fff, inset 0 -1px 0 #7A8090, 3px 0 2px rgba(0,0,0,.3);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    font-size: 17px;
    font-family: Helvetica;
    font-weight: bold;
    letter-spacing: .2px;
    text-align: center;
    padding-top:9px;
    color:#71787F;
    text-shadow: 0 1px 0 #E3E5E9;
}

.content{
    position: absolute;
    left:0;
    right: 0;
    top:42px;
    bottom: 0;
}

#leftColumn .content{
    background-color:#F5F5F5;
}

#rightColumn .content{
    background-color:#fff;
}

#columnResize{
    position: absolute;
    width:2px;
    top:0;
    bottom: 0;
    left:50%;
    margin-left:-1px;
    background-color:#000;
    z-index: 2;
}

#columnResizeIcon{
    position: absolute;
    z-index: 3;
    width:10px;
    height:30px;
    top:50%;
    bottom:50%;
    margin-top:-15px;
    left:50%;
    margin-left:-7px;
    border-left:2px solid #000;
    border-right:2px solid #000;
}


推荐答案

工作比我有更好的。基本上,我动画的容器,我隐藏的内容,当我调整大小。然后,当调整大小完成后,我再次显示内容。我使用一个动画,使它看起来漂亮,当隐藏/显示。代码会比我更好地解释它:

I finally figured out a solution that works a lot better than what I had. Basically, I animate the container, and I hide the content when I'm resizing. Then, when the resizing is done, I show the content again. I used an animations to make it look pretty when hiding/showing. The code will explain it better than I will:

1 http://jsfiddle.net/charlescarver/hnQHH/134/

当滑动条被点击时,它用 translate3d() transform,然后隐藏div。这是因为如果我尝试更新宽度时显示元素,滞后返回。因此,一旦div被隐藏,我然后只需向左或向右移动列,再次使用 translate3d()转换。我可以这样做,而不是每个元素的宽度停止短,因为我设置这是永远无法达到的,所以它的扩展远远超出了页面。

When the slider is tapped, it pushes all the text elements off the page with a translate3d() transform, then hides the div. This is because the lag returns if I try to update the width while the elements are shown. So, once the divs are hidden, I then just move the columns left or right with the translate3d() transform once again. I can do this without having the width of each element stop short because I set the left or right values to a value that can never be reached so it's extended far enough beyond the page. That way, I can simply shift it without worrying that it will cut off prematurely.

有部分这可能是多余的,但我会尽快清理。你也可能会注意到一些奇怪的事情,比如(1) cornerLeft ,(2) dummy (3) shadow 和在JS中,(4) minimum

There are parts of this that are probably redundant, but I'll clean those up soon. You'll also probably notice some weird things going on, such as (1) cornerLeft, (2) dummy, (3) shadow, and in the JS, (4) minimum:


  1. 当调整页面大小时, dummy 导航栏会扩展左右列的整个宽度,这意味着它的宽度的1000%。这意味着我不能在每个列的左侧和右侧的nav上设置 border-radius ,因为它将离屏幕太远不可见。

  1. When I resize the page, the dummy nav bar extends the entire width of the left and right columns, which means it goes 1000% of the width. That means that I can't set a border-radius on the nav for the left and right sides of each column, as it would be so far off the screen that it wouldn't be visible. So, I made a simple corner to mask each side of the window, making it look pretty.

我隐藏 .contentLeft

I hide .contentLeft and .contentRight when I resize as it causes lag when it's shown. I don't want to get rid of the nav bar though, so I make a dummy one that is always there on the page, and is simply revealed when the resize is about to happen. I think this reduces the lag as I don't have to add the element in, since it's always there.

但是,一个问题在于,我们不必添加元素,当正常导航覆盖虚拟导航时, box-shadow 的重叠,导致它变暗了200ms。我不喜欢这个。

One problem with that, however, is that when the normal nav overlays the dummy nav, the box-shadow's overlap, causing it to become darker for 200ms. I don't like this. So, I put in a shadow that is always on top of the nav, regardless of what nav is showing.

现在我可以很容易地设置一个边界,可拖动列可以在停止之前到达。方便,对吗?

I can now easily set a bound that the draggable columns can reach before stopping. Convenient, right?



代码



Code

HTML:

<div id="container">
    <div class="cornerLeft"></div>
    <div class="cornerRight"></div>
    <div class="shadow"></div>
    <div class="left">
        <div class="contentLeft">
            <div class="header"></div>
            <div class="headerbehind"></div>
            <div class="text textLeft">Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus.</div>
        </div>
        <div class="dummy"></div>
        <div class="dummybg"></div>
    </div>
    <div class="divider"></div>
    <div class="right">
        <div class="contentRight">
            <div class="header"></div>
            <div class="headerbehind"></div>
            <div class="text textRight">Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus.</div>
        </div>
        <div class="dummy"></div>
        <div class="dummybg"></div>
    </div>
</div>

CSS:

* {
    -webkit-text-size-adjust:none;
}
#container {
    position:fixed;
    left:0;
    right:0;
    bottom:0;
    top:0;
    background-color:#000;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
}
.left {
    -webkit-transform:translate3d(0, 0, 0);
    position:absolute;
    left:-3000px;
    right:50%;
    top:0;
    bottom:0;
    border-right:1px solid #000;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.right {
    -webkit-transform:translate3d(0, 0, 0);
    position:absolute;
    left:50%;
    right:-3000px;
    top:0;
    bottom:0;
    border-left:1px solid #000;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.divider {
    width:24px;
    height:40px;
    border-left:2px solid #000;
    border-right:2px solid #000;
    position:absolute;
    left:50%;
    z-index:3;
    margin-left:-14px;
    margin-top:-20px;
    top:50%;
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
}
.contentLeft {
    position:absolute;
    right:0;
    bottom:0;
    top:0;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.contentRight {
    position:absolute;
    left:0;
    bottom:0;
    top:0;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.cornerLeft:after {
    content:"";
    height:5px;
    position:absolute;
    left:0;
    width:5px;
    background: -webkit-linear-gradient(top, #F0F2F4 0%, #EAEBEE 100%);
    z-index:700;
    border-top-left-radius:5px;
    box-shadow:inset 0 1px 0 #fff;
}
.cornerLeft {
    position:absolute;
    z-index:700;
    left:0;
    width:5px;
    height:5px;
    background-color:#000;
}
.cornerRight:after {
    content:"";
    height:5px;
    position:absolute;
    right:0;
    width:5px;
    background: -webkit-linear-gradient(top, #F0F2F4 0%, #EAEBEE 100%);
    z-index:700;
    border-top-right-radius:5px;
    box-shadow:inset 0 1px 0 #fff;
}
.cornerRight {
    position:absolute;
    z-index:700;
    right:0;
    width:5px;
    height:5px;
    background-color:#000;
}
.header, .dummy {
    position: absolute;
    left:0;
    right:0;
    height:35px;
    background: -webkit-linear-gradient(top, #f4f5f7 0%, #a7abb7 100%);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    font-size: 17px;
    font-family: Helvetica;
    font-weight: bold;
    letter-spacing: .2px;
    text-align: center;
    padding-top:9px;
    color:#71787F;
    text-shadow: 0 1px 0 #E3E5E9;
    word-break: break-all;
    box-shadow:inset 0 1px 0 #fff, inset 0 -1px 0 #7A8090;
}
.shadow {
    height:44px;
    position:absolute;
    left:0;
    right:0;
    box-shadow:0 1px 2px rgba(0, 0, 0, .2);
    z-index:600;
}
.header {
    z-index:500;
}
.dummy {
    z-index:100;
}
.headerbehind {
    position:absolute;
    background-color:#000;
    left:0;
    right:0;
    height:44px;
    z-index:499;
}
.text, .dummybg {
    margin-top:44px;
    background-color:#fff;
    position:absolute;
    top:0;
    right:0;
    left:0;
    bottom:0;
}
.text {
    z-index:2;
    padding:20px 40px;
    -webkit-animation-duration:200ms;
    -webkit-animation-timing-function:ease;
}
.contentLeft, .contentRight {
    z-index:300;
}
.leftOut {
    -webkit-transform:translate3d(-100%, 0, 0);
    -webkit-animation-name:leftOut;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.leftIn {
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-animation-name:leftIn;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
@-webkit-keyframes leftOut {
    0% {
        -webkit-transform:translate3d(0, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(-100%, 0, 0);
    }
}
@-webkit-keyframes leftIn {
    0% {
        -webkit-transform:translate3d(-100%, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(0, 0, 0);
    }
}
.rightOut {
    -webkit-transform:translate3d(100%, 0, 0);
    -webkit-animation-name:rightOut;
}
.rightIn {
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-animation-name:rightIn;
}
@-webkit-keyframes rightOut {
    0% {
        -webkit-transform:translate3d(0, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(100%, 0, 0);
    }
}
@-webkit-keyframes rightIn {
    0% {
        -webkit-transform:translate3d(100%, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(0, 0, 0);
    }
}

JS:

minimum = 100;
$(".contentLeft").css("width", ($("#container").width() / 2) - 1);
$(".contentRight").css("width", ($("#container").width() / 2) - 1);

$("div").on("touchstart", ".divider", function (e) {
    $(".textLeft").removeClass("leftIn");
    $(".textLeft").addClass("leftOut");
    $(".textRight").removeClass("rightIn");
    $(".textRight").addClass("rightOut");
    setTimeout(function () {
        $(".contentLeft, .contentRight").hide();
    }, 200);
});

$("div").on("touchmove", ".divider", function (e) {
    e.preventDefault();
    if ($(".contentLeft").css("display", "none")) {
        var page = $("#container").width();
        var left = e.originalEvent.touches[0].pageX;
        var right = page - left;
        updateWidth(page, left, right);
    }
});

//$(".contentLeft, .contentRight").hide();

$("div").on("touchend", ".divider", function (e) {
    setTimeout(function () {
        $(".textLeft").removeClass("leftOut");
        $(".textLeft").addClass("leftIn");
        $(".textRight").removeClass("rightOut");
        $(".textRight").addClass("rightIn");
        $(".contentLeft, .contentRight").show();
    }, 200);
});

$(window).on('orientationchange', function (e) {
    var page = $("#container").width();
    var leftWidth = $(".contentLeft").width();
    var rightWidth = $(".contentRight").width();
    var previousWidth = (leftWidth + rightWidth);
    if (leftWidth + rightWidth + 2 < page) {
        var left = (page / 2) - (previousWidth / 2) + leftWidth;
    } else if (leftWidth + rightWidth + 2 > page) {
        var left = leftWidth - ((previousWidth / 2) - (page / 2));
    }
    var right = page - left;
    updateWidth(page, left, right);
});

function updateWidth(page, left, right) {
    if (left < minimum) {
        var finalLeft = minimum;
        var finalRight = (-1 * (page - minimum));
        var finalRightWidth = (page - minimum);
    } else if (right < minimum) {
        var finalLeft = (page - minimum);
        var finalRight = (-1 * minimum);
        var finalRightWidth = minimum;
    } else {
        var finalLeft = (left);
        var finalRight = (0 - right);
        var finalRightWidth = (right);
    }
    $(".divider").css({
        "-webkit-transform": "translate3d(" + finalLeft + "px, 0, 0)",
            "left": "auto",
    });
    $(".left").css({
        "-webkit-transform": "translate3d(" + finalLeft + "px, 0, 0)",
            "right": "100%",
    });
    $(".right").css({
        "-webkit-transform": "translate3d(" + finalRight + "px, 0, 0)",
            "left": "100%",
    });
    $(".contentLeft").css("width", finalLeft);
    $(".contentRight").css("width", finalRightWidth);
}

1 134次尝试。

这篇关于CSS硬件加速宽度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆