Flip all embedded Images in a SVG file - image

I have an SVG file which contains about 50 embedded images. Now I wish to flip all the images vertically. The only way i found that does this is:
Copy the xlink:href to a browser and download the image
Flip the image in any image editor
Convert the image to a href code
Replace the xlink:href with the one newly generated
I don't want to use any SVG programs please, I hope for a coding help
Example code
<svg contentScriptType="text/ecmascript" zoomAndPan="magnify" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" baseProfile="full"
contentStyleType="text/css" id="svg2" version="1.1" width="460pt" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#" preserveAspectRatio="xMidYMid meet" viewBox="0 0 460 130" height="130pt"
xmlns="http://www.w3.org/2000/svg">
<image x="0" y="0" width="460" xlink:href= "data:image/png;base64,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"
id="image6418" height="130"/>

Add transform="scale(1, -1)" to the images. You may need to translate them back if they aren't centred round the origin. So in the case above you want to add this to the image element:
transform="translate(0, 130) scale(1, -1)"

Related

svg tspans within textPath drawing differently across browsers

I'm using a textPath and tspans to fit text into a svg path, and it works great in Chrome, but not so much in Edge and FF (o. Any help would be greatly appreciated
Here's a jsfiddle the svg node:
https://jsfiddle.net/ych9dr59/
And here's the relevant text code:
<text text-anchor="middle" font-size="8pt" font-family="Calibri" pointer-events="none">
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="-14pt">12): Maintain a</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">policy that</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">addresses</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">information security</tspan>
</textPath>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#text_5_4_5_1590" startOffset="50%">
<tspan dy="8pt">for all personnel. </tspan>
</textPath>
</text>
SVG text element is pretty buggy in general in my experience. My recommendation for maximum cross-browser sanity would be to use a separate text element for each text fragment and use normal x/y positioning and a transform/rotate to render your text.
Firefox is actually rendering correctly. According to the 1.1 spec, the start of each new textPath should be an absolute reset of the current text position. You should manually adjust the dy offsets of the tspans so they're cumulative (instead of 8pt in ever one, it should be 8pt, 16pt, 24pt). So it's actually a Chrome bug that your stuff works in the first place.
Edge only seems to support a single textPath element per text element, so you do need to wrap each textPath in its own text element.

GSAP / TimelineMax SVG Animation of 3D Bar (3 polygons)

I've created a 3D bar in illustrator (see codepen). Now I want to animate it with TweenMax (or TimelineMax) as if it's building up from the bottom to the top.
This is the end result what I need to create:
http://postimg.org/image/pg2drnvch/
I tried a couple of things to make this happen, but without any luck.
Created a clipping-path and then try to change the Y coordinate of the 3 polygons (or wrapped them in a < g >< /g >)
Tried to animate the points of the polygon (http://greensock.com...ing-attrplugin/)
I hope someone can help me with this.
Codepen URL: http://codepen.io/boldcolin/pen/rOPPgP
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="bar_1_" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="140.5px" height="366.7px" viewBox="0 0 140.5 366.7" style="enable-background:new 0 0 140.5 366.7;" xml:space="preserve"
>
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);fill:#8BBE3F;}
.st1{clip-path:url(#SVGID_2_);fill:#81A83F;}
.st2{clip-path:url(#SVGID_2_);fill:#A1C63C;}
</style>
<g>
<defs>
<polygon id="SVGID_1_" points="80.3,0 0,40.1 0,336.7 60.2,366.7 140.5,327.1 140.5,30.7 "/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<polygon class="st0" points="140.7,169.4 0.2,178.9 0.2,350.2 60.4,380.1 140.7,340.6 "/>
<polyline class="st1" points="60.4,380.1 60.4,205.9 0.2,178.9 0.2,350.2 "/>
<polygon class="st2" points="0.2,178.9 80.5,138.7 140.7,169.4 60.4,209 "/>
</g>
This is an example: http://boldinteractive.nl/raet/bar/
Here I used a white layer on top of the bar which acts like a faux mask. But this is not how I want to make this work..
It's seems impossible to mask a polygon with a polygon and then animate the shape. I'm now using a path (in Illustrator use 'make compound path') and then use this as clipping mask.

How do I control the opacity of image mask output created from two images, in SVG?

How do I retain the opacity of an image when creating an image mask using two images in SVG?
As seen in the picture below, the image is nearly transparent - it should be completely opaque. Why is this happening, and how can I force the masked product to have 100% opacity?
Here is the result I am getting:
Here is the mask image I am using:
Here is my code (sorry about the PHP variables):
<svg width="'.$width.'" height="'.$height.'" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="mask'.$id.'" maskUnits="userSpaceOnUse"
x="0" y="0" width="'.$width.'" height="'.$height.'">
<image id="maskImg'.$id.'" x="0" y="0" width="'.$width.'px" height="'.$height.'px"
xlink:href="images/'.$treatment_url.'" >
</image>
</mask>
<g id="imgGroup'.$id.'">
<rect x="0" y="0" width="'.$width.'" height="'.$height.'" fill="rgba(30,30,30,0.2)" />
<image id="listingImg'.$id.'"
x="0" y="0" width="'.$width.'px" height="'.$height.'px"
xlink:href="'. $img_url .'">
</image>
</g>
</defs>
<use xlink:href="#imgGroup'.$id.'" mask="url(#mask'.$id.')" opacity="1" />';
</svg>
FYI: the <rect> in the <g> group is just to provide a background when the MASKED image is smaller in the x or y dimension than the MASKING image; it does not affect the masking problem I'm having, as I've tried it both ways.
I'm stumped, and appreciate any help!
SVG 1.1 uses luminance masks. A simple and somewhat inaccurate explanation is: White in the mask image gives fully opaque, black gives fully transparent. Some more explanations here. Some more advanced examples of masks with images, see here.
Alpha masks have been proposed and accepted as a requirement for SVG2.

How can I make text orbit along a circular path using HTML5 Canvas?

There are a number of JavaScript snippets that will make text or graphics travel along a circular path with the letters or words always upright.
Example: http://www.dseffects.com/f_scripts.html
I want to have text (or graphics) orbit a point the way the moon orbits the Earth, with one face always toward the center. The following example shows this, but very crudely and not using web fonts.
Example: http://javaboutique.internet.com/text/Manipulation/TextRotor/
I am sure there is a way to modify orbiting code like the first example (only not around the cursor) so that each letter/image keeps one side toward the center (axis).
SVG really is the way to go for this kind of thing. I just whipped this up really quick but at least it works as an example. The HTML part can vary a lot but this is one way.
Put this into an html page:
<iframe src="orbitingText.svg" width="100%" height="100%"></iframe>
Then, create the orbitingText.svg file (it's just a text file with a .svg extension):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 300 300">
<defs>
<path id="textPath" d="M 150 75 a 75 75 0 1 0 0.00001 0"/>
</defs>
<circle cx="150" cy="150" r="40" stroke="blue" stroke-width="1"></circle>
<text fill="red">
<textPath xlink:href="#textPath" startOffset="0">
<animate attributeName="startOffset" dur="7s" from="0" to="500" repeatCount="indefinite" />
Orbiting Text
</textPath>
</text>
Oh, and if you are worried about cross-browser compatibility, check out this site:
http://code.google.com/p/svgweb/

Calculate path center after transformation matrices have been applied

I made a logo in Inkscape. For learning I wanted to make a wheel shape in the logo rotate by the animation support in SVG.
It was easy to implement the rotation, but it was difficult for me to be able to specify the correct axis of rotation. The shape was a cog wheel and I wanted it to rotate around its center. Trial and error gave that the xy-coordinate (47.1275, 1004.17) (whose components are strangely asymmetric, but I guess that has to do with the transformation matrices Inkscape applies) was a good approximation (see animateTransform tag below), but how would I get that from first principles?
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 321.281 150.799" xmlns:dc="http://purl.org/dc/elements/1.1/">
<g transform="translate(-9.9178912,-891.57237)">
<g transform="matrix(1.9522781,0,0,1.9522781,4.6434311,-1008.1558)">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 47.1275 1004.17" to="45 47.1275 1004.17" dur="2s" fill="freeze" additive="sum" repeatCount="indefinite" />
<g transform="matrix(0.65043772,0,0,0.65043772,-143.67477,980.4256)" stroke="#666" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="7.68713093" fill="none">
<path stroke-linejoin="miter" d="m293.404-3.51576c-2.73916,0-5.41514,0.287192-8,0.8125v6.1875c-3.47484,0.838872-6.7198,2.18462-9.6875,4l-4.375-4.375c-2.24264,1.48612-4.29226,3.22977-6.1875,5.125s-3.63888,3.94486-5.125,6.1875l4.375,4.375c-1.81538,2.9677-3.16112,6.21265-4,9.6875h-6.1875c-0.5253,2.58486-0.8125,5.26083-0.8125,8s0.2872,5.41515,0.8125,8h6.1875c0.83888,3.47485,2.18462,6.7198,4,9.6875l-4.375,4.375c1.48612,2.24264,3.22976,4.29227,5.125,6.1875s3.94486,3.63888,6.1875,5.125l4.375-4.375c2.9677,1.81538,6.21266,3.16113,9.6875,4v6.1875c2.58486,0.525308,5.26082,0.8125,8,0.8125,2.73916,0,5.41514-0.287192,8-0.8125v-6.1875c3.47484-0.838872,6.7198-2.18462,9.6875-4l4.375,4.375c2.24264-1.48612,4.29226-3.22977,6.1875-5.125s3.63888-3.94486,5.125-6.1875l-4.375-4.375c1.81538-2.9677,3.16112-6.21266,4-9.6875h6.1875c0.5253-2.58485,0.8125-5.26083,0.8125-8s-0.2872-5.41515-0.8125-8h-6.1875c-0.83888-3.47485-2.18462-6.7198-4-9.6875l4.375-4.375c-1.48612-2.24264-3.22976-4.29227-5.125-6.1875s-3.94486-3.63888-6.1875-5.125l-4.375,4.375c-2.9677-1.81538-6.21266-3.16113-9.6875-4v-6.1875c-2.58486-0.525308-5.26084-0.8125-8-0.8125z" stroke-dashoffset="162" stroke="#666" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="7.68713093" fill="none"/>
</g>
</g>
</g>
</svg>
From what I've read in the specification I would say the transformation matrices applied are
1.9522781 0 4.6434311
0 1.9522781 -1008.1558
0 0 1
and
0.65043772 0 -143.67477
0 0.65043772 980.4256
0 0 1
Are they applied on the xyz-coordinate (-9.9178912,-891.57237,0) after the translation transformation?
I guess a correct analysis above would get me the top left point of the path described, or maybe the coordinate for the first handle. After that, does one have to parse the path to decide the bounding-box and thereby the center (since it concerns a somewhat circular object) of the path?
Is it all a lesson in not trying to manually do animation on freely created shapes?
I think the transformations will be applied from the innermost outward, so transform="translate(-9.9178912,-891.57237)" will be done last. But you can ignore the other transformations if you put your animation in the innermost region, i.e. within the path itself:
<g transform1>
<g transform2>
<g transform3>
<path d="coordinates">
<animateTransform your transformation here>
</path>
</g>
</g>
</g>
Then you just need to find the centre of your path, which is easy to do in Inkscape, but tricky to do on-the-fly (related question here: programmatically How to get shape width in SVG document using java).
Personally, I'd use a script within the svg so you can use getBBox to find the bounding box of your shape. If you add the following element into your SVG you can make any element with the id="cog" turn about its centre:
<script type="text/ecmascript"><![CDATA[
var svgNS = "http://www.w3.org/2000/svg";
function init(evt)
{
if ( window.svgDocument == null )
{
svgDocument = evt.target.ownerDocument;
}
addRotateTransform('cog');
}
function addRotateTransform(target_id)
{
var element_to_rotate = svgDocument.getElementById(target_id);
var my_transform = svgDocument.createElementNS(svgNS, "animateTransform");
var bb = element_to_rotate.getBBox();
var cx = bb.x + bb.width/2;
var cy = bb.y + bb.height/2;
my_transform.setAttributeNS(null, "attributeName", "transform");
my_transform.setAttributeNS(null, "attributeType", "XML");
my_transform.setAttributeNS(null, "type", "rotate");
my_transform.setAttributeNS(null, "dur", "4s");
my_transform.setAttributeNS(null, "repeatCount", "indefinite");
my_transform.setAttributeNS(null, "from", "0 "+cx+" "+cy);
my_transform.setAttributeNS(null, "to", "360 "+cx+" "+cy);
element_to_rotate.appendChild(my_transform);
my_transform.beginElement();
}
]]></script>
You also need to add onload="init(evt)" as an attribute to the SVG tag. e.g.
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 321.281 150.799"
xmlns:dc="http://purl.org/dc/elements/1.1/"
onload="init(evt)">
This will call the init() function when the SVG is first loaded. The init() function calls addRotateTransform() which find the element with a given id. It then finds the centre of that object using getBBox() and adds an animateTransform method with the relevant centres. You can change the dur attribute which determines the speed of a full rotation.
It might seem like a lot of code, but I think it's the easiest way to determine the centre of a path. It also means to can easily add other rotating elements by add addRotateTransform('whatever-id'); to the init() function.

Resources