【问题标题】:How to get color that is behind a transparent element?如何获得透明元素背后的颜色?
【发布时间】:2014-01-20 15:52:12
【问题描述】:

我正在研究一个身体有多种颜色的网站。当内容向下滚动时,内容的背景会发生变化。
在下图中,您可以看到带有蓝色背景的正文。因此,当使用滚动条向下滚动内容时,背景图像也应该与内容一起滚动。
所以当滚动条停在像蓝色这样的颜色时会发生什么,然后菜单标题(主页)背景会自动变为蓝色。

【问题讨论】:

  • 请出示您的代码,一张漂亮的图片还不够
  • 你在使用渐变背景吗???
  • @Wisam:我拍摄了高度为 1551 像素的非常大的图像。滚动时我需要循环这张图片。
  • @madhukumar 您的标头是否定位不正确或真的不起作用? jsfiddle.net/7rkgx/1
  • @madhukumar 啊,是的,我故意补充说 ^^ 这是实时滚动事件:jsfiddle.net/7rkgx/2 虽然,我仍然不完全觉得这是一个值得回答的问题,因为画布是硬编码的,并且创建自己的背景并不容易(因为它也会导致一些内存峰值,尤其是在使用大背景时)。虽然我会检查更多。

标签: javascript jquery html css


【解决方案1】:

首先我们应该知道我们想要做什么。第一步实际上是获取图像的颜色,从而访问图像的属性。
但是,浏览器无法直接获取图像本身的信息(当然,您可以从图像元素中获取信息)。然而,一种网络浏览器绘图方法可以让我们控制图像的各个方面:画布。

所以首先我们必须将图像转换为画布元素。 使用drawImage(img, posx, posy, canvasWidth, canvasHeight); 可以很简单地完成此操作

我们还将画布图像+元素拉伸到整个屏幕。我们想在画布上定义大小的原因是因为这样画布将计算每个新生成的像素,因此我们可以访问每个新像素:

var screenWidth = window.innerWidth,
    screenHeight = window.innerHeight,
    c = document.createElement('canvas');
    ctx = c.getContext("2d"),
    img = document.getElementById("image");

    c.width = screenWidth;
    c.height = screenHeight;
    ctx.drawImage(img, 0, 0, screenWidth, screenHeight);
    $(c).attr('id', 'c');
    $('body').prepend(c);
    $(img).remove();

动态制作的 Canvas 元素将适合屏幕大小(请注意,这只是在网络浏览器的第一次启动时。因此,当您调整画布大小时,不会随屏幕调整大小)。

我们删除了图像,因为它不再有用了。在我看来,从图像转换为画布是一个很好的实践。因为您将确定图像将首先加载到浏览器中,然后转换为画布元素。

接下来我们将访问一个像素。可以通过getImageData(offsetX, offsetY, sizeX, sizeY).data;访问像素数据,返回RGBA颜色数组。

现在 offsetX 和 offsetY 将是元素颜色选择器的偏移量。 请注意,由于背景是固定的,因此此元素偏移量应相对于 webbrowsers 视口您可以使用 getBoundingClientRect();
大小只有 1x1,因为我们想要 1 个像素。

这一切都应该在用户滚动时发生,您可以使用.scroll(function); 捕获滚动事件:

   $(window).scroll(function () {
        var offset = document.getElementById('color').getBoundingClientRect(),
            offsetX = offset.left,
            offsetY = offset.top;

        var color = document.getElementById('c').getContext('2d').getImageData(offsetX, offsetY, 1, 1).data;
        $('header').css('background-color',"rgba("+ color[0] + ', ' + color[1] + ', '+ color[2] + ', ' + color[3] + ")");
    });

我们在header 元素中添加带有纯 css 的前 4 个索引的 rgba 数组颜色(因为 rgba 颜色模式永远不会有超过 4 个值)。

将外部图像加载到画布中

当您想将外部图像转换为画布元素时,您可能会收到以下错误:

跨域资源共享策略拒绝跨域图像加载。

由于security 的原因,您无法完全访问此图像。

如此处所述:HTML 5 canvas getImageData from an externally-loaded image

有一些外部主机支持这个,例如dropbox

本地

但是,当您将其存储在本地时,它就可以正常工作。

jsFiddle

这个方法已经在chrome、IE和firefox中测试过了。

我想使用那些外部(保管箱)文件

我不确定为什么会发生这种情况,但由于某种原因,这种方法仍然存在一些安全问题。要启用此CORS,您必须添加图像属性.crossOrigin = "Anonymous";。但是,当您使用 HTML 加载图像时,该元素已在没有此属性的情况下生成。因此,您应该在创建图像时分配此属性:

 var canvas = document.getElementById("c"),
        ctx = canvas.getContext("2d"),
        screenWidth = window.innerWidth,
        screenHeight = window.innerHeight;
    // Using image WITH crossOrigin=anonymous
    // Succeeds in Chrome+Mozilla, Still fails in IE
    var externalImage2 = new Image();
    externalImage2.onload = function(){
        canvas.width= screenWidth;
        canvas.height= screenHeight;
        ctx.drawImage(externalImage2, 0, 0, screenWidth, screenHeight);
        // this will FAIL on a CORS violation
    }
    externalImage2.crossOrigin = "Anonymous";                     
    externalImage2.src="https://dl.dropboxusercontent.com/s/8g8lgmdx341j1d6/rainbow_gradient_horizontal.jpg";

这只是我上传到我刚刚分享照片的保管箱的一张照片。注意:

将共享链接转换为直接链接的方法是将域从“www.dropbox.com”更改为“dl.dropboxusercontent.com”。见https://www.dropbox.com/developers/blog/53/programmatically-download-content-from-share-links

来源:Cross-origin image load from cross-enabled site is denied

这会创建一个图像并将其放入一个 existing 画布元素中。所以请注意,您的 HTML 中应该有一个 canvas 元素。

jsFiddle

此方法仅适用于 chrome 和 firefox,因为其他浏览器仍然存在一些安全问题。

补充说明的是,被捕获的像素是“color-pick”元素的左上角像素。如果您希望它捕捉到元素的中间像素,您可以调整此偏移量。


这是一个非常有趣的问题。希望对您有所帮助!

【讨论】:

  • 感谢您的回答,但您的 jsfiddle 无法正常工作。请让标题在移动滚动条时不要从它的位置移动。
  • 您以前的答案有效。但问题是,内容在 bg 图像上滚动,但标题颜色没有改变。
  • @madhukumar 你用的是什么浏览器?你用的是什么例子?你在 jsFiddle 中尝试吗?
  • @madhukumar 打开 F12 时会抛出任何错误吗? jsFiddle 不需要这个“头标签”,因为它在 jsFiddle 中被选为扩展。
  • 在dreamweaver 中执行并且浏览器是chrome 时出现此错误。 “未捕获的 TypeMismatchError:对象的类型与与该对象关联的参数的预期类型不兼容。” jsfiddle 根本没有改变颜色。标头也不固定在一个地方。
【解决方案2】:

好吧,如果主页和内容之间没有边框,您可以将主页栏的背景颜色设置为透明。

.home{
 background:transparent;
 }

【讨论】:

  • 也许你应该换个问题让我们更容易理解。
  • 我认为这个问题并不难理解。
猜你喜欢
  • 2019-09-29
  • 2014-10-14
  • 1970-01-01
  • 2023-03-27
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
相关资源
最近更新 更多