SVG: text inside rect - text

I want to display some text inside SVG rect. Is it possible?
I tried
<svg xmlns="http://www.w3.org/2000/svg">
<g>
<rect x="0" y="0" width="100" height="100" fill="red">
<text x="0" y="10" font-family="Verdana" font-size="55" fill="blue"> Hello </text>
</rect>
</g>
</svg>
But it does not work.

This is not possible. If you want to display text inside a rect element you should put them both in a group with the text element coming after the rect element ( so it appears on top ).
<svg xmlns="http://www.w3.org/2000/svg">
<g>
<rect x="0" y="0" width="100" height="100" fill="red"></rect>
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue">Hello</text>
</g>
</svg>

Programmatically using D3:
body = d3.select('body')
svg = body.append('svg').attr('height', 600).attr('width', 200)
rect = svg.append('rect').transition().duration(500).attr('width', 150)
.attr('height', 100)
.attr('x', 40)
.attr('y', 100)
.style('fill', 'white')
.attr('stroke', 'black')
text = svg.append('text').text('This is some information about whatever')
.attr('x', 50)
.attr('y', 150)
.attr('fill', 'black')

You can use foreignobject for more control and placing rich HTML content over rect or circle
<svg width="250" height="250" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="250" height="250" fill="aquamarine" />
<foreignobject x="0" y="0" width="250" height="250">
<body xmlns="http://www.w3.org/1999/xhtml">
<div>Here is a long text that runs more than one line and works as a paragraph</div>
<br />
<div>This is <u>UNDER LINE</u> one</div>
<br />
<div>This is <b>BOLD</b> one</div>
<br />
<div>This is <i>Italic</i> one</div>
</body>
</foreignobject>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(145,200,103);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(132,168,86);stop-opacity:1" />
</linearGradient>
</defs>
<rect width="220" height="30" class="GradientBorder" fill="url(#grad1)" />
<text x="60" y="20" font-family="Calibri" font-size="20" fill="white" >My Code , Your Achivement....... </text>
</g>
</svg>

Programmatically display text over rect using basic Javascript
var svg = document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'svg')[0];
var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('x', 20);
text.setAttribute('y', 50);
text.setAttribute('width', 500);
text.style.fill = 'red';
text.style.fontFamily = 'Verdana';
text.style.fontSize = '35';
text.innerHTML = "Some text line";
svg.appendChild(text);
var text2 = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text2.setAttribute('x', 20);
text2.setAttribute('y', 100);
text2.setAttribute('width', 500);
text2.style.fill = 'green';
text2.style.fontFamily = 'Calibri';
text2.style.fontSize = '35';
text2.style.fontStyle = 'italic';
text2.innerHTML = "Some italic line";
svg.appendChild(text2);
var text3 = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text3.setAttribute('x', 20);
text3.setAttribute('y', 150);
text3.setAttribute('width', 500);
text3.style.fill = 'green';
text3.style.fontFamily = 'Calibri';
text3.style.fontSize = '35';
text3.style.fontWeight = 700;
text3.innerHTML = "Some bold line";
svg.appendChild(text3);
<svg width="510" height="250" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="510" height="250" fill="aquamarine" />
</svg>

Related

SVG <use> ignores Gradient styling

I have a svg file that does not render gradient in the <use> tag. Why is it behaving differently, and how can I fix it?
SVG File:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"
style="stroke:#000000;stroke-width:2"
xml:space="preserve"
id="pb_svg_1">
<rect width="50" height="50" style="fill: url(#lg1)"/>
<defs>
<linearGradient id="lg1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(88,88,88);stop-opacity:1"></stop>
<stop offset="100%" style="stop-color:rgb(255,255,255);stop-opacity:1"></stop>
</linearGradient>
</defs>
</svg>
These are 3 methods I render the svg. 2 work but the one I need does not:
<!-- Does NOT include gradient style -->
<svg width="100" height="100">
<use href="12.svg#pb_svg_1" width="100" height="100"/>
</svg>
<!-- Gradient style works! -->
<div>
<object data="12.svg" width="100" height="100"></object>
</div>
<!-- Gradient style works! -->
<div style="width: 100px;height: 100px">
<embed src="12.svg"/>
</div>
I expect the use element to render the file as it does when the svg is on the same page.
EDIT: It does work in firefox and does not work in chrome and edge
Workaround: define gadients in an inlined svg
Move the gradient <defs> to an inlined hidden <svg>.
It's important to hide this svg via zero width and height properties like width:0; height:0;position:absolute;.
display:none or visibility:hidden will remove/disable gradients, clip paths etc.
<!-- HTML svg use instance -->
<svg width="100" height="100" viewBox="0 0 100 100">
<use href="#pb_svg_1" style="fill: url(#lg1); stroke:#000000;stroke-width:2 "/>
</svg>
<!-- Inline svg: hidden gradient definition -->
<svg style="width:0; height:0; position:absolute;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
<defs>
<linearGradient id="lg1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(88,88,88);stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,255,255);stop-opacity:1"/>
</linearGradient>
</defs>
</svg>
<!-- External svg: 12.svg -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="pb_svg_1" viewBox="0 0 100 100">
<rect x="0" y="0" width="50" height="50" /></symbol>
</svg>
Workaround 2: inline external use references
If refactoring all svg assets isn't feasible – change your embedding method.
2.1 via fetch
HTML
<!-- HTML svg use instance -->
<svg width="100" height="100" viewBox="0 0 100 100">
<use href="12.svg#pb_svg_1" />
</svg>
Js
inlineExternalUse();
function inlineExternalUse(){
let extSvgs = document.querySelectorAll('use');
if(extSvgs.length){
extSvgs.forEach(function(item, i){
let href = item.getAttribute('href') ? item.getAttribute('href') : item.getAttribute('xlink:href');
// change href to inline reference
let hrefNew = '#'+href.split('#')[1];
item.setAttribute('href', hrefNew);
fetch(href)
.then(response => response.text() )
.then(data => {
//inline ext svg
let parser = new DOMParser();
let svgInline = parser.parseFromString(data, "application/xml").querySelector('svg');
svgInline.setAttribute('aria-hidden', 'true')
svgInline.style.width=0;
svgInline.style.height=0;
svgInline.style.position='absolute';
document.body.appendChild(svgInline);
});
});
}
}
2.2: via native web component
See #Danny '365CSI' Engelman's article "〈load-file〉Web Component, add external content to the DOM" or this answer "How to change the color of an svg element?"

How to create an SVG icon consisting of two overlapping shapes, one with a hole?

I have made a progress bar icon from two partially overlapping SVG shapes.
I would like the icon to have the same color as the surrounding text, so I set stroke and fill to currentColor.
The icon is displayed correctly if the color of the surrounding text doesn't have alpha channel e.g. color: black. However, if the color of the surrounding text has alpha channel e.g. color: rgba (0, 0, 0, 0.7), then the icon is darker where the shapes overlap.
How can I get the same color at each point of the icon?
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
Question Prevent overlapping figures with alpha channel from shading each other? is very similar, but the accepted answer doesn't work in this case:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<clipPath id="myClip">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="black" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" />
</clipPath>
</defs>
<rect width="100%" height="100%" fill="currentColor" clip-path="url(#myClip)"/>
</svg>
Update:
I decided to draw the icon without overlapping parts, because it is much easier and it also looks good:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="4" y="4" width="23" height="7" rx="2" ry="2" fill="currentColor" />
</svg>
One solution is to user a mask. But if you don't change the geometry, you will get the same issue as with #InvisibleGorilla's solution: you will get antialiasing artifacts.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2.5" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
To fix the antialiasing artifacts, move your bar so that it is positioned at a whole pixel (y="2") instead of a half pixel (y="2.5"). You still might still see very slight artifacts at some scales. But it should be a lot better.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
Before the rect where fill has currentColor, add a rect with the exact same attributes but with a white fill directly before it (so that it gets drawn underneath it in the svg).
See snipped below:
<style>
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="white" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
You could also change the order of your rects and add a matching white rect under the one where the stroke has currentColor.
Here's the updated snippet using background color and underlying both rects. I've tested on Chrome and Firefox on Mac and I don't see any lines from the background color rects.
<style>
body { background-color: #232b32; color: rgba(240, 240, 240, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="#232b32" stroke-width="2" fill="transparent" />
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="#232b32" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
<p>Some text</p>
Here's a screenshot of when I run this snippet.

Why is my SVG not looking like a ripple (regarding the feDisplacementMap filter)

I am trying to make a ripple filter:
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#fff"></stop>
</radialGradient>
This works perfectly in that it makes many circles. But when I sum these two filters, I only get the filter (#f) effect; why does my radialGradient (#g) effect get lost? (See full code below.)
I am expecting it to look like the following:
Reference:
https://www.oxxostudio.tw/articles/201410/svg-28-filter-feDisplacementMap.html
https://www.oxxostudio.tw/articles/201410/svg-29-filter-water-ripple.html
<svg width="340" height="231">
<defs>
<filter id="f" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox" x="0" y="0" width="1.1"
height="1.1">
<feImage result="pict1" xlink:href="#m1" x="0" y="0" width="1.1" height="1.1"></feImage>
<feImage result="pict2" xlink:href="#m2" x="0" y="0" width="1.1" height="1.1"></feImage>
<feDisplacementMap id="fdm" scale=".1" xChannelSelector="R" yChannelSelector="R" in2="pict2" in="pict1">
</feDisplacementMap>
</filter>
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#fff"></stop>
</radialGradient>
<rect id="m2" x="-10" y="0" width="410" height="300" fill="url(#g)"></rect>
<image id="m1" x="0" y="0" width="400" height="300"
xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG"></image>
</defs>
<rect x="0" y="0" width="400" height="300" filter="url(#f)" transform="translate(-60 -60)"></rect>
</svg>
==================2020 03 17=====================
thx to respond my ask
make me find the point
============================
For the feImage you need to use an external svg or, as I did, a data:uri. If you want to use data:uri you can use this svg-encoder
now it's work perfect
Reference:
https://codepen.io/enxaneta/post/svg-waves-with-fedisplacementmap
const filterFeImage = document.querySelector("#f feImage");
const xlink = "http://www.w3.org/1999/xlink";
let div = document.getElementById('div');
let svg = document.getElementById('svg');
let width = div.offsetWidth;
let height = div.offsetHeight;
svg.innerHTML = '<g id="svgandg" filter="url(#f)"><image id="Darwin" xmlns:xlink="http://www.w3.org/1999/xlink"xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG" width="' + width + '" height="'+ height +'"></image><text id="text" text-anchor="middle" x="' + (width / 2) +'" y="' + (height / 2) +'" style="font-size:180px;font-weight:900;"> How Are You </text></g>';
let displacement = 0;
let speed = 0.2;
function setXlinkHref() {
/*
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width="300" height="300">
<defs>
<radialGradient id="rg" r=".9">
*/
let xlinkHref =
"data:image/svg+xml;utf8,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='" + width + "' height='" + height + "'%3E%3Cdefs%3E%3CradialGradient id='rg' r='.9'%3E";
/*
<stop offset='0%' stop-color='#f00'></stop>
<stop offset='10% 'stop-color='#000'></stop>
<stop offset='20%' stop-color='#f00'></stop>
<stop offset='30%' stop-color='#000'></stop>
<stop offset='40%' stop-color='#f00'></stop>
<stop offset='50%' stop-color='#000'></stop>
<stop offset='60%' stop-color='#f00'></stop>
<stop offset='70%' stop-color='#000'></stop>
<stop offset='80% 'stop-color='#f00'></stop>
<stop offset='90%' stop-color='#f00'></stop>
<stop offset='100%' stop-color='#f00'></stop>
*/
for (var i = 0; i < 11; i++) {
// offset='${(i - 2) * 20 + displacement * 2}%25' 可以控制每一個波的波長
xlinkHref += `%3Cstop
offset='${(i - 2) * 20 + displacement * 2}%25'
stop%2Dcolor='%23${i % 2 == 0 ? "f00" : "000"}'%3E%3C/stop%3E`;
}
/*
</radialGradient>
<rect id="witness" width="300" height="300" fill="url(#rg)"></rect>*/
xlinkHref +=
"%3C/radialGradient%3E%3C/defs%3E%3Crect id='witness' width='"+ width +"' height='" + height + "' fill='url(%23rg)'%3E%3C/rect%3E%3C/svg%3E";
return xlinkHref;
}
function AnimateOffset() {
let xlinkHref = setXlinkHref();
filterFeImage.setAttributeNS(xlink, "href", xlinkHref);
// ripples.setAttributeNS(xlink, "href", xlinkHref);
if (displacement <= 20) {
displacement += speed;
} else {
displacement = 0;
}
// window.requestAnimationFrame(AnimateOffset);
}
// 設定楨數的地方
setInterval(() => {
AnimateOffset();
}, 66);
// window.requestAnimationFrame(AnimateOffset);
*{
margin: 0;
padding: 0;
list-style: none;
}
.div{
width: 100%;
height: 100vh;
background: url("20180319090858589.jpg");
}
.div svg{
width: 100%;
height: 100%;
}
<svg>
<defs>
<filter id="f" primitiveUnits="objectBoundingBox">
<feImage result="pict2" xlink:href=""></feImage>
<feDisplacementMap scale=".05" xChannelSelector="R" yChannelSelector="R" in2="pict2" in="SourceGraphic">
<!-- 需要重複漣漪所以需要改能用透明度去互相覆蓋 -->
</feDisplacementMap>
</filter>
</defs>
</svg>
<div class="div" id="div">
<svg id="svg">
<!-- <g id="svgandg" filter="url(#f)">
<image id="Darwin" xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg">
</image>
<text id="text" x="0" y="150" style="font-size:50px;font-weight:900;"> How Are You </text>
</g> -->
</svg>
</div>
Several things:
Since you are using xChannelSelector="R" yChannelSelector="R" where R stands for red the gradient needs to have some red.
You need to fill the rect for the feImage with the gradient.
<svg>
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#f00"></stop>
</radialGradient>
<rect id="m1" width="410" height="300" fill="url(#g)"></rect>
</svg>
For the feImage you need to use an external svg or, as I did, a data:uri. If you want to use data:uri you can use this svg-encoder
You apply the filter to the image.
I hope it helps.
<svg width="340" height="231">
<filter id="f" >
<feImage result="pict1" xlink:href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3CradialGradient id='g' cx='.6' cy='.6' r='.05' spreadMethod='reflect'%3E%3Cstop offset='0' stop-color='%23000'%3E%3C/stop%3E%3Cstop offset='1' stop-color='%23f00'%3E%3C/stop%3E%3C/radialGradient%3E%3Crect id='m1' width='340' height='230' fill='url(%23g)'%3E%3C/rect%3E%3C/svg%3E" x="0" y="0" width="100%" height="100%"></feImage>
<feDisplacementMap scale="20" xChannelSelector="R" yChannelSelector="R" in2="pict1" in="SourceGraphic">
</feDisplacementMap>
</filter>
<image filter="url(#f)" width="100%" xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG"></image>
</svg>

How to exclude shapes in svg or canvas?

Forgive my English
I am using svg with filters, but faced the following problem.
This is the base for svg. The result is expected:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<g>
<circle id="2" cx="50" cy="50" r="50"/>
<g id="1">
<rect x="0" y="0" width="50" height="50" fill="#ccc"/>
<rect x="50" y="50" width="50" height="50" fill="#ccc"/>
</g>
</g>
</svg>
But with the filter feComposite:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<defs>
<filter id="myFilter1">
<feImage href="#1" result="1"/>
<feImage href="#2" result="2"/>
<feComposite in="1" in2="2" operator="xor"/>
</filter>
</defs>
<g filter="url(#myFilter1)">
<circle id="2" cx="50" cy="50" r="50"/>
<g id="1">
<rect x="0" y="0" width="50" height="50" fill="#ccc"/>
<rect x="50" y="50" width="50" height="50" fill="#ccc"/>
</g>
</g>
</svg>
As you can see, the image is shifted. If you inspect the code, the blocks will not match the visible image:
Here with the addition of interactivity:
const value = (max = 100000000, min = 0) => Math.round(Math.random() * (max - min)) + min;
const createCircle = (size) => {
const r = value(10, 3);
const cx = value(size - r - 10, r + 10);
const cy = value(size - r - 10, r + 10);
return {
r,
cx,
cy
}
};
const createCircles = (counts, size) => Array(counts).fill().map(() => createCircle(size));
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
position: {
x: 0,
y: 0,
}
};
this.size = 300;
this.circlesData = createCircles(100, this.size);
const getCoords = (c, i) => c + (this.state.position.x * 0.002 * c * (i % 2 ? 1 : -1));
this.circles = () => this.circlesData.map((item, i) => <circle key = {`circles_12dew1_${i}`} cx={getCoords(item.cx, i)} cy={getCoords(item.cy, i)} r={item.r}/>);
}
onMouseMove = e => {
const position = {
x: e.pageX,
y: e.pageY,
};
this.setState({position});
}
render() {
return (
<div className = "App" >
<svg onMouseMove={this.onMouseMove} ref = {elem => this.svg = elem} xmlns = "http://www.w3.org/2000/svg" width = {this.size} height = {this.size} viewBox={`0 0 ${this.size} ${this.size}`}>
<defs>
<filter id="myFilter1">
<feImage href="#1" result="1"/>
<feImage href="#2" result="2"/>
<feComposite in ="1" in2="2" operator="xor"/>
</filter>
</defs>
<g id = "3" filter = "url(#myFilter1)" >
<circle id = "2" cx={this.size / 2 + 100} cy={this.size / 2 + 100} r={this.size / 3}/>
<g id="1"> {this.circles()} </g>
</g>
</svg>
</div>
);
}
}
ReactDOM.render( < App / > , document.getElementById('root'));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
As you can see, a big circle is moving, but it shouldn't be doing that.
How to fix?
Or how to make the exception of figures as in the interactive example without svg? For example using canvas, thank you!
The image placement behaviour you are seeing is because <feImage> elements are positioned using the filter region, or filter primitive region.
https://www.w3.org/TR/SVG11/single-page.html#filters-feImageElement
By default the filter region is an area that is 10% bigger than the original object on all sides.
x="-10%" y="-10%" width="120%" height="120%"
This is done to cater for filter primitives, such as <feGuassianBlur>, which extend outside the original size and would otherwise get clipped.
To get the images to position how you want, change the filter region, or filter primitive region, to be the same size as the original object. For example:
<feImage href="#1" x="0" y="0" width="100%" height="100%" result="1"/>
Updated demo:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<defs>
<filter id="myFilter1">
<feImage href="#1" x="0" y="0" width="100%" height="100%" result="1"/>
<feImage href="#2" x="0" y="0" width="100%" height="100%" result="2"/>
<feComposite in="1" in2="2" operator="xor"/>
</filter>
</defs>
<g filter="url(#myFilter1)">
<circle id="2" cx="50" cy="50" r="50"/>
<g id="1">
<rect x="0" y="0" width="50" height="50" fill="#ccc"/>
<rect x="50" y="50" width="50" height="50" fill="#ccc"/>
</g>
</g>
</svg>

Setting property of SVG elements from internal script

It's possible to set the property of the elements of SVG direcly from the script?
For example
<svg width="100px" height="100px" version="1.1" onload="setValues()" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
// <![CDATA[
function setValues() {
//Set cx || cy || whatever of circle
// Set property of rect
}
// ]]>
</script>
<circle id="circleId" cx="50" cy="50" r="45" fill="green" />
<rect id="rectId" height="40" width="400" y="0" x="170" style="fill:#ffffff" />
</svg>
Sure, setAttribute will do that.
<svg width="100px" height="100px" version="1.1" onload="setValues()" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
// <![CDATA[
function setValues() {
// Set property of circle
document.getElementById("circleId").setAttribute('cx', '20');
// Set property of rect
document.getElementById("rectId").setAttribute('x', '10');
document.getElementById("rectId").setAttribute('style', 'fill:red');
}
// ]]>
</script>
<circle id="circleId" cx="50" cy="50" r="45" fill="green" />
<rect id="rectId" height="40" width="400" y="0" x="170" style="fill:#ffffff" />
</svg>

Resources