I am trying to draw shapes on top of an HTML5 video, but am having trouble figuring out how to do it. I know how to apply a mask on top of the video:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG Test</title>
</head>
<body>
<video class="target1" height="270px" width="480px" controls >
<source src="testVideo.webm" type="video/webm" />
</video>
<!-- Apply a mask to the video -->
<style>
.target1 { mask: url("#mask1"); }
</style>
<!-- Define the mask with SVG -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width="480px" height="270px">
<defs>
<mask id="mask1" maskUnits="objectBoundingBox"
maskContentUnits="objectBoundingBox">
<circle cx="0.25" cy="0.25" r="0.5" fill="white" />
</mask>
</defs>
</svg>
</body>
</html>
But how do I do something like draw a polyline on top of the video?
<polyline id="line" points="0,0 25,25, 25,50 75,50 100,100, 125,125"
style="fill:none;stroke:orange;stroke-width:3" />
I can draw the line elsewhere on the page, like so:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG Test</title>
</head>
<body>
<video class="target1" height="270px" width="480px" controls >
<source src="testVideo.webm" type="video/webm" />
</video>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1200px" height="700px">
<polyline id="line" points="0,0 25,25, 25,50 75,50 100,100, 125,125"
style="fill:none;stroke:orange;stroke-width:3" />
</svg>
</body>
</html>
But I just can't figure out how to get the line on top of the video. Any help would be greatly appreciated!
yes, css solution is one option. try to put those two elements above either in one div or (as jörn pointed out) with absolute positioning. z-index is very useful, to make sure your svg is really on top.
<div id="canvas">
<video id="videoContainer"> (...) </video>
<svg id="svgContainer"> (...) </svg>
</div>
<style>
canvas{ position:relative; width:480px; height:240px; }
videoContainer{ position:relative; width:100%; height:100%; z-index:1 }
svgContainer{ position:relative; width:100%; height:100%; z-index:2 }
</style>
use CSS position:absolute to position your SVG where you want it.
<style> svg { position:absolute; top:20px; left:40px; }</style>
the above example should positions the svg 20 px from the top of the page and 40px from the left
Related
I want to embed a video into an SVG to be displayed on a website, but I'm facing some issues with both playback and also responsive sizing. the code is below:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 1050 550" style="enable-background:new 0 0 1050 550;" preserveAspectRatio="xMaxYMid" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
<style type="text/css">
.background{fill:#4D4D4D;}
.box{stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
</style>
<rect id="Background" class="background" width="1050" height="550" bx:origin="0 0">
<title>background</title>
</rect>
<foreignObject>
<video xmlns="http://www.w3.org/1999/xhtml" width="800" controls="" style="position: fixed; left: 101px; top: 51px;">>
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4"></source>
</video>
</foreignObject>
<rect id="Box" class="box" width="800" height="450" y="50" style="fill: none;" x="100" bx:origin="0 0">
<title>background</title>
</rect>
</svg>
RE: sizing - I've tried using "vw" and "em" sizing conventions for this but when I do, the video doesn't show at all.
RE: playback - there is no way I can add "controls" to the foreignObject class - it just gives me an error and won't render the SVG.
Can anyone help or think of any ideas here? Would be really grateful :)
Then main issue is that the <foreignObject> should have a size, just like other SVG elements.
I couldn't get the video to show, so I picked another one.
<svg viewBox="0 0 340 200" xmlns="http://www.w3.org/2000/svg">
<rect id="Background" class="background" width="340"
height="200" fill="gray" />
<foreignObject width="320" height="180" x="10" y="10">
<video xmlns="http://www.w3.org/1999/xhtml" width="320"
height="180" controls>
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4"/>
</video>
</foreignObject>
<rect width="340" height="100" y="100" fill="black"
opacity=".3" pointer-events="none" />
</svg>
Update
I'm not able to reproduce the error "error on line 14 at column 56: Specification mandates value for attribute controls", but make sure that the control attribute has a value (or, like here controls=""), now that it is an XML document.
In the following example I have the SVG document and a HTML document. Both documents have a stylesheet that behaves responsive at 300 and 400 pixel width. This seams to work fine.
SVG document (video.svg)
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 340 200" xmlns="http://www.w3.org/2000/svg">
<style>
.backgrond {
fill: gray;
}
#media (min-width: 300px) {
.background {
fill: orange;
}
}
</style>
<rect class="background" width="340" height="200" fill="gray" />
<foreignObject width="320" height="180" x="10" y="10">
<video xmlns="http://www.w3.org/1999/xhtml" width="320"
height="180" controls="">
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4"/>
</video>
</foreignObject>
<rect width="340" height="100" y="100" fill="black"
opacity=".3" pointer-events="none" />
</svg>
HTML document
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.video {
width: 100%;
}
#media (min-width: 400px) {
.video {
width: 400px;
}
}
</style>
</head>
<body>
<object class="video" type="image/svg+xml" data="video.svg"></object>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<style>
body, html {
height: 100%;
background-color:#eee;
margin:0;
padding:0;
overflow: hidden;
}
path {
fill: #eee;
stroke: #000;
stroke-width:1;
pointer-events: visible;
}
</style>
</head>
<body>
<svg width="100%" height="100%" >
<pattern id="pattern-hex" x="0" y="0" width="112" height="190" patternUnits="userSpaceOnUse" viewBox="56 -254 112 190">
<g id="hexagon">
<path class="bla" d="M168-127.1c0.5,0,1,0.1,1.3,0.3l53.4,30.5c0.7,0.4,1.3,1.4,1.3,2.2v61c0,0.8-0.6,1.8-1.3,2.2L169.3-0.3 c-0.7,0.4-1.9,0.4-2.6,0l-53.4-30.5c-0.7-0.4-1.3-1.4-1.3-2.2v-61c0-0.8,0.6-1.8,1.3-2.2l53.4-30.5C167-127,167.5-127.1,168-127.1 L168-127.1z"/>
<path class="bla" d="M112-222.5c0.5,0,1,0.1,1.3,0.3l53.4,30.5c0.7,0.4,1.3,1.4,1.3,2.2v61c0,0.8-0.6,1.8-1.3,2.2l-53.4,30.5 c-0.7,0.4-1.9,0.4-2.6,0l-53.4-30.5c-0.7-0.4-1.3-1.4-1.3-2.2v-61c0-0.8,0.6-1.8,1.3-2.2l53.4-30.5 C111-222.4,111.5-222.5,112-222.5L112-222.5z"/>
<path class="bla" d="M168-317.8c0.5,0,1,0.1,1.3,0.3l53.4,30.5c0.7,0.4,1.3,1.4,1.3,2.2v61c0,0.8-0.6,1.8-1.3,2.2L169.3-191 c-0.7,0.4-1.9,0.4-2.6,0l-53.4-30.5c-0.7-0.4-1.3-1.4-1.3-2.2v-61c0-0.8,0.6-1.8,1.3-2.2l53.4-30.5 C167-317.7,167.5-317.8,168-317.8L168-317.8z"/>
</g>
</pattern>
<!-- The canvas for our pattern -->
<rect x="0" y="0" width="100%" height="100%" fill="url(#pattern-hex)" />
</svg>
</body>
</html>
How would I go about changing the SVG pattern's stroke color on hover via CSS? I read elsewhere that SVG patterns might not accept pure CSS hover changes, and I'd have to rely on JS events attached to the individual paths?
I am using an external svg file and applying a mask from the file to an image on my web page. The mask is working well, but I'd like to have a colored stroke around the mask. I can't figure out how to add just a shape in an external svg file and how to apply that with CSS.
Right now the mask has a semi transparent stroke to kind of illustrate the size of the stroke I would like with color.
How could I add this?
Thanks
External SVG File:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<mask id="m1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
<circle cx=".5" cy=".5" r=".45" style="stroke:#909; stroke-width:.05; fill: #ffffff"/>
</mask>
</svg>
HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>test mask</title>
<style>
body {
background-color:LightBlue;
}
.masked {
mask: url(svg/filters.xml#m1);
}
</style>
</head>
<body>
<div class="item">
<a href="#">
<img class="masked" src="http://i.imgur.com/nSdiEn3.jpg"/>
</a>
</div>
</body>
</html>
Create another path with the dimensions of the masked portion with:
fill-opacity="0.0" stroke="#000000" stroke-width="2"
(replace stroke and stroke-width with the desired values)
I don't know if this is possible, but I would like to cut holes in an opaque wrapper set to the height and width of the window to a layer of video beneath it using a div positioned within wrapper.
Here is a jsFiddle with the desired layout set up and further explanation:
http://jsfiddle.net/XuYxg/
Any help, or an alternate method would be very helpful. Thanks!
You could use a transparent png or svg to create the shape overlay, with the blank areas in effect becoming the mask or you could use the clip or mask property in CSS.
Here's a jsFiddle example using svg.
External JS/CSS:
<link href="http://vjs.zencdn.net/4.3/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.3/video.js"></script>
HTML:
<body>
<!--VideoJS linked to default video for placeholder -->
<div id="videoDiv">
<video id="example_video_1" class="video-js vjs-default-skin" autoplay controls preload="none" width="900" height="600"
poster="http://video-js.zencoder.com/oceans-clip.png"
data-setup="{}">
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
<track kind="captions" src="demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
<track kind="subtitles" src="demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
</video>
</div>
<!--End Video JS-->
<!--SVG Mask, output from Adobe Illustrator -->
<div id="wrapper">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="900px" height="600px" viewBox="0 0 900 600" enable-background="new 0 0 900 600" xml:space="preserve">
<g>
<path stroke="#FFFFFF" stroke-miterlimit="10" d="M0,0v600h900V0H0z M316.549,351.231h-30.796v-92.803l-23.729,92.803h-27.875
l-23.685-92.803v92.803h-30.796V229.542h49.452l19.07,74.043l18.936-74.043h49.422V351.231z M421.439,351.231l-6.088-20.088h-42.69
l-5.932,20.088h-38.394l45.737-121.689h41.017l45.727,121.689H421.439z M570.138,333.218c-4.316,6.586-10.349,11.58-18.096,14.983
c-7.748,3.403-17.515,5.105-29.302,5.105c-20.697,0-35.029-3.984-42.998-11.953s-12.479-18.096-13.53-30.381l35.776-2.241
c0.774,5.811,2.352,10.238,4.731,13.281c3.873,4.926,9.407,7.388,16.602,7.388c5.367,0,9.505-1.258,12.409-3.777
c2.906-2.517,4.358-5.437,4.358-8.757c0-3.154-1.384-5.977-4.15-8.467c-2.768-2.49-9.187-4.842-19.258-7.056
c-16.491-3.707-28.251-8.633-35.278-14.775c-7.084-6.143-10.625-13.973-10.625-23.491c0-6.253,1.812-12.161,5.438-17.722
c3.623-5.562,9.074-9.932,16.352-13.115c7.276-3.182,17.252-4.773,29.925-4.773c15.55,0,27.405,2.892,35.569,8.674
c8.161,5.783,13.018,14.983,14.567,27.6l-35.444,2.075c-0.941-5.479-2.92-9.463-5.936-11.953c-3.017-2.49-7.18-3.735-12.492-3.735
c-4.372,0-7.665,0.927-9.878,2.781c-2.214,1.855-3.32,4.109-3.32,6.765c0,1.938,0.913,3.681,2.739,5.229
c1.771,1.606,5.977,3.1,12.617,4.482c16.436,3.542,28.208,7.126,35.32,10.75c7.109,3.625,12.285,8.122,15.521,13.489
c3.238,5.368,4.856,11.372,4.856,18.013C576.612,319.439,574.454,326.633,570.138,333.218z M678.392,351.231l-25.657-50.045
l-19.428,20.35v29.695h-37.603V229.542h37.603v45.986l39.389-45.986h50.011L678.3,275.473l46.398,75.758H678.392z"/>
<polygon stroke="#FFFFFF" stroke-miterlimit="10" points="380.828,304.83 407.552,304.83 394.12,261.084 "/>
</g>
</svg>
</div>
<!--End SVG Mask-->
</body>
CSS:
#wrapper {
position: absolute;
height: 100%;
width: 100%;
z-index: 5;
}
#videoDiv {
position: absolute;
z-index: -5;
}
Is it possible to put a div inside an svg shape?
Here's an example of what I'm trying to do:
<!DOCTYPE html>
<html>
<body xmlns="http://www.w3.org/1999/xhtml">
<svg id="main" xmlns="http://www.w3.org/2000/svg" version="1.1">
<foreignObject x="10" y="10" width="100" height="150">
<div>I'm a div in an svg</div>
</foreignObject>
<rect fill="red" stroke="darkred" class="box" x="90" y="90" rx="20" ry="20" width="320" height="320" id="box_0">
<foreignObject width="100" height="50">
<body xmlns="http://www.w3.org/1999/xhtml">
<div>Hi, I'm a div inside a shape!! I don't work :(</div>
</body>
</foreignObject>
</rect>
</svg>
</body>
</html>
The second <div> doesn't show, is this somehow doable?
A <rect> element cannot have a <foreignObject> element as a child. You'd have to make the <foreignObject> element a later sibling and locate it on top of the rect element.