I'm having problems with Webkit browsers (e.g., Chrome, Safari) and changing patterned fills in SVG objects. The example below tries to toggle the fill of a rectangle between a solid red and the google logo on hover:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="275" height="95">
<image xlink:href="http://www.google.com/intl/en_com/images/srpr/logo3w.png" x="0" y="0" width="275" height="95" />
</pattern>
</defs>
<rect id="rect" width="550" height="190" style="fill:url(#img1);stroke-width:1;stroke:rgb(0,0,0)">
<set attributeName="fill" from="url(#img1)" to="red" begin="mouseover" end="mouseout"/>
</rect>
</svg>
In Chrome/Safari, the rectangle correctly fills the rectangle with the google logo pattern on load. On mouse over, the rectangle fill switches to red. On mouse out, the fill appears as white rather than swapping back to the google logo.
Related
I am drawing a couple circles ontop of a zoomable image. I want the circles to be hole views so the holes highlight the image behind it. So I am using a mask to draw the rect to darken the image and then circles to highlight parts of the image. I group together the mask and the rectangle and do the transformation on the mask. When the image is not zoomed in, everything is perfect. When I zoom in and pan the image, the circles stay where they are supposed to, but the background rect does not translate from the transformations.
<Svg
height={imageDetails.HEIGHT}
width={imageDetails.WIDTH}
pointerEvents='none'>
<G transform={{
translateX: delta.x,
translateY: delta.y,
scale: delta.zoom
}} >
<Defs>
<Mask id={`clip`} >
<Rect fill="#fff" strokeWidth='5' stroke='white'
originX={delta.x * delta.zoom}
width={imageDetails.WIDTH * delta.zoom} height={imageDetails.HEIGHT} />
{data.map(item =>
<Circle r={item.size} cx={item.x} cy={item.y} key={item.key} fill='#000' />
)}
</Mask>
</Defs>
<Rect width={imageDetails.WIDTH} height={imageDetails.HEIGHT} clipRule={'evenodd'}
fillRule={'nonzero'} stroke='blue' strokeWidth='2' vectorEffect='inherit'
fill="rgba(0,0,0,.5)" fillOpacity='.7' mask={`url(#clip)`} />
</G>
</Svg>
I have played around with trying to transform the mask and the rect inside, but nothing.
Here are my screen shots show the full image, then zooming in, and the zooming in even more.
So my knowledge of SVG is limited, but I am learning. What I believe was happening was that the transformation was being applied to the everything, but the masked rect width and height are set to a value. Upon doing a scale, the width and height stay the exact same, so that is why it is being cut off. I had to change it so the transformation was being applied to the mask circles. So the mask rect will fill the whole screen always, and the circles will receive the transformation. Hopefully this helps anyone facing this issue.
<Svg
height={imageDetails.HEIGHT}
width={imageDetails.WIDTH}
pointerEvents='none'>
<G >
<Defs>
<Mask id={`clip`} >
<Rect fill="#fff" width='100%' height='100%' />
{data.map(item =>
<Circle
transform={{
translateX: delta.x,
translateY: delta.y,
scale: delta.zoom
}}
r={item.size} cx={item.x} cy={item.y} key={item.key} fill='#000' />
)}
</Mask>
</Defs>
<Rect width='100%' height='100%'
fill="rgba(0,0,0,.5)" fillOpacity='.7' mask={`url(#clip)`} />
</Svg>
I am trying yo create the slanting Image in svg with slanting text as shown in below Image
I have tried to create same format but not able to create exact design as display in overall text, you can also see that down horizontal is attached with below column.
Please find my below code
<svg width="100" height="100">
<rect x="10" y="10" width="80" height="30" style="fill:grey;" transform="rotate(30 20,40)" />
<style> .textColor { fill: white; } </style>
<text x="50" y="25" text-anchor="middle" font-size="12" class="textColor" stroke-width="0" dy=".3em" transform="rotate(30 20,40)">overall</text>
</svg>
please find below image created with this svg, where the red portion is there I also want grey color over there, Im short i want exact image as shown in upper image.
I need to do this in PDFMake, Copy this below code and paste on left section screen in PDFMake site, I need to display exact layout as display in 1st Image
var dd = {
content: [
{
style: 'tableExample',
table: {
body: [
['OverAll', 'Operational', 'Solvency'],
['1', '1', '1']
]
}
}
]
}
You may try to skew the rectangle. If you rotate the text and the rectangle 50 degs the skew angle should be -90+50 = -40. Please note that I've added a viewBox to the svg since by skewing and rotating the rect part of it was moved outside the svg elelent.
Probably the best solution to your problem (Robert Longson's comment) would be drawing a polygon in an svg editor instead of the rect.
svg{border:1px solid;}
<svg width="140" height="100" viewBox="-20 0 120 80">
<rect x="10" y="10" width="80" height="30" style="fill:grey;" transform="rotate(50 20,40) skewX(-40)" />
<style> .textColor { fill: white; } </style>
<text x="50" y="25" text-anchor="middle" dx="-10" font-size="12" class="textColor" stroke-width="0" transform="rotate(50 20,40)">overall</text>
</svg>
I want to create a home screen design where icons are vertically tilted (not a property stacked design). Also these navigational icons are connected by thick black connecting lines. I tried to use absolute positions but on different resolutions either icons are misaligned or those images are not reaching full screen edges. Can you please suggest how can we create such designs perfectly fit in all kind of resolutions?
You are gonna have a really fun time to do this in RN but it is possible. You can use the transform property in the style to apply a rotation.
Check here: https://facebook.github.io/react-native/docs/transforms#transform
I tried getting the screen size and positioning the each element using position absolute but it was still getting distorted in different mobiles.
If anyone still looking for an answer, I solved this using svg. (not sure if it is the best solution).
If you are not using expo then you need to use react-native-svg. It is already included in expo. Then you can create complex design as svg using sketch/adobe illustrator. Now edit svg image using any text editor and copy the code. "react-native-svg" supports most of the standard svg tags but there is slight difference (you can get that from documentation).
<Svg height={height} width={width} viewBox="150 90 650 806">
<G id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<G id="Group" transform="translate(1.000000, 0.000000)">
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(400.223611, 262.930718) rotate(-45.000000) translate(-400.223611, -262.930718) " x="440.723611" y="300.930718" width="41" height="46"></Rect>
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(481.794679, 552.516504) rotate(-45.000000) translate(-481.794679, -552.516504) " x="461.794679" y="525.516504" width="40" height="54"></Rect>
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(486.235804, 697.148232) rotate(45.000000) translate(-486.235804, -697.148232) " x="464.735804" y="671.648232" width="43" height="51"></Rect>
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(488.244426, 399.637825) rotate(45.000000) translate(-488.244426, -399.637825) " x="466.744426" y="366.637825" width="43" height="66"></Rect>
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(363.430718, 723.930718) rotate(-45.000000) translate(-363.430718, -723.930718) " x="343.430718" y="704.930718" width="40" height="38"></Rect>
<Rect id="Rectangle" stroke="#000000" fill="#000000" transform="translate(498.284271, 856.748737) rotate(-45.000000) translate(-498.284271, -856.748737) " x="475.784271" y="835.248737" width="45" height="43"></Rect>
</G></G></Svg>
This was some sample code for creating those connecting lines in the image. In svg you can easily create tilted graphics and fix their positions. It will automatically become responsive as per screen resolution.
I have noticed that when I use Apache Batik to transcode SVG documents to PDF's that have an opacity set to less than one Batik will create a raster version of the SVG and place it in the pdf instead. When dealing with print this is not desirable. Is there any reason Batik does this? Is there anyway to avoid this flattening of SVG documents regardless of their opacity?
Our code to create the transcoder:
PDFTranscoder pdfTranscoder = new PDFTranscoder();
pdfTranscoder.addTranscodingHint(PDFTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER, PIXEL_CONVERSION);
pdfTranscoder.addTranscodingHint(PDFTranscoder.KEY_AUTO_FONTS, false);
We then take the SVG which is returned form element.getEncodedData() as an SVG string.
TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(element.getEncodedData().getBytes()));
TranscoderOutput output = new TranscoderOutput(byteStream);
pdfTranscoder.transcode(input, output);
For opacity we edit the SVG adding a group. Consider the following svg: Note many markup tags have been removed to keep the example concise:
<svg>
<rect x="100" y="100" width="100" height="100" />
</svg>
We would edit this SVG to appear as
<svg>
<g opacity="0.5">
<rect x="100" y="100" width="100" height="100" />
</g>
</svg>
I have the following SVG:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="150" viewBox="0 0 800 150" xml:space="preserve">
<linearGradient id="SVGID_0" gradientUnits="userSpaceOnUse" x1="-400" y1="-150" x2="-400" y2="0">
<stop offset="0%" style="stop-color:rgb(255,64,64);stop-opacity: 1"/>
<stop offset="100%" style="stop-color:rgb(230,57,155);stop-opacity: 1"/>
</linearGradient>
<rect x="-400" y="-75" rx="0" ry="0" width="800" height="150" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: url(#SVGID_0); fill-rule: nonzero; opacity: 1;" transform="translate(400.5 75.5)"/>
</svg>
I am converting this to PDF using TCPDF:
$pdf->ImageSVG($file='images/testsvg.svg', $x=0, $y=0, $w='', $h='', $align='', $palign='', $border=0, $fitonpage=true);
As you can see from the image below, the gradient is applied wrongly.
Based on the illustrator image, it seems like TCPDF applies the center of the gradient to the bottom edge. If I manually move the center to the top edge then it looks very close to the original.
Any idea how I can fix this?
I think it's because of how the rect is positioned. It actually starts outside the viewbox and then both the gradient and the box get transformed. For example the box and the gradient x parameter are both -400. This is overly complex and I think some of the parameters are getting cancelled out by the $fitonpage=true parameter or the translations are being applied differently:
<rect x="-400" y="-75" rx="0" ry="0" width="800" height="150" style="... transform="translate(400.5 75.5)"/>
Based on the supplied examples there isn't really any point to this trickery. The only purpose appears to be modifying the gradient start and end colors. I would just move the rect to start at 0,0, remove the transforms, and then modify the gradient colors and stops to achieve the same effect the correct way:
<linearGradient y2="150" x2="0" y1="0" x1="0" gradientUnits="userSpaceOnUse" id="SVGID_0">
<stop
style="stop-color:#f13c73;stop-opacity:1"
id="stop4139"
offset="0" />
<stop
style="stop-color:#e6399b;stop-opacity:1"
id="stop4141"
offset="0.40" />
</linearGradient>
<rect
id="rect4143"
style="opacity:1;fill:url(#SVGID_0);fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
height="150"
width="800"
ry="0"
rx="0"
y="0"
x="0" />
The changes that matter are the removal of all the strange negative offsets on the rect and gradient and the change of the gradient stop colors and position to recreate the same gradient without the need to use cropping and transforms.