Reputation: 1493
I want to fill a svg element e.g. a circle
element with an image that the user can select from his local computer via a <input type='file'/>
input.
I know that you can fill a svg element using a pattern:
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="wall.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
<circle cx=100 cy=100 r=100 fill="url(#img1)" />
But I can't get it to work with a local Image.
A working fiddle would be amazing :)
Related Issues:
Fill SVG path element with a background-image
Thanks!
Upvotes: 3
Views: 3739
Reputation: 29022
You will find a decent example here. It uses a minimum of JavaScript to update the pattern
. Adapted to your given code, the result could look like this:
<html>
<head>
<script>
var E;
function prepare(){ E=document.getElementById('imgPath'); }
function change(v){ E.setAttribute("xlink:href", v); }
</script>
</head>
<body onload="prepare()">
<table border="2">
<tr><td><input type="file" formmethod="GET" onchange="change(this.value)" /></td></tr>
<tr><td>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="320" height="286" viewBox="0 0 320 86">
<defs>
<pattern id="imgPattern" patternUnits="userSpaceOnUse" width="100" height="100">
<image id="imgPath" xlink:href="wall2.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
<circle cx=100 cy=100 r=100 fill="url(#imgPattern)" />
</svg>
</td></tr>
</table>
</body>
</html>
It just gets the id
for the image path with JavaScript and then sets the SVG's xlink:href
attribute triggered by the onchange
event.
Upvotes: -1
Reputation: 2371
This seems to work in latest Chrome and Firefox.
First, HTML part:
<input id="upload" type="file"/>
<svg>
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="wall.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
<circle cx=100 cy=100 r=100 fill="url(#img1)" />
</svg>
Next, JS part:
var upload = document.getElementById('upload');
var patternImage = document.querySelector('#img1 image');
var currentBlobData = null;
upload.addEventListener('change', function (e) {
var file = this.files[0];
if (currentBlobData) {
URL.revokeObjectURL(currentBlobData);
}
currentBlobData = URL.createObjectURL(file);
patternImage.setAttribute('xlink:href', currentBlobData);
});
Finally, a working fiddle demo: https://jsfiddle.net/5qLb9m1t/
Upvotes: 2