image cropped as a triangle on webpage - css

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

Related

SVG ClipPath: Why does applying the clip path to a DIV have different results to an IMAGE?

I need to create a set of 3 triangles that each have content in them (images, copy, etc).
I have setup this Pen to show roughly what I'm trying to achieve: https://codepen.io/andystent/pen/OJyNdmB
And here is an image for quick reference:
In this example the "Top" and "Left" triangles are IMAGES with the clip-path applied and displaying perfectly.
The "Right" triangle (with the red background) is a DIV with the clip-path applied but the proportions are wrong.
It should look like a mirrored version of the "Left" triangle.
When I apply it to an image it is perfect but when I apply to the div it is not. What is the best way to do this?
I am new to SVG so it is extremely likely that I am not doing this correctly. I have looked at numerous posts and the method I have tried is from a few of those but without success... so now I'm reaching out to you geniuses...
Here's the HTML and CSS for the red "Right" triangle with the clip applied to the DIV in the CSS:
#right-wrapper {
position: absolute;
width: 50%;
height: 100%;
right: 0;
padding: 40px 20px;
box-sizing: border-box;
}
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
right: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
display: flex;
justify-content: center;
align-items: center;
}
<div id="right-wrapper">
<svg width="100%" height="100%" viewBox="0 0 1220 1214" preserveAspectRatio="none">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
<!-- <image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" /> -->
</svg>
</div>
----- UPDATE: -----
As suggested in the comments, I have created a simplified Pen that gets to the heart of what I'm trying to achieve and the embedded HTML and CSS is below.
Essentially I am trying to get the red <div> to be clipped exactly like the <image>.
https://codepen.io/andystent/pen/RwWRjLd
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
}
<svg width="20%" height="20%" viewBox="0 0 1220 1214">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" />
</svg>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
Here is an idea where I will be using mask instead of clip-path. The main trick to correctly set the viewBox (you already have it in your code) add preserveAspectRatio="none" then have a mask size of 100% 100%
.box {
width:200px;
height:200px;
display:inline-block;
background:red;
}
.mask {
-webkit-mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
}
<div class="box mask"></div>
<div class="box mask" style="width:300px;"></div>
<div class="box mask" style="height:300px;"></div>
<img src="https://i.picsum.photos/id/1074/200/200.jpg" class="mask">

CSS mask not working properly in Angular 5

I'm trying to create an Angular 5 app that consists of a masked/clipped image.
In plain ol' HTML + CSS, I can achieve what I want with the following code pen: https://codepen.io/earthican/pen/BJjgRv
body,
html,
.img {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
background-color: white;
overflow: hidden;
}
svg {
pointer-events: none;
width: 100%;
height: 100%;
position: absolute;
background: transparent;
fill: transparent;
mask: url(#polygon-mask);
}
<svg id="mask">
<defs>
<mask id="polygon-mask" x="0" y="0" width="960" height="588" >
<rect id="reverse-mask" fill="white" x="0" y="0" width="960" height="588" ></rect>
<polygon fill="red" points="112,62 162,112 162,162 62,162 62,112"></polygon>
</mask>
</defs>
<rect width="960" height="588" fill="teal"></rect>
</svg>
<div class="img">
<img src="https://i.pinimg.com/originals/53/5e/5b/535e5b3744dbb8264a7ebba5f29f44ca.jpg" style="margin-left: 0px; margin-top: 0px;">
</div>
However, I'm having trouble trying to convert the above to Angular. Here's what I have so far: https://plnkr.co/edit/w2gVe91NEIdUlCWs3qkN?p=preview
I think I'm starting to realize that Angular doesn't play very well with SVG. I should also point out that I'm fairly new to Angular 2+ and SVG, so I can't really be sure. If anyone can help or point out some useful resources, that will be greatly appreciated!
I have solved this by moving the mask attribute from CSS to the SVG tree, i.e.:
<svg mask="url(#polygon-mask)">
...
</svg>

css scale translated element without moving

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>

How to make an svg masked image compatible with Internet Explorer

Lately i have created an svg masked image that works perfectly in Chrome but done not work in My version of Internet explorer. Here is the End result expected from my svg
This is my svg code
<svg width="0" height="0" viewBox="0 0 160 160">
<defs>
<clipPath id="shape">
<path d="M10,70 Q0,80 10,90 L70,150 Q80,160 90,150 L150,90 Q160,80 150,70 L90,10 Q80,0 70,10z" />
</clipPath>
</defs>
</svg>
<img src='http://i.imgur.com/NR6kefg.jpg' class='photo_rectangle_inverse' />
<img src='http://i.imgur.com/DXaH323.jpg' class='photo_rectangle_inverse' />
And this is my css
* {
padding: 0;
margin: 0;
}
.photo_rectangle_inverse {
height: 160px;
width: 170px;
-webkit-clip-path: url(#shape);
clip-path: url(#shape);
position: relative;
-webkit-transform: translateZ(1px)
}
Since the svg was not working in Internet Explorer (IE 11), after reading this article that talks about compatibility issue with Browsers, I added
<meta http-equiv="X-UA-Compatible" content="IE=edge">
To the top of my page because IE Edge based on the article seems to be the most compatible with Svg.
But still the svg shape is not displaying.
Here is a Jsfiddle . Note Jsfiddle does not allow meta tag
How to make an svg masked image compatible with Internet Explorer ?
Tks
IE won't apply an SVG clip to a html element, so you need an SVG <image> element rather than an HTML <img> element e.g.
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width: 100%;
}
.photo_rectangle_inverse {
-webkit-clip-path: url(#shape);
clip-path: url(#shape);
position: relative;
-webkit-transform: translateZ(1px)
}
<svg height="100%" width="100%" >
<defs>
<clipPath id="shape">
<path d="M10,70 Q0,80 10,90 L70,150 Q80,160 90,150 L150,90 Q160,80 150,70 L90,10 Q80,0 70,10z" />
</clipPath>
</defs>
<image height="160px" width="170px" xlink:href='http://i.imgur.com/NR6kefg.jpg' class='photo_rectangle_inverse'/>
<image transform="translate(170,0)" height="160px" width="170px" xlink:href='http://i.imgur.com/DXaH323.jpg' class='photo_rectangle_inverse' />
</svg>'

Colour overlay for SVG using CSS?

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/

Resources