我正在使用JavaFX应用程序,该应用程序使用JavaFX WebView浏览器显示Sencha Touch Web应用程序。长话短说,Sencha Touch应用程序最初是通过其他浏览器访问的,但将来需要在运行JavaFX WebView的设备上进行访问。这使事情有些混乱,但是通常这是一个非常无缝的过渡。

我遇到的问题来自我们对-webkit-mask-image CSS属性的使用。我们正在使用此属性快速为许多按钮和其他图像着色,以适应所使用的任何着色方案。不幸的是,JavaFX WebView似乎对-webkit-mask-image的处理方式非常困惑,并且所有这些图像都被扭曲了。

我做了功课,并提出了this blog post,它描述了如何使用svg的foreignObject在其他浏览器中实现类似于-webkit-mask-image的效果。

根据该文章,我将以下html添加到我的Sencha Touch应用程序中,只是为了查看它如何在JavaFX WebView中呈现:

<svg width="400px" height="300px">
  <defs>
    <mask id="mask" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
      <image width="400px" height="300px" xlink:href="foo.png"></image>
    </mask>
  </defs>
  <foreignObject width="400px" height="300px" style="mask: url(#mask);">
    <div style="display:inline-block;background-color:blue;width:400px;height:300px">
    </div>
  </foreignObject>
</svg>


遮罩图像“ foo.png”是带有某些透明胶片的白色图像。当我们使用-webkit-mask-image时,蒙版图像为黑色,但我根据博客文章的建议将其反转。实际上,这在Firefox中效果很好,我希望这是个好消息(因为以前我们的图像遮罩在Firefox中不起作用)。 Firefox显示了一个漂亮的蓝色div,并用“ foo.png”掩盖了。我漫长的噩梦结束了!

除了不是。在JavaFX WebView中,它仅显示一个蓝色框。为了确保它可以访问“ foo.png”,我尝试将其作为常规的旧<img>标记,并显示图像,所以这不是问题。

我确实在OpenJDK上找到了this bug,这听起来与我的问题非常相似,尽管它仍被列为“开放”并且并没有引导我很远。

此外,我发现作者正在尝试执行类似的this question。此操作与我要尝试执行的操作之间的区别在于,在该解决方案中,他希望在图像中显示并遮罩/显示该图像的某些部分。我想做的是有一个彩色的div,并用透明胶片掩盖图像。这是一个例子:



.something-red {
  background-color: red;
  width: 400px;
  height: 365px;
  -webkit-mask-size: 400px;
  -webkit-mask-image: url(http://i.imgur.com/cWSCfGl.png);
}

<div class='something-red'>
</div>





我的临时解决方案是用(我自己)已预先着色的静态图像替换我们的图像蒙版。这看起来不像我们能够掩盖图像时那样好,当然,这也意味着我必须为我们要使用的任何配色方案创建具有不同颜色的重复图像。

有没有办法在JavaFX WebView浏览器中实现类似-webkit-mask-image的功能?非常感谢您抽出宝贵的时间阅读我的问题,希望我提供了足够的信息!

最佳答案

我找到了一种在JavaFX浏览器中模拟SVG屏蔽的方法。我没有尝试强制支持-webkit-mask-image,而是找到了一个浏览器polyfill来启用我在问题中引用的文章中所述的SVG遮罩类型。

Modernizr polyfill collection包含无数的javascript库,旨在帮助添加对多个功能的跨浏览器支持。在尝试了其中一些方法之后,我选择了canvg,它将将SVG定义转换为canvas元素,并在其上绘制了对象。看一下他的示例页面,看看它的实际效果-它使您可以编辑SVG输入,从而可以查看代码是否适合您。

因此,要实现此解决方案,您必须做四件事。首先,在需要图像的位置创建一个canvas元素。请注意,无论图像大小如何,都应为其提供宽度和高度。

<canvas id='foo'></canvas>


接下来,获取对画布的引用。这将由canvg库使用。

var canvas = document.getElementById('foo');


第三,创建您的svg。 canvg支持几种不同的格式,但我只是将其作为XML字符串提供:

var svg =
        '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 100 100">' +
            '<defs>'+
              '<mask id="Mask" maskUnits="userSpaceOnUse">'+
                '<image width="100" height="100" xlink:href="fooBar.png"></image>' +
              '</mask>'+
              '<rect id="rect" x="0" y="0" width="100" height="100" style="stroke-width:0px"/>'+
            '</defs>'+
            '<use xlink:href="#rect" mask="url(#Mask)" fill="red"/>'+
        '</svg>';


请注意,这与我在问题中引用的SVG遮罩文章非常相似,但并不完全相同。它定义一个遮罩,然后是一个矩形,然后简单地遮罩该矩形。

您要做的最后一件事是像这样调用canvg:

canvg(canvas, svg);


这应该在JavaFX浏览器中启用图像遮罩,但是由于我特别询问了Sencha Touch,因此我将提及如何将其添加到我的Sencha Touch应用程序中。

在屏幕上呈现元素之后,使用Ext的组件查询获取对该元素的引用:

var component = Ext.ComponentQuery.query('#itemId');

接下来,如上所述生成画布HTML元素。然后,执行以下操作:

component.setHtml(yourCanvasHtmlElement);


现在,您的组件包含一个空的canvas元素。这就是canvg将要使用的元素。如上所述,调用canvg,canvas元素将更新。

关于html - JavaFX WebView在Sencha Touch应用程序中不显示蒙版图像,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35260477/

10-12 00:32
查看更多