How to render a foreignObject SVG encoded with Base64 on browser - html

I have written the SVG code below. I want to encode it with Base64 and display it with data:image/svg+xml;base64,BASE64ENCODINGHERE. The issue is probably with foreignobject but I cannot see the text on the image. How can I solve this problem?
For this case the Base64 encoding is:
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj48c3R5bGU+ZGl2IHtmb250OiAxNHB4IHNlcmlmO2hlaWdodDoyMDBweDt3aWR0aDo0ODBweDttYXJnaW4tdG9wOjEwcHg7b3ZlcmZsb3c6IGF1dG87fS5iYXNlIHsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHg9IjAiIHk9IjAiIHJ4PSIxMCIgcnk9IjEwIiB3aWR0aD0iNTAwIiBoZWlnaHQ9IjI1MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOmJsYWNrO3N0cm9rZS13aWR0aDo1O2ZpbGwtb3BhY2l0eTowLjE7c3Ryb2tlLW9wYWNpdHk6MC45IiAvPjxmb3JlaWdub2JqZWN0IHg9IjgiIHk9IjgiIHdpZHRoPSI0OTAiIGhlaWdodD0iMjQwIj48dGV4dCB4PSIxMCIgeT0iMTYwIiBjbGFzcz0iYmFzZSI+Q2F0ZWdvcnk6eGF4YXhhPC90ZXh0PjxkaXYgPmhlYmVsZSBodWJlbGUgYnVtIGJhbSBidW08L2Rpdj48L2ZvcmVpZ25vYmplY3Q+PC9zdmc+
So, the link becomes:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj48c3R5bGU+ZGl2IHtmb250OiAxNHB4IHNlcmlmO2hlaWdodDoyMDBweDt3aWR0aDo0ODBweDttYXJnaW4tdG9wOjEwcHg7b3ZlcmZsb3c6IGF1dG87fS5iYXNlIHsgZm9udC1mYW1pbHk6IHNlcmlmOyBmb250LXNpemU6IDE0cHg7IH08L3N0eWxlPjxyZWN0IHg9IjAiIHk9IjAiIHJ4PSIxMCIgcnk9IjEwIiB3aWR0aD0iNTAwIiBoZWlnaHQ9IjI1MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOmJsYWNrO3N0cm9rZS13aWR0aDo1O2ZpbGwtb3BhY2l0eTowLjE7c3Ryb2tlLW9wYWNpdHk6MC45IiAvPjxmb3JlaWdub2JqZWN0IHg9IjgiIHk9IjgiIHdpZHRoPSI0OTAiIGhlaWdodD0iMjQwIj48dGV4dCB4PSIxMCIgeT0iMTYwIiBjbGFzcz0iYmFzZSI+Q2F0ZWdvcnk6eGF4YXhhPC90ZXh0PjxkaXYgPmhlYmVsZSBodWJlbGUgYnVtIGJhbSBidW08L2Rpdj48L2ZvcmVpZ25vYmplY3Q+PC9zdmc+
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 500 250">
<style>
div {
font: 14px serif;
height: 200px;
width: 480px;
margin-top: 10px;
overflow: auto;
}
.base {
font-family: serif;
font-size: 14px;
}
</style>
<rect x="0" y="0" rx="10" ry="10" width="500" height="250" style="fill:white;stroke:black;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
<foreignobject x="8" y="8" width="490" height="240">
<text x="10" y="160" class="base">Category:xaxaxa</text>
<div>hebele hubele bum bam bum</div>
</foreignobject>
</svg>
Expected output:
enter image description here
Result I got:
enter image description here

It's foreignObject with a capital O. SVG is case sensitive except when it's embedded in HTML.
You need to specify that the div lives in the XHTML namespace
There's no such thing as a text element in HTML so if you want to keep that, move it from the foreignObject contents. I've just removed it. That gives us this...
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 500 250">
<style>
div {
font: 14px serif;
height: 200px;
width: 480px;
margin-top: 10px;
overflow: auto;
}
.base {
font-family: serif;
font-size: 14px;
}
</style>
<rect x="0" y="0" rx="10" ry="10" width="500" height="250" style="fill:white;stroke:black;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
<foreignObject x="8" y="8" width="490" height="240">
<div xmlns="http://www.w3.org/1999/xhtml">hebele hubele bum bam bum</div>
</foreignObject>
</svg>
and if you base64 encode that you get
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCA1MDAgMjUwIj4KICA8c3R5bGU+CmRpdiB7CiAgZm9udDogMTRweCBzZXJpZjsKICBoZWlnaHQ6IDIwMHB4OwogIHdpZHRoOiA0ODBweDsKICBtYXJnaW4tdG9wOiAxMHB4OwogIG92ZXJmbG93OiBhdXRvOwp9CgouYmFzZSB7CiAgZm9udC1mYW1pbHk6IHNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKfQogIDwvc3R5bGU+CiAgPHJlY3QgeD0iMCIgeT0iMCIgcng9IjEwIiByeT0iMTAiIHdpZHRoPSI1MDAiIGhlaWdodD0iMjUwIiBzdHlsZT0iZmlsbDp3aGl0ZTtzdHJva2U6YmxhY2s7c3Ryb2tlLXdpZHRoOjU7ZmlsbC1vcGFjaXR5OjAuMTtzdHJva2Utb3BhY2l0eTowLjkiIC8+CiAgPGZvcmVpZ25PYmplY3QgeD0iOCIgeT0iOCIgd2lkdGg9IjQ5MCIgaGVpZ2h0PSIyNDAiPgo8ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj5oZWJlbGUgaHViZWxlIGJ1bSBiYW0gYnVtPC9kaXY+CiAgPC9mb3JlaWduT2JqZWN0Pgo8L3N2Zz4=

Related

SVG mask not loading initially in Chrome

Working on a project which is using a SVG mask on the homepage hero component but for some reason the text in the mask only shows when I resize the window. It's not showing on the initial page load. This is happening only in Chrome (latest version).
You can view the example on the STAGING environment here: https://staging.erwconstructions.com.au/
HTML Markup is:
<section data-component="mask-hero" class="in-view mask-hero">
<picture>
<img src="https://staging.erwconstructions.com.au/wp-content/uploads/2020/07/home-hero.jpg" alt="Home">
<svg width="100%" height="100%" viewBox="0 0 100% 100%">
<defs>
<linearGradient id="gradient">
<stop offset="100%" stop-color="black" />
</linearGradient>
<mask id="mask">
<rect width="100%" height="100%" fill="#fff" />
<text x="0" y="50%">
<tspan x="5vw" dy="-.1em">Building</tspan>
<tspan x="5vw" dy="1em">Redefined</tspan>
</text>
</mask>
</defs>
<rect width="100%" height="100%" fill="url(#gradient)" fill-opacity="0.9" mask="url(#mask)" />
</svg>
</picture>
</section>
The CSS is:
[data-component="mask-hero"] {
height: 100vh;
padding: 0;
background: none;
& picture {
display: block;
height: 100vh;
& img {
height: 100%;
object-fit: cover;
object-position: center;
position: fixed;
will-change: transform;
width: 100%;
z-index: -1;
}
& svg {
display: block;
height: 100%;
}
& text {
font-family: var(--defaultFont);
font-weight: var(--bold);
font-size: 3em;
#media (--app-breakpoint-2) {
font-size: 6em;
}
#media (--app-breakpoint-4) {
font-size: 8em;
}
#media (--app-breakpoint-5) {
font-size: 14em;
}
}
}
}
For some reason there is also a console error regarding the viewBox, even though the correct attributes are set on the SVG:
Error: <svg> attribute viewBox: Expected number, "0 0 100% 100%".
Any help would be greatly appreciated.
Thanks,
Dayne
By the given error, I'd guess to problem is with the viewBox. It should be given an absolute number in px, not percent. Like <svg viewBox="0 0 100 100">
Have you tried using javascript to make it work ?
This code below adds background color to white on rect inside svg code to show the text when the page has loaded.
var svgRect = document.querySelector('svg rect');document.addEventListener("DOMContentLoaded", function(){ setTimeout(function() { svgRect.style.backgroundColor = 'white'; }, 500); });

I want to implement SVG clip-path for SVG element

I want to implement SVG clip-path for SVG element. I have a DIV element in which I want to put SVG element which will act as a clipping mask, and also I have the separate SVG element that has an image to which the clipping mask will be applied.
The first problem I faced with is that clipping mask moves to the left top corner of the viewport but not located inside of the parent DIV element.
The second problem is that I want to make an image on the full screen not depending on the screen size.
Incorrect Mask Circle
Correct Mask Circle (what I want to have)
Do you have suggestions how to make it?
Thanks in advance!
html, body { margin:0; padding:0; overflow:hidden }
svg { position:absolute; top:0; left:0;}
.image-clip-src {
width: 100%;
height: 100%;
}
.svg-wrapper {
width: 72px;
height: 72px;
padding: 2.5em;
border: 1px solid #4D4F51;
margin: 0 auto;
border-radius: 50%;
overflow: hidden;
position: fixed;
top: 55%;
z-index: 9;
left: 64%;
transform: translateY(-50%);
cursor: pointer;
}
.clipped-image image {
clip-path: url(#clipping);
}
<svg class="clipped-image" width="100%" height="100%" viewBox="0 0 1440 960" preserveAspectRatio="xMinYMin meet">
<image class="image-clip-src" xlink:href="https://images.unsplash.com/photo-1526327227970-4bda49fa3489?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3c4bce33d96df6b18af53fb2dae3363e&auto=format&fit=crop&w=1650&q=80" width="100%" height="100%" overflow="visible"/>
</svg>
<div class="svg-wrapper">
<svg class="svg-defs">
<defs>
<clipPath id="clipping">
<circle r="72" stroke="black" stroke-width="3"/>
</clipPath>
</defs>
</svg>
</div>
That's not the way SVG works.
When you tell something to use a clip path, all it sees is the clip path definition itself. It doesn't know or care about where on the page you have positioned it's parent <svg>.
If you want the clip circle to be at a certain position on the water image, you need to specify its position using cx and cy.
html, body { margin:0; padding:0; overflow:hidden }
svg { position:absolute; top:0; left:0;}
.image-clip-src {
width: 100%;
height: 100%;
}
.clipped-image image {
clip-path: url(#clipping);
}
<svg class="clipped-image" width="100%" height="100%" viewBox="0 0 1440 960" preserveAspectRatio="xMinYMin meet">
<defs>
<clipPath id="clipping">
<circle cx="64%" cy="55%" r="72" stroke="black" stroke-width="3"/>
</clipPath>
</defs>
<image class="image-clip-src" xlink:href="https://images.unsplash.com/photo-1526327227970-4bda49fa3489?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3c4bce33d96df6b18af53fb2dae3363e&auto=format&fit=crop&w=1650&q=80" width="100%" height="100%" overflow="visible"/>
<circle cx="64%" cy="55%" r="72" fill="none" stroke="#4D4F51" stroke-width="1"/>
</svg>

chrome does not identify svg image perfectly

xyz.html
<div class="r-view-products">
<span>KNOW MORE</span>
<img class="r-arrow-image" src="image/test.svg" alt="image">
</div>
xyz.scss
.r-view-products {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 1rem;
font-size: 18px;
.r-arrow-image {
width: 40px;
height: 21px;
transform: rotate(180deg);
}
}
On edge , i get perfect image like
But on chrome it shows like
The code for my svg file is as shown below:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="9.097" height="18.878" style="enable-background:new 0 0 9.097 18.878;" xml:space="preserve"><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none"/>
<g class="currentLayer" style=""><title>Layer 1</title><g id="svg_1" class="selected" fill="#ffffff" fill-opacity="1">
<path style="" d="M7.74,0c0.295,0,0.592,0.095,0.841,0.292C9.168,0.757,9.27,1.61,8.804,2.199l-5.717,7.24l5.717,7.24 c0.466,0.589,0.364,1.442-0.223,1.907c-0.59,0.464-1.443,0.364-1.907-0.224l-6.381-8.082c-0.391-0.494-0.391-1.189,0-1.683 l6.381-8.082C6.941,0.177,7.339,0,7.74,0z" id="svg_2" fill="#ffffff" fill-opacity="1"/>
</g></g></svg>
Is there anything missing in my scss/html file because of which chrome does not identify image perfectly?

Solution: How to make a transparent Text over Image

Solution : Gives CSS - Transparent Fonts. Any Letters you Want. It's from : http://lea.verou.me/2012/05/text-masking-the-standards-way/ which some editing.
/**
* Text masking — The SVG way
*/
svg {
width: 7em; height: 3em;
font: 900 500%/1.2 'Arial Black', sans-serif;
}
text { fill: url(#wood); }
<svg>
<defs>
<pattern id="wood" patternUnits="userSpaceOnUse" width="240" height="300" >
<image xlink:href="http://hd.wallpaperswide.com/thumbs/girl_beach_background-t2.jpg" width="400" height="400" />
</pattern>
</defs>
<text y="2em">Nice Beach</text><text y="3em">Isnt't It</text>
</svg>
Code: Just change the < text.. >Change this< /text > to other words.
HTML
<svg>
<defs>
<pattern id="wood" patternUnits="userSpaceOnUse" width="240" height="300" >
<image xlink:href="http://hd.wallpaperswide.com/thumbs/girl_beach_background-t2.jpg" width="400" height="400" />
</pattern>
</defs>
<text y="2em">Nice Beach</text><text y="3em">Isnt't It</text>
</svg>
CSS:
/**
* Text masking — The SVG way
*/
svg {
width: 7em; height: 3em;
font: 900 500%/1.2 'Arial Black', sans-serif;
}
text { fill: url(#wood); }
With css. It's easy:
div {
opacity: 0.5;
}
div p {
opacity: 1.0;
}
Just change div and p for whatever you need.
/**
* Text masking — The SVG way
*/
svg {
width: 7em; height: 3em;
font: 900 500%/1.2 'Arial Black', sans-serif;
}
text { fill: url(#wood); }
<svg>
<defs>
<pattern id="wood" patternUnits="userSpaceOnUse" width="240" height="300" >
<image xlink:href="http://hd.wallpaperswide.com/thumbs/girl_beach_background-t2.jpg" width="400" height="400" />
</pattern>
</defs>
<text y="2em">Nice Beach</text><text y="3em">Isnt't It</text>
</svg>
Run code snippet

Change font height and width

I want to change not the font-size of text, but two independent properties relative to its width and height.
So, by applying font-width: 50% to this element:
the text would be stretched to half:
Is this possible to do using CSS?
CSS transform has the scale function for this:
p {
display: inline-block;
font-size: 32px;
transform: scale(.5, 1);
}
<p>This is text.</p>
Use the two numbers in the function for X- and Y-axis respectively.
You can try scaling the font in x direction.
p{
-webkit-transform: scaleX(0.5);
transform: scaleX(0.5);
}
The closest thing I can find is font-weight
It accepts not only bold,normal but also numeric values. 100-900 in 100 increments.
. Paragraph {font-weight :700;}
This combined with height properties should help but will not give you complete solution
Also look at spacing properties as you can reduce the the width of the words that way
letter-spacing: 2px;
Using a svg text with preserveAspectRatio="none" allow text deformations and very precise positioning.
To adjust, It's all about the viewBox. The rendering stays natively responsive to browser resizes.
The text stays select able.
.title {
width: 540px;
height: 40px
}
.content {
width: 300px;
height: 400px
}
.side {
width: 270px;
height: 100px;
color: red;
position: absolute;
right: 30px;
top: 160px;
transform: rotate(44deg)
}
<div class="title">
<svg preserveAspectRatio="none" x="0" y="30" viewBox="0 0 100 15" width="100%" height="100%">
<foreignObject x="5" y="1" height="100%" width="100%">
<div>
Hello world!
</div>
</foreignObject>
</svg>
</div>
<div class="content">
<svg preserveAspectRatio="none" x="0" y="30" viewBox="0 0 400 200" width="100%" height="100%">
<foreignObject x="55" y="15" height="100%" width="80%">
<div>
The best way to use a hello cheer for introducing players is to have one cheerleader use a megaphone or loudspeaker to announce the players names and stats.
</div>
</foreignObject>
</svg>
</div>
<div class="side">
<svg preserveAspectRatio="none" x="0" y="30" viewBox="0 0 100 100" width="100%" height="100%">
<foreignObject x="5" y="15" height="200%" width="100%">
<div>
NOW WITH COLORS!
</div>
</foreignObject>
</svg>
</div>
Tip: For complex stuffs, flyers making, using the cm css unit works very well.