14

我正在寻找一个具有背景渐变的页面,该背景渐变每隔几秒就会改变一次颜色并在过渡之间混合。现在我想将此效果应用于被具有纯色背景的元素阻挡的上部元素。

为了给你一个更好的例子,我的意思是我附上了一个简单的模型,希望你能理解我想要做什么,我愿意接受建议。

jQuery 和 CSS
(来源:bybe.net

问题显然是包含黑色背景的块,任何使用 PNG 透明文件都会看到黑色而不是渐变。

到目前为止,我将包含示例代码:

<body><!-- A Jquery script will be used to add CSS background, Easy stuff -->
<div class="blackbox">
    <div class="logo"><img src="#" alt=""></div>
    <hr class="h-line">
    <div class="v-line"> </div>
</div>

所以我追求的是:

  • 一种已知的 jQuery 方法来获取背景图像,但它需要能够引用渐变的位置,以便它与背景内联。
  • 让它工作的更好的解决方案,请记住页面需要响应,所以我可以使用其他方法,但由于它的响应,我想不出任何方法。
4

7 回答 7

18

由于您要求 jQuery 解决方案的替代方案

你可以玩一点marginsbox-shadow关键帧动画。

形状的这个方向的东西(取决于你想对哪个部分做什么 - 添加内容......以及你希望它以什么方式响应):

html:

<div class="wrapper">
    <div class="header"><img src="http://i.imgur.com/CUbOIxr.png" alt="Company name" /></div>
    <div class="content"></div>
</div>

CSS:

body {
    background:orange;
    width:100%;
    height:100%;
}
.wrapper {
    width:40%;
    height:90%;
    border:30px solid #000;
    border-right-width:100px;
    border-bottom-width:100px;
}
.header {
    width:100%;
    border-bottom:10px solid transparent;
    -webkit-box-shadow: 0 30px 0 #000;
    -moz-box-shadow: 0 30px 0 #000;
    box-shadow: 0 30px 0 #000;
}
.header img {
    width:100%;
}
.content {
    width:95%;
    height:400px;
    background-color:#000;
    margin-top:30px;
}

演示

这种方式不需要javascript。对于背景,您可以使用线性渐变并使用 css过渡关键帧动画制作所有动画。您还需要调整长度并根据需要调整边框和框阴影,也许可以添加一些 @media 查询以提高响应能力

希望这可以帮助您朝着正确的方向前进=)


更新:

我希望渐变的变化是较小的问题;-) 愚蠢的我,对不起。

我将详细说明我对动画的纯 CSS 建议,但是如果您不喜欢 CSS3 解决方案,您可以为背景动画选择一个 javascript 滑块 - 尽管这是现在很热门的东西 ;-)

好的。所以,我会添加一些具有渐变背景(layer1 和 layer2)的固定定位元素。

现在在html中有这个方向的东西:

<div class="layer layer1"></div>
<div class="layer layer2"></div>
<div class="wrapper">
    <div class="header">
        <img src="http://newtpond.com/test/company-name.png" alt="Company name" />
    </div>
    <div class="content"></div>
</div>

并在CSS中为它们添加关键帧动画(这里只是带有 -webkit 供应商前缀 [可能是因为我是一个懒惰的流浪汉],但我希望你能明白这个想法,并可以添加其他的):

body {
    width:100%;
    height:100%;
    margin:0;
    padding:0;
}
/* for the animation */
 .layer {
    position:fixed;
    width:100%;
    height:100%;
}
@-webkit-keyframes GoLayer1 {
    0% {
        opacity:1;
    }
    50% {
        opacity:0;
    }
    100% {
        opacity:1;
    }
}
@-webkit-keyframes GoLayer2 {
    0% {
        opacity:0;
    }
    50% {
        opacity:1;
    }
    100% {
        opacity:0;
    }
}
.layer1 {
    background: -webkit-linear-gradient(bottom, rgb(43, 70, 94) 29%, rgb(194, 41, 41) 65%, rgb(155, 171, 38) 83%);
    -webkit-animation: GoLayer1 5s infinite;
}
.layer2 {
    background: -webkit-linear-gradient(bottom, rgb(225, 202, 230) 29%, rgb(39, 163, 194) 65%, rgb(36, 124, 171) 83%);
    -webkit-animation: GoLayer2 5s infinite;
}
/* the wrapper shape */
 .wrapper {
    z-index:999;
    opacity:1;
    position:relative;
    width:40%;
    height:90%;
    border:30px solid #000;
    border-right-width:100px;
    border-bottom-width:100px;
}
.header {
    width:100%;
    border-bottom:10px solid transparent;
    -webkit-box-shadow: 0 30px 0 #000;
    -moz-box-shadow: 0 30px 0 #000;
    box-shadow: 0 30px 0 #000;
}
.header img {
    width:100%;
}
.content {
    width:95%;
    height:400px;
    background-color:#000;
    margin-top:28px;
}

演示(在 Chrome 26 中测试 - 看起来很酷 =)

现在,我可以根据这种仅使用 CSS 的方法向您指出。还有一些东西需要修改并考虑浏览器的兼容性。但它肯定是一个替代方案......并且朝着 html5 和 css3 的发展方向迈出了一步(如果你想变得又热又酷;-),呵呵,对不起,太愚蠢了。

祝你好运!


更新 2:

所以,我稍微克服了我的懒惰,并在上面的例子中添加了更多的供应商前缀(当然你可以使用任何图像作为背景):

演示

在这里我添加另一个示例,即使用 png 图像作为渐变,并在背景中上下滑动(作为另一种选择):

演示

于 2013-05-15T22:04:28.037 回答
4

有很多方法可以做到这一点,已经建议使用 CSS3 和图像,所以我建议使用画布。

HTML 画布元素内置了您需要的一切。它允许渐变背景填充,并且使用globalCompositeOperation,可以对形状和文本进行遮罩,在背景中创建切口以使真正的可变 HTML 元素在彩色背景下真正透明。它也可以很好地扩展,并且可以很容易地做出响应。

所有主流浏览器都支持 canvas 元素,除了 Internet Explorer 8 及更低版本,这意味着浏览器支持比前面提到的许多 CSS3 方法更好,比如关键帧和背景大小。

使用后备,比如在画布不可用时淡入淡出的图像,应该不会很难弄清楚,并且在除 Internet Explorer 9 以下的所有其他浏览器中,不需要图像来创建渐变画布中的背景和文本掩码,这应该会使页面的加载速度显着加快。

要检测是否支持画布,您可以使用这个方便的功能:

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

像这样使用:

if ( isCanvasSupported() ) {
    // do canvas stuff
}else{
    // fall back to images
}

所以,让我们开始吧!要创建“最后的手段”后备和一些我们可以“克隆”到画布中的元素,我们将在 HTML 中创建我们需要的元素,以获得类似于您在问题中概述的结构。这具有额外的优势,即能够仅更改一些 CSS 以在画布中进行更改:

<div id="gradient">
    <div class="text">COMPANY NAME</div>
    <div class="h_bar"></div>
    <div class="v_bar"></div>
</div>

它只是一个容器,其中包含一个文本元素,每个条都有一个元素。

一些样式也是必要的,我会用简单的方法来做,有位置absolute和一些非常快速的定位,因为除非有人禁用了 javascript,否则这些元素将不可见:

#gradient {position: absolute; 
           background: #000; 
           top: 5%; left: 5%; right: 5%; bottom: 5%;
          }
.text {position: absolute; 
      top: 20px; 
      left: 100px; 
      width: 400px; 
      color: #fff; font-size: 40px; font-weight: bold;
      font-family: arial, verdana, sans-serif;
      }
.h_bar {position: absolute; 
        height: 20px; 
        top: 100px; left: 60px; right: 60px; 
        background: #fff;
       }
.v_bar {position: absolute; 
        width: 20px; 
        top: 140px; bottom: 30px; right: 60px; 
        background: #fff;
       }

没有任何看起来完全像THIS FIDDLE的 javascript ,它应该有点响应并适应窗口大小。

现在我们需要一些 javascript 来将这些元素变成画布中的东西。我们将创建两个画布元素,一个用于背景,因为我决定在随机渐变之间连续设置背景动画,另一个用于内部黑框和内容(文本和条形图)。

由于文本和条的遮罩可能有点慢,我们不必重绘所有内容,只需重新绘制背景画布,因为前景是相当静态的。这也避免了某些高帧率浏览器中的闪烁问题,我们将使用 requestAnimationFrame 作为背景画布的动画,因此如果我们不使用两个画布元素,文本掩码中的闪烁将是一个问题。

对于不支持 requestAnimationFrame 的浏览器,我们将添加这个 polyfill以确保它可以在任何地方工作。

是时候写一些 javascript 了,这当然使用 jQuery :

var gradSite = {
    init: function() {
        var self = this;
        self.create().setSizes().events();
        (function animationloop(){
            requestAnimationFrame(animationloop);
            self.draw().colors.generate();
        })();
    },
    create: function() { // creates the canvas elements
        this.canvas     = document.createElement('canvas');
        this.canvas2    = document.createElement('canvas');
        this.canvas.id  = 'canvas1';
        this.canvas2.id = 'canvas2';
        this.canvas.style.position = 'absolute';
        this.canvas2.style.position = 'absolute';
        $('#gradient').after(this.canvas, this.canvas2);
        return this;
    },
    events: function() { //event handlers
        $(window).on('resize', this.setSizes);
        $('#gradient').on('contentchange', this.draw2);
        return this;
    },
    setSizes: function() { // sets sizes on load and resize
        var self = gradSite,
            w    = $(window),
            m    = $('#gradient');

        self.canvas.height      = w.height();
        self.canvas.width       = w.width();
        self.canvas2.bg         = m.css('background-color');
        self.canvas2.height     = m.height();
        self.canvas2.width      = m.width();
        self.canvas2.style.top  = m.offset().top + 'px';
        self.canvas2.style.left = m.offset().left + 'px';
        self.draw2();
        return self;
    },
    colors: {
        colors: {
                0: [255,255,0],
                1: [255,170,0],
                2: [255,0,0]
        },
        map: {
                0: [0,0,1],
                1: [0,1,1],
                2: [0,1,1]
        },
        generate: function() { // generates the random colors
            var self = this;
            $.each(self.colors, function(i,color) {
                $.each(color, function(j, c) {
                    var r   = Math.random(),
                        r2  = Math.random(),
                        val = self.map[i][j] == 0 ? (c-(j+r)) : (c+(j+r2));

                    if (c > 255) self.map[i][j] = 0;
                    if (c < 0  ) self.map[i][j] = 1;

                    self.colors[i][j] = val;
                });
            });
        }
    },
    raf: (function() { // polyfill for requestAnimationFrame
        var lastTime = 0,
            vendors  = ['webkit', 'moz'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame  = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime(),
                    timeToCall = Math.max(0, 16 - (currTime - lastTime)),
                    id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };

        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }()),
    calculateColor: function(colors) { // returns a rgb color from the array
        return 'rgb(' + Math.round(colors[0]) + ',' + Math.round(colors[1]) + ',' + Math.round(colors[2]) + ')';
    },
    draw: function() { //draws the color background
        var self = this,
            c    = self.canvas || document.getElementById('canvas1'),
            ctx  = c.getContext('2d'),
            grad = ctx.createLinearGradient(0,0,0,self.canvas.height);

        c.width = c.width;
        grad.addColorStop(0, self.calculateColor(self.colors.colors[0]));
        grad.addColorStop(0.5, self.calculateColor(self.colors.colors[1]));
        grad.addColorStop(1, self.calculateColor(self.colors.colors[2]));
        ctx.fillStyle = grad;
        ctx.fillRect(0,0,self.canvas.width, self.canvas.height);
        return self;
    },
    draw2: function() { // draws the black square and content
        var self = this,
            c    = self.canvas2 || document.getElementById('canvas2'),
            ctx2 = c.getContext('2d'),
            txt  = $('.text', '#gradient').first(),
            hbar = $('.h_bar', '#gradient').first(),
            vbar = $('.v_bar', '#gradient').first();

        c.width = c.width;
        ctx2.globalCompositeOperation = 'xor';

        ctx2.font = txt.css('font');
        ctx2.fillStyle = c.bg || '#000';
        ctx2.fillText(txt.text(), txt.offset().left, txt.offset().top);  

        ctx2.fillRect(hbar.position().left, hbar.position().top, hbar.width(),hbar.height());
        ctx2.fillRect(vbar.position().left, vbar.position().top, vbar.width(),vbar.height());
        ctx2.fillRect(0,0,c.width,c.height);
    }
}

raf函数将是 requestAnimationFrame 的 polyfill,两个绘制函数在画布中创建内容。真的没那么复杂。

我们将在 DOM 就绪处理程序中调用上述脚本,如下所示:

$(function() {
    gradSite.init(); // starts the canvas stuff
});

将所有这些添加到小提琴中,并添加一些用于演示目的的元素,它看起来像THIS FIDDLE,这是完成的 ->

全屏演示

于 2013-05-18T09:33:11.863 回答
3

我能看到这个工作的唯一方法是,如果你的黑色 div 没有背景,并且被切割成每个都有背景的部分。公司名称区域需要与其他 div 部分的背景具有相同的前景色。根据您的布局需要,这可能没问题。

例如,您可以将其分成三个部分和两个图像: 在此处输入图像描述

于 2013-05-13T18:58:52.293 回答
2

您可以尝试将 background-size 和 background-position 与 javascript 结合使用:

setGradientSizes = function (el) {
var width = $(document).width() + 'px', height = $(document).height() + 'px';
$(el || '.gradient:not(body)').each(function () {
    var offset = $(this).offset();
    $(this).css('background-size', width + ' ' + height);
    $(this).css('background-position', (offset.left * -1) + 'px ' + (offset.top * -1) + 'px');
})};

这里的工作示例-> jsbin

笔记:

  • 这不是 100% 跨浏览器 - FF4.0+、IE9.0+、Opera 10.0+、Chrome 1.0+、Safari 3+ 支持背景大小。
  • 对于某些较旧的浏览器,您可以尝试使用特定于浏览器的前缀(例如 -moz-background-size)——我的示例并未涵盖这一点。
  • 为了减少负载闪烁,您可以先应用计算,然后添加背景渐变
于 2013-05-15T21:54:14.517 回答
1

If I was you I'll duplicate the css and jQuery, print it on a div on top of what ever and make the overflow hidden (like masking layers but with z-index).

于 2013-05-22T00:22:21.593 回答
1

您可以使用黑色文本将图像的背景设置为,然后将 div 的背景颜色设置为rgba(0,0,0,0)透明

于 2013-05-18T23:20:44.063 回答
1

根据我的理解,这可能对你有帮助

继承可以将某个值从父级复制到其子级,但反过来没有属性(这将涉及另一个选择器来决定要恢复哪种样式)。

您将不得不手动恢复样式更改:

div { color: green; }

form div { color: red; }

form div div.content { color: green; }

如果您有权访问标记,则可以添加几个类来精确设置您需要的样式

form div.sub { color: red; }

form div div.content { /* remains green */ }

编辑:CSS 工作组正在做一些事情:

div.content {
  all: default;
}
于 2013-05-21T09:51:09.107 回答