nos*_*hcd 3 html5 internet-explorer svg canvas windows-runtime
目标:使用html5和JavaScript将CSS过滤器应用于视频.
Contraints:该解决方案必须与Internet Exporer 10兼容(适用于Windows 8).我正在制作一个Metro应用程序.
到目前为止:
我有一个<video>我正在抽水的<canvas>.我以为我可以直接将CSS过滤器应用于此(例如invert或者brightness),但事实证明它们与IE10不兼容.
想法:我希望有一种方法可以将SVG过滤器应用到画布上.这可能吗?我是否需要将其复制<canvas>到<image>并应用过滤器?或者,是否应该有一种方法将画布包裹在<foreignObject>?
以下是一些感兴趣的代码:
filters.svg:
<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="2 3" />
</filter>
</defs>
</svg>
Run Code Online (Sandbox Code Playgroud)
style.css中:
.a {
filter: url(filter.svg#blur);
-ms-transform: matrix(-1, 0, 0, 1, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
page.html中:
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
<canvas class="a" style="width: 180px;height:180px;margin-bottom: -5px;" data-win-bind="style.backgroundColor: bc; id: effectId" />
</div>
Run Code Online (Sandbox Code Playgroud)
下面的代码作品,尽管速度很慢,要完成我的目标.谢谢,安东尼!
<html>
<head>
</head>
<body>
<svg id="svgroot" viewbox="0 0 800 800" width="800" height="800" preserveAspectRatio="xMidYMin">
<defs>
<filter id="myHueRotate">
<feColorMatrix type="hueRotate" values="270"/>
</filter>
</defs>
<image id="a" filter="url(#myHueRotate)" x="0" y="0" width="300" height="300" />
<image id="b" filter="url(#myHueRotate)" x="300" y="0" width="300" height="300" />
<image id="c" filter="url(#myHueRotate)" x="0" y="300" width="300" height="300" />
<image id="d" filter="url(#myHueRotate)" x="300" y="300" width="300" height="300" />
</svg>
<canvas id="canvas" height="300" width="300"></canvas>
<video id="vid" src="movie.m4v" height="300" width="300" style="display: none" autoplay/>
<script>
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = 'img.jpg';
img.onload = function(){
//ctx.drawImage(img,0,0);
//var canvasImage = canvas.toDataURL("image/png");
//var svgImage = document.getElementById('a');
//svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage);
draw();
}
img.load();
function draw(){
var ctx = document.getElementById('canvas').getContext('2d');
var vid = document.getElementById('vid')
ctx.drawImage(vid,0,0,300,300);
var canvasImage = canvas.toDataURL("image/png");
document.getElementById('a').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage);
document.getElementById('b').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage);
document.getElementById('c').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage);
document.getElementById('d').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage);
setTimeout(draw,40);
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
首先,文章阅读:
特别注意以下部分:
使用SVG,而不是VML
和
使用CSS3,而不是DX过滤器
在第二部分中,他们提到:
DX过滤器与SVG过滤器效果不同,但两者都使用CSS属性名称过滤器.
第二篇文章:
他们给出了一个如何使用的具体示例invert,但是,假设它是IE中的方式,我可以看到为什么它不容易找到,可能或可能不适用于您的情况.但css将是:
#yourTargetElement {
filter: DXImageTransform.Microsoft.BasicImage(invert=1);
}
Run Code Online (Sandbox Code Playgroud)
他们没有提到亮度,但他们确实提到了其他几个过滤器和过渡,第一篇文章提到了使用SVG.更多细节(希望对您有帮助):
这看起来像关键的第1部分:
过滤器通过filter属性以filter ="url(#filterId)"的形式应用于SVG元素,或者它可以作为CSS属性过滤器应用:url(#filterId)
这是第2部分:
有16种不同的过滤器基元.
现在,我相信他们提到的16是SVG的全套,但是知道MS,它也可能意味着:
或者,引用Lily Tomlin的话:"我们不在乎,我们没有......我们是电话公司."
但是,假设MS终于意识到他们需要赶上来,进一步阅读16个原始过滤器,据说你只需要嵌入式SVG,过滤器位于正确的位置(defs)并通过css调用它们.这是他们的一个例子(由我稍加修改和简化):
<div id="svg_wrapper">
<svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 800 533" preserveAspectRatio="xMidYMin">
<defs>
<filter id="filtersPicture">
<feComposite operator="arithmetic" k1="0" k2="1" k3="0" k4="0"
in="SourceGraphic" in2="SourceGraphic" result="inputTo_6">
</feComposite>
<feColorMatrix type="saturate" id="filter_6" values="2"
data-filterId="6">
</feColorMatrix>
</filter>
</svg>
</div>
Run Code Online (Sandbox Code Playgroud)
<style type="text/css">
#yourTargetElement{
filter:url(#filtersPicture);
}
</style>
Run Code Online (Sandbox Code Playgroud)
我之所以提醒他们看起来"简单"的原因是因为他们通过js和交互式表单添加了风格(也许你有同样的想法),但我认为这与调用元素的风险相同它之前的脚本在DOM中,因为它找不到过滤器并抛出错误.因此,请确保您想要保持简单(非动态)并且仍然无法正常工作,尝试将filter/svg放在样式之上(即使这会导致闪烁).