Image masking using css/javascript - html

Is it possible to transform a div into this kind of shape then fill it with an image? Or better transform an image to that shape? Both with CSS or Javascript.
Then arrange multiple of them in this manner
I intend to group the shapes into several rings as per the second picture. As for the pictures, it will be dynamic, so can't really pre-cut them.
*Edit: I found out the effect I actually want. It is actually masking. In webkit, this css property: -webkit-mask-box-image works well (I can use .png image too for the mask), but when I tried masking for firefox (using .svg file generated by Illustrator), it doesn't seem to work. The same .svg file works in Chrome using -webkit-mask-box-image css property

Yes, it is possible. Even without using any JavaScript or browser specific properties.
demo
I've tested it and it works on all current versions of Chrome, IE, FF, Opera, Safari (on Windows 7).
The idea is to have multiple wheels with slices of different angles (get the angle using a skew transform; the slices are also rotated using a rotate transform). The inner wheels cover the the central part of the outer ones.
The version I've made is a pretty simple one, with two wheels, 8 images for the inner wheel (that means each slice of the inner wheel has 360°/8 = 45°) and 12 images for the outer wheel (=> each slice of the outer one has 360°/12 = 30°).
Relevant HTML:
<div class='picture-wheel'>
<div class='outer-wheel wheel'>
<div class='slice'><div class='bg'></div></div>
<!-- the rest of the slices, 11 more for this demo -->
<div class='inner-wheel wheel'>
<div class='slice'><div class='bg'></div></div>
<!-- the rest of the slices, 7 more for this demo -->
<div class='cover-wheel wheel'></div>
</div>
</div>
</div>
Relevant CSS:
.wheel {
overflow: hidden;
position: relative;
border-radius: 50%;
box-shadow: 0 0 1em;
}
.picture-wheel {
width: 30em; height: 30em;
margin: 3em auto 0;
}
.slices-wrapper {
position: absolute;
width: 100%; height: 100%;
}
.slice {
overflow: hidden;
position: absolute;
bottom: 50%; right: 50%;
transform-origin: 100% 100%;
}
.outer { width: 30em; height: 30em; }
.inner-wheel {
transform: rotate(7.5deg);
width: 21em; height: 21em;
margin: 4.5em;
}
.cover-wheel {
width: 12em; height: 12em;
margin: 4.5em;
box-shadow: inset 0 0 1em;
background: white;
}
.bg {
border-radius: 50%;
background-position: 50% 0;
background-repeat: no-repeat;
background-size: 8em 6em;
}
.outer-wheel > .slice {
width: 15em; height: 15em;
transform: skewY(60deg);
}
.outer-wheel > .slice:nth-child(2) { transform: rotate(30deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(3) { transform: rotate(60deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(4) { transform: rotate(90deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(5) { transform: rotate(120deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(6) { transform: rotate(150deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(7) { transform: rotate(180deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(8) { transform: rotate(-150deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(9) { transform: rotate(-120deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(10) { transform: rotate(-90deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(11) { transform: rotate(-60deg) skewY(60deg); }
.outer-wheel > .slice:nth-child(12) { transform: rotate(-30deg) skewY(60deg); }
.outer-wheel > .slice .bg {
width: 30em; height: 30em;
transform: skewY(-60deg) rotate(-15deg);
}
.outer-wheel > .slice .bg {
background-image:
url(image-for-first-slice-outer.jpg);
}
.outer-wheel > .slice:nth-child(2) .bg {
background-image:
url(image-for-second-slice-outer.jpg);
}
/* background images for the other slices of the outer wheel */
.inner-wheel > .slice {
width: 10.5em; height: 10.5em;
transform: skewY(45deg);
}
.inner-wheel > .slice:nth-child(2) { transform: rotate(45deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(3) { transform: rotate(90deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(4) { transform: rotate(135deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(5) { transform: rotate(180deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(6) { transform: rotate(-135deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(7) { transform: rotate(-90deg) skewY(45deg); }
.inner-wheel > .slice:nth-child(8) { transform: rotate(-45deg) skewY(45deg); }
.inner-wheel > .slice .bg {
width: 21em; height: 21em;
transform: skewY(-45deg) rotate(-22.25deg);
}
.inner-wheel > .slice .bg {
background-image:
url(image-for-first-slice-inner.jpg);
}
.inner-wheel > .slice:nth-child(2) .bg {
background-image:
url(image-for-second-slice-inner.jpg);
}
/* background images for the other slices of the inner wheel */
Another slightly different enhanced version:
demo

Could try using the Canvas element and draw
http://jsfiddle.net/m6QgV/6/
Here's an example

Have a look at CSS3 transformations. You should be able to use standard matrix transformations (similar to how you would in OpenGL or DirectX) to do it.

Related

Why does 3d image cube require background?

I have created a 3d photo cube according to instructions from a code school class. There seems to be an error in the instructions. I have fixed the error by adding one line of code, but I am trying to understand why that line of code is necessary.
Here is the code (I put it in a CodePen):
.stage {
width: 200px;
height: 200px;
perspective: 600px;
perspective-origin: 50% 0;
margin-left: auto;
margin-right: auto;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation: rotate 10s infinite linear;
}
.side {
position: absolute;
width: 200px;
height: 200px;
top: 0;
left: 0;
background-color: red; /* THE LINE IN QUESTION */
text-align: center;
}
.front {
transform: translateZ(100px);
}
.back {
transform: rotateY(180deg) translateZ(100px);
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
transform: rotateX(-90deg) translateZ(100px);
}
#keyframes rotate {
0% {
transform: rotateY(0deg);
}
5% {
transform: rotateY(90deg);
}
25% {
transform: rotateY(90deg);
}
30% {
transform: rotateY(180deg);
}
50% {
transform: rotateY(180deg);
}
55% {
transform: rotateY(270deg);
}
75% {
transform: rotateY(270deg);
}
80% {
transform: rotateY(360deg);
}
100% {
transform: rotateY(360deg);
}
}
<div class="photobox">
<div class="stage">
<div class="cube">
<img class="side front" src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80">
<img class="side back" src="https://images.unsplash.com/photo-1499996860823-5214fcc65f8f?ixlib=rb-1.2.1&auto=format&fit=crop&w=702&q=80">
<img class="side left" src="https://images.unsplash.com/photo-1441786485319-5e0f0c092803?ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80">
<img class="side right" src="https://images.unsplash.com/photo-1510274332963-71d4e866fccf?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80">
</div>
</div>
</div>
In the .side class CSS, the instructions from the code school didn't include the background-color property. This creates a distortion. When the front image of the cube is facing front, the picture appears as it should. When the back image is facing front, it is covered by the front image, which is now on the back side of the cube. You can tell from the perspective that the front image is in back of the cube, but it is still superimposed on what is now in the front view. The same thing happens with the left and right images. I don't think I'm explaining it very well, so here is the CodePen so you can see what I'm talking about. https://codepen.io/dtarvin/pen/mdeGqXV You'll see that if the background-color property is commented out, you get the distortion, but if it's not, the cube works as it should.
So why is a background-color necessary for the image cube to display properly when I have an image filling each side? Why do two of the sides appear properly but two others don't when I don't use a background-color?
By the way, the instructions were put together by a teacher who is no longer at the code school, so I can't ask him what is going on.
Thanks!

How to get text normally into a distorted shape(parallelogramm)?

I am a bit confused: I want to create some parallelograms and put text into it. But as i put text into it, the text aligns to the shape of the parallelogram. Here is what ive tried
.parallelogram {
width: 130px;
height: 75px;
background: blue;
-webkit-transform: skew(20deg);
-moz-transform: skew(20deg);
-o-transform: skew(20deg);
transform: skew(20deg);
}
<div class="parallelogram">
<div>
<p>Projects</p>
</div>
</div>
So as you can see, i created a Div within a class, that creates the parallelogram. Now if i try to put another p tag as child into the div tag that contains the shape, my text looks not normally. Is there any way to remove the inerhit of the child? So my text would look normaly or is there even a better way? Thanks
.parallelogram {
width: 130px;
height: 75px;
background: blue;
-webkit-transform: skew(20deg);
-moz-transform: skew(20deg);
-o-transform: skew(20deg);
transform: skew(20deg);
}
.parallelogram p{
transform: skew(-20deg);
}
<div class="parallelogram">
<div>
<p>Projects</p>
</div>
</div>
.parallelogram p{
transform: skew(-20deg);
}
I think you trying something like this :
.parallelogram {
width: 300px;
height: 100px;
background-color: green;
transform: skewX(30deg);
transform-origin: top;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
}
.parallelogram > span {
transform: skewX(-30deg);
}
<div class="parallelogram">
<span>Projects</span>
</div>

prevent children from inheriting translateZ property

I am trying to create a 3d cube effect using css3. I am using translateZ property to create the 3d cube environment when I use translateZ on parent div the child div automatically inherits the property. I have tried to use transform: none and the tried to give negative transform but of no use. Here is an example fiddle
HTML
<div class="box-big">
<div class="box">
<h1>ABCD</h1>
</div>
</div>
CSS
body{
perspective: 1000px;
}
.box-big{
transform-style: perserve-3D;
}
.box{
width: 300px;
height: 300px;
background: #FF0000;
transform: translateZ(400px);
}
h1{
font-color: white;
line-height: 300px;
text-align: center;
transform: translateZ(-400px);
}
All the children of the parent are going to be rendered according to the parent, so what you are asking is not possible. You would have to re-transform it to what you want, or probably your best bet is to use some "layering" technique (such as position: absolute or negative margins) so that the h1 can be outside of the .box element, but still appear "on top" of the .box element.
Here's a working example:
Modified HTML:
<div class="wrapper">
<div class="box-big">
<div class="box">
</div>
</div>
<h1>ABCD</h1>
</div>
Modified CSS:
body{
perspective: 1000px;
}
.wrapper {
position: relative;
}
.box-big {
transform-style: preserve-3D;
}
.box{
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background: #FF0000;
transform: translateZ(300px);
z-index: 1;
}
h1 {
position: absolute;
top: 0;
left: 0;
width: 200px;
color: white;
line-height: 200px;
text-align: center;
z-index: 255555;
}
https://jsfiddle.net/kcobbvcL/4/
As a side note, your fiddle css has some typos. Be sure to use a good IDE or a browser tool to watch for illegal / invalid css.
every cube has 6 sides, so u should use 6 div s. As we want to move the whole cube we should include those 6 div s in one div (div#cube).
first, you should create the cube using css, as the example below, then you translate or rotate the cube, using transform in div#cube.
.container {
width: 200px;
height: 200px;
position: relative;
perspective: 1000px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
}
#cube figure {
width: 196px;
height: 196px;
display: block;
position: absolute;
border: 2px solid black;
}
#cube .front { transform: rotateY( 0deg ) translateZ( 100px ); }
#cube .back { transform: rotateX( 180deg ) translateZ( 100px ); }
#cube .right { transform: rotateY( 90deg ) translateZ( 100px ); }
#cube .left { transform: rotateY( -90deg ) translateZ( 100px ); }
#cube .top { transform: rotateX( 90deg ) translateZ( 100px ); }
#cube .bottom { transform: rotateX( -90deg ) translateZ( 100px ); }
#cube{
transition: all 1s;
}
#cube:hover{
transform: rotateY( -20deg );
/*transform: translateZ( -100px );*/
}
<section class="container">
<div id="cube">
<figure class="front">1</figure>
<figure class="back">2</figure>
<figure class="right">3</figure>
<figure class="left">4</figure>
<figure class="top">5</figure>
<figure class="bottom">6</figure>
</div>
</section>

Centering image css/html

I'm having a problem centering an image in css,
I have this:
<div class="workcontainer3">
<div class="wc3_inside"></div>
</div>
.workcontainer3 {
display:box;
width: 300px;
height: 300px;
margin-left:341px;
margin-top:277px;
background-color: #68477c;
-webkit-transform: rotateX(0deg) rotateY(50deg) rotateZ(-45deg);
transform: rotateX(0deg) rotateY(60deg) rotateZ(-45deg);
position:absolute;
overflow:hidden;
}
.wc3_inside{
-webkit-transform: rotateX(0deg) rotateY(0deg) rotateZ(45deg);
transform: rotateX(0deg) rotateY(0deg) rotateZ(45deg);
max-width: 500px;
max-height: 500px;
content:url(../testeimg.jpg) 50% 50%;
}
So basicaly I want to create a site, when i'll go to publish articles with images, and I want to get that image and independently of his size, i want that the image become centered in the" rhombus workcontainer3".
Like this:
So anyone knows what i'm doing wrong please?
I don't know your html, but you could try this, assuming your .wc3_inside is inside .workcontainer3.
.workcontainer3 {
display: table;
}
.wc3_inside {
display: table-cell;
text-align: center;
vertical-align: middle;
}
Working Fiddle

text moving out of the element using transform rotate [duplicate]

This question already has an answer here:
Text overflowing out of div using transform: rotate(xdeg)
(1 answer)
Closed 8 years ago.
I have twisted the text to a 270 degree angle. my problem is aligning it inside another div.
Here is the image before I twisted the text:
and this is my my code for that for this:
#infoside {
background-color: #00ff00;
float: right;
height: 100%;
width: 41%;
}
#tabbings {
float: left;
width: 15%;
height: 100%;
background-color: #ffff00;
}
#tab_panels {
float: right;
width: 85%;
height: 100%;
background-color: #00ffff;
}
#client_info {
height: 100px;
width: 100%;
}
<div id="infoside">
<div id="tabbings">
<div id="client_info" class="active_tabbing">
<div id="text_here" style="width: 100px; height: 25%; text-align: center">
CLIENT INFO
</div>
</div>
<div class="clear"></div>
</div>
<div id="tab_panels"></div>
<div class="clear"></div>
</div>
and when I add this class to the div with id text_here that will twist the text the image below will be the result
.twist_text {
-moz-transform: rotate(270deg);
-webkit-transform: rotate(270deg) ;
-o-transform: rotate(270deg) ;
-ms-transform: rotate(270deg) ;
transform: rotate(270deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
}
How do I make this be inside the square?
Thank you.
You need to use transform-origin:0 0; on your CSS to set the rotation axis on the top left of your div. By default, it is set at 50% 50%, and you can set it to any value you like.
If i got it........
Try this
.twist_text {
-moz-transform: rotate(270deg) translateX(-35px);
-webkit-transform: rotate(270deg) translateX(-35px) ;
-o-transform: rotate(270deg) translateX(-35px) ;
-ms-transform: rotate(270deg) translateX(-35px) ;
transform: rotate(270deg) translateX(-35px);
}
after that it will look like below