I would like to animate an svg element and let it scale(2). This works fine but the problem is that my element has an 'x' and 'y' value. Because of this the scale moves the element to a different position.
But I would like to scale it without moving it to a different position. The 'x' and 'y' values are defined somewhere else and I don't would like to "hardcode" the values in my css.
And I don't want to use JS it shoudl be plane css if possible.
Code:
.hello {
transition: 1s;
height: 100px;
width: 100px;
margin: 100px;
background-color: red;
transform-origin: center center;
position:relative;
}
.hello:hover {
transform: scale(4);
}
<use
id="=test"
xlink:href="#but"
x="100" y="20"
width="100%"
height="100%"
class="hello">
<title
id="title31">
I am an example toolTip
</title>
</use>
A code example can be found here:
https://jsfiddle.net/6agd23cL/3/
remove the x and y attributes and increase the translate on the parent <g> element to compensate.
.hello {
transition: 1s;
height: 100px;
width: 100px;
margin: 100px;
background-color: red;
transform-origin: center center;
position:relative;
}
.hello:hover {
transform: scale(4);
}
<div id="container" style="width: 100%; height: 100%">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
id="target"
width="3600"
height="4100"
style="top:0;left:0;"
version="1.1">
<defs
id="styles">
<g
id="but">
<style
id="style11">
.cls-1{fill:#ffc60b;}.cls-2{stroke:#231f20;stroke-width:0.5px;}.cls-3{fill:#fff;opacity:0.1;}
</style>
<rect
id="Frame"
width="12"
height="12"
x="0.25"
y="0.25"
class="cls-1"
rx="2"
ry="2" />
<circle
id="circle14"
cx="6.25"
cy="6.25"
r="4.5"
class="cls-2" />
<circle
id="Highlight"
cx="6.25"
cy="6.25"
r="3"
class="cls-3" />
</g>
</defs>
<g
id="view"
transform="translate(114.386917,29.7722462)">
<use
id="=test"
xlink:href="#but"
width="100%"
height="100%"
class="hello">
<title
id="title31">
I am an example toolTip
</title>
</use>
</g>
</svg>
</div>
</html>
Related
How can i "crop" the svg filter to fit the shape of the parent?
Right now I have a div as a circle, with an svg in it. But the svg filter creates an rectangel.
Edit: I tried to implement a wrapping div with border-radius:100% as suggested below, but then it removes the blur.
original codepen
updated codepen with wrapping div
svg{
width:100%;
height: 100%;
}
.custom-cursor {
border-radius: 50%;
overflow: hidden;
width: 20px;
height: 20px;
background-image: conic-gradient( cyan, magenta, yellow, cyan);
filter: blur(5px) url("#blur-plus-grain");
}
<div class="custom-cursor">
<svg preserveAspectRatio="none">
<filter id="blur-plus-grain">
<feGaussianBlur stdDeviation="0.8" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
<circle fill="transparent" r="10" cx="50%" cy="50%" filter="url(#blur-plus-grain)" />
</svg>
</div>
You apply the svg noise-blur filter to your round gradient-filled div.
But there is still a css box context.
You actually need some padding to provide enough 'canvas' area.
Otherwise any kind of blur might exceed for div elements boundaries:
* {
box-sizing: border-box;
}
svg {
width: 100%;
height: 100%;
}
.custom-cursor-clip {
width: 50px;
height: 50px;
padding:2%;
filter: url("#blur-plus-grain");
}
.custom-cursor {
width: 100%;
height: 100%;
border-radius: 100%;
background-image: conic-gradient(from 20deg, #003399, #74b4da, #e0bbd9);
}
<div class="custom-cursor-clip">
<div class="custom-cursor">
<svg preserveAspectRatio="none">
<filter id="blur-plus-grain">
<feGaussianBlur stdDeviation="4" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
</svg>
</div>
</div>
Edit:
Essentially you apply the conic gradient to the inner div.
The wrapping/outer div provides some padding as well as the svg-filter.
Edit 2:
You might also use the <foreignObject> element for a more self-contained svg img asset:
<svg width="50" height="50" viewBox="0 0 100 100">
<style>
.conicGradient{
width: 100%;
height: 100%;
border-radius: 100%;
background-image: conic-gradient(from 20deg, #003399, #74b4da, #e0bbd9);
}
</style>
<filter id="blur-plus-grain" filterUnits="userSpaceOnUse" >
<feGaussianBlur stdDeviation="4" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
<foreignObject filter="url(#blur-plus-grain)"
x="10" y="10" width="80" height="80">
<div class="conicGradient" xmlns="http://www.w3.org/1999/xhtml" ></div>
</foreignObject>
</svg>
However, you still need some sort of padding/inner offset to prevent undesired cropping.
From this website
https://smooth.ie/blogs/news/svg-wavey-transitions-between-sections
i generated the following svg
<div style="height: 100%; overflow: hidden;" class='parent' ><svg viewBox="0 0 500 150" preserveAspectRatio="none" style="height: 100%; width: 100%;"><path d="M213.19,0.00 C152.69,70.06 270.03,70.06 202.98,150.00 L500.00,150.00 L500.00,0.00 Z" style="stroke: none; fill: #08f;"></path></svg></div>
the problem is that when i try to add background image for example here on the parent class
.parent {
background-image: url('../../../assets/images/calendar.png');
}
then the image is hidden behind the blue color of the svg.How can i 'insert' this image to be on the blue svg color image ?
As name says - it's "background-image" so it always is on the background of selected element.
I suggest that you should make an <img> tag in parent element and style it so that .parent would have attribute position: relative and img should have position: absolute.
Also remember to set top and left/right position for <img>.
it's Answered here https://stackoverflow.com/a/3798797/9017484
You can do it by making the background into a pattern:
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image href="wall.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
your code should be something like this:
<div style="height: 100%; overflow: hidden;" class='parent' >
<svg viewBox="0 0 500 150" preserveAspectRatio="none" style="height: 100%; width: 100%;">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image href="ImageFile.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
<path d="M213.19,0.00 C152.69,70.06 270.03,70.06 202.98,150.00 L500.00,150.00 L500.00,0.00 Z" style="stroke: none; fill: url(#img1);"></path>
</svg>
</div>
change the opacity level so the color is lower opacity. something like this perhaps.
background {
backgroundColor:blue,
opacity: 0.5;
}
How do I make an image shrink to fit inside a fixed position flex box modal?
When trying the below the image overlaps the header/footer. It needs to work for images both tall, or wide, and in IE.
.modal-dialog {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.modal-content {
display: flex;
flex-direction: column;
height: 100%;
}
.modal-header {
background: red;
margin: 20px;
}
.modal-body {
background: green;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0 20px;
}
.modal-footer {
background: blue;
margin: 20px;
}
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
header
</div>
<div class="modal-body">
<img src="https://via.placeholder.com/900x1200" />
</div>
<div class="modal-footer">
footer
</div>
</div>
</div>
</div>
Note this is a simple example, and I am really using a complicated SVG, not an image tag, so I can't use a background image.
You can use good old position: absolute with max-width and max-height:
/* for demonstration I have replaced all irrelavant styles with this */
.modal-body {
width: 80vw;
height: 60vh;
margin: 10% auto 0;
background: green;
}
/* parent must be positioned */
.modal-body {
position: relative;
}
/* size and center */
.modal-body img {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
max-width: 100%;
max-height: 100%;
margin: auto;
}
<div class="modal-body">
<img src="https://via.placeholder.com/900x1200" />
</div>
Just a reminder but by default images try to maintain their aspect ratios, so simply setting a percentage width will allow an inlined image to grow to the proper height OR setting only the height to a percentage will maintain the width.
The key is to only set ONE dimension and let the browser figure out the rest.
This is especially true if you set the sizes Inline using the appropriate HTML structure.
<div class="modal-body">
<img src="https://via.placeholder.com/900x1200" width="100%" />
</div>
Now you just set the max-width of the container with CSS and everything is happy. That should be true of any use of the img tag. Meaning if you use an SVG in the img src attribute you'll get it to function like an image. That said, I believe you lose SVG interactions if you do it that way.
So assuming you're going to actually drop the SVG into your code, you need to do a bit of work to the SVG.
Note how most SVG's have hard-coded heights and widths in the header Simply removing the hard-coded height/width "should" make the SVG scale correctly since the view-box keeps the proportions of the image.
<svg width="299px" height="138px" viewBox="0 0 299 138" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="example">
<rect id="Rectangle" fill="#D8D8D8" x="0" y="0" width="299" height="138"></rect>
<circle id="Oval" fill="#46BEC6" cx="53" cy="50" r="26"></circle>
<circle id="Oval-Copy" fill="#46BEC6" cx="105" cy="76" r="26"></circle>
<circle id="Oval-Copy-2" fill="#46BEC6" cx="165" cy="95" r="26"></circle>
<circle id="Oval-Copy-3" fill="#46BEC6" cx="217" cy="63" r="26"></circle>
<circle id="Oval-Copy-4" fill="#46BEC6" cx="269" cy="32" r="26"></circle>
</g>
</g>
</svg>
<svg viewBox="0 0 299 138" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="example">
<rect id="Rectangle" fill="#D8D8D8" x="0" y="0" width="299" height="138"></rect>
<circle id="Oval" fill="#46BEC6" cx="53" cy="50" r="26"></circle>
<circle id="Oval-Copy" fill="#46BEC6" cx="105" cy="76" r="26"></circle>
<circle id="Oval-Copy-2" fill="#46BEC6" cx="165" cy="95" r="26"></circle>
<circle id="Oval-Copy-3" fill="#46BEC6" cx="217" cy="63" r="26"></circle>
<circle id="Oval-Copy-4" fill="#46BEC6" cx="269" cy="32" r="26"></circle>
</g>
</g>
</svg>
If you don't know which one needs to be set (like in the case of a dynamic image) you'll need to measure it with javascript before applying the correct measurement. Something along these lines:
fixImage(){
var img = findTheImageInTheDom;
if (img.width > img.height){
img.width = "100%";
} else {
img.height = "100%";
}
Is there a way to apply a colour overlay to an SVG using CSS?
I have some SVGs (icons, shapes etc) that I need to be able to "tint" - adding a solid colour overlay but keep the transparency.
I read about the CSS filters, but none of them cater for adding a colour over the top, only stuff like blur or desaturate.
Please check this code snippet. I hope it will be help you.
<svg width="0" height="0" class="svg-visiblity">
<defs>
<path id="hex" d="M11.5,20.9L44.3,2c3.7-2.2,8.3-2.2,12.1,0l32.8,18.9c3.7,2.2,6,6.1,6,10.4v37.8c0,4.3-2.3,8.3-6,10.4 L56.3,98.4c-3.7,2.2-8.3,2.2-12.1,0L11.5,79.5c-3.7-2.2-6-6.1-6-10.4V31.3C5.4,27,7.7,23,11.5,20.9z"/>
<clipPath id="hex-clip-200">
<use xlink:href="#hex" transform="scale(2 2)" />
</clipPath>
</defs>
</svg>
<svg class="image-200-2">
<rect class="border" width="100%" height="100%" transform="scale(1.02)" style="clip-path: url(#hex-clip-200);" /></rect>
<image xlink:href="http://placehold.it/200x200" width="200" height="200" transform="translate(2 2)" style="clip-path: url(#hex-clip-200);"></image>
</svg>
CSS
.image-200-2 {
display: inline-block;
height: 205px;
width: 205px;
}
.image-200-2 .border {
fill: rgba(0, 0, 0, 0.5);
}
.svg-visiblity {
height: 0;
opacity: 0;
position: absolute;
width: 0;
}
See here: https://jsfiddle.net/zyr8wovg/4/
This is a real css-challenge, I don't think this is possible:
I've made some white css triangles. and when you hover on a triangle, the white triangle should change in a photo also cropped like a triangle. I've made a jsfiddle for it:
fiddleLink
Any help appreciated
You can use svg to achieve this effect: http://jsfiddle.net/xTd6Y/4/
<div id="image-wrapper">
<svg id="svg-1" class="clip-svg">
<rect class='svg-background' width="300" height="300" fill="#ffffff" />
<image id="img-1" class='svg-image' width="300" height="300" xlink:href="http://lorempixel.com/300/300" />
</svg>
<svg id="svg-2" class="clip-svg">
<rect class='svg-background' width="300" height="300" fill="#ffffff" />
<image id="img-2" class='svg-image' width="300" height="300" xlink:href="http://lorempixel.com/300/301" />
</svg>
<svg id="svg-3" class="clip-svg">
<rect class='svg-background' width="300" height="300" fill="#ffffff" />
<image id="img-3" class='svg-image' width="300" height="300" xlink:href="http://lorempixel.com/300/302" />
</svg>
</div>
<svg id="svg-defs">
<defs>
<clipPath id="clip-triangle">
<polygon points="0, 200 100, 0 200, 200"/>
</clipPath>
</defs>
</svg>
css
body {
background-color: #e0e0e0;
}
#image-wrapper {
position: relative;
}
.svg-background, .svg-image {
clip-path: url(#clip-triangle);
}
.svg-image {
visibility: hidden;
}
.clip-svg .svg-image:hover {
visibility: inherit;
}
/* size and positioning */
svg.clip-svg {
position: absolute;
height: 250px;
width: 250px;
}
#svg-1 {
top: 110px;
left: 50px;
}
#svg-2 {
top: 40px;
left: 140px;
}
#svg-3 {
top: 160px;
left: 250px;
}
The clipping path is defined in svg#svg-defs, and can be set to whatever you like.
Image attributes are visible to / accessible by js and css.
You can apply the clipping path to any html element with css of
myElement {
clip-path: url(#clip-triangle);
}
but this is only reliable on firefox so far as I can tell.
Note: solution only tested on FF and chrome
note: small edit to move :hover from the svg to the embedded image, to correct problem with hover triggered outside clip area