I have an html/css 3d object as in picture 2. I want to make it curve a little bit as in picture 1
Does someone have an idea perhaps how it could be achieved Or if there is any other technology by which I can shape these 3d objects ?
This is the code for my object in the picture 2:
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.cube {
background: #dc2e2e;
width: 200px;
height: 50px;
position: relative;
margin: 50px;
transform: rotate(32deg);
}
.cube::before {
content: '';
display: inline-block;
background: #f15757;
width: 200px;
height: 2px;
transform: skewX( -80deg);
position: absolute;
top: -2px;
left: 6px;
}
.cube::after {
content: '';
display: inline-block;
background: #9e1515;
width: 12px;
height: 50px;
transform: skewY(-10deg);
position: absolute;
top: -1px;
left: 100%;
}
<div class="container">
<div class="cube"></div>
</div>
Creating an arc out of a div element is not so straightforward . Also using div tag to create shapes and graphics is not a good way instead you should use Scalable Vector Graphics(SVG), HTML Canvas, WebGL or any other JS libraries.
Using div tag you can create a bottom arc by adding bottom border radius:
.cube {
background: #dc2e2e;
width: 200px;
height: 50px;
position: relative;
margin: 50px;
box-shadow: 0px 10px 16px -6px black;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
}
<div class="container">
<div class="cube"></div>
</div>
But you can't achieve a top arc using the border top radius because using it will create an arc in opposite direction and thus create an oval instead of an arch.
One thing you can do is to overlay the upper part of the rectangle with another div tag of white color to create an arch like effect.
.arch {
width: 200px;
overflow: hidden;
}
.lowerarc {
width: 240px;
position: relative;
right: -10px;
left: -20px;
height: 80px;
background-color: black;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
}
.upperarc {
height: 80px;
position: relative;
width: 240px;
top: -120px;
right: -10px;
left: -20px;
background-color: white;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
}
<div class="arch">
<div class="lowerarc"></div>
<div class="upperarc"></div>
</div>
But it doesn't look good. so using div is probably not the best way to get the desired result.
Try using SVG instead:
In this example below we create an arch using lines and curves by plotting pixel values and filling the shape with a specific color.
M means move to, L to create a line, Q to draw curves, and z to close the path and the number corresponding to it are the values in pixel
<svg width="200">
<path d="M0,0 L0,50 Q100,80 200,50 L200,0 Q100,25 0, 0z" fill="black" />
</svg>
In this code below, we just create a curve line but with a 50px thickness.
<svg viewBox="0 0 1000 400">
<path d="M 60,250 C 60,150 150,50 250,50" fill="none"
stroke="green" stroke-width="50"></path>
</svg>
Use Canvas:
Canvas is similar to Svg but it uses javascript to create path and graphics.
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
c.beginPath();
c.moveTo(60, 0);
c.lineTo(10, 0);
c.quadraticCurveTo(0, 170, 170, 250);
c.lineTo(195, 210);
c.quadraticCurveTo(50, 150, 60, 0);
c.fill();
<canvas id="canvas" width="622" height="1080"></canvas>
While SVG and Canvas are used to create 2D graphics only,but still you can use 2D objects together to create a 3D like illusion.
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
c.fillStyle="rgba(0, 0, 25, 0.7)";
c.beginPath();
c.moveTo(10, 0);
c.lineTo(0, 5);
c.quadraticCurveTo(-10, 180, 170, 260);
c.lineTo(195, 220);
c.lineTo(195, 210);
c.quadraticCurveTo(30, 250, 60, 0);
c.fill();
c.fillStyle="rgb(200, 210, 200)";
c.beginPath();
c.moveTo(60, 0);
c.lineTo(10, 0);
c.quadraticCurveTo(0, 165, 170, 250);
c.lineTo(195, 210);
c.quadraticCurveTo(50, 135, 60, 0);
c.fill();
<canvas id="canvas" width="622" height="1080"></canvas>
<script src="main.js">
</script>
SVG and Canvas codes looks scary but it is not as difficult as it looks like. You can read documentations or watch Youtube tutorials to learn it properly.
Making curved 3d objects in pure html/css is not very easy but it is doable. There a few techniques to do it but you will need to understand exactly what you want and how to alter the number to achieve it.
You can stack multiple div elements to create a curved 3d effect and then offset the z axis for each one. Essentially you are just stacking lots of elements together to give the illusion of a curved 3d object. In the below links I use radial gradient.
I would recommend using a pre-proccessor like SCSS for this as it allows you to run a loop to offset each element cutting out a lot of code you would have to write for each element. Also keep in mind if you intend to animate this after then that will be very taxing on the processing depending on device. If you are trying to make it static then it shouldn't be an issue.
SCSS
#for $i from 1 through 20 {
$color: red;
&:nth-child(#{$i}) {
position: absolute;
width: $width;
height: $height;
list-style: none;
background: rgb(0, 0, 0);
background: radial-gradient(
circle at 50% 150%,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0) 60%,
darkred 60%,
darkred 70%,
rgba(0, 0, 0, 0) 70%,
rgba(0, 0, 0, 0) 100%
);
transform: translateZ(-20px + (0.8px * ($i - 1)));
filter: blur(0px) contrast(200%);
}
simple curves example 1 https://codepen.io/jfirestorm44/pen/MWmKraz?editors=0100
complex art example 2 https://codepen.io/jfirestorm44/pen/qBZYQBL
Like I said about performance; Example 2 will take some processing power and may lag. The object can be rotate by clicking.
I'd like to add to #Miran Firdausi's answer about SVGs (but I can't comment yet). A good way to create SVGs and then "hard code" them into CSS is to use any vector paint program (such as Inkscape) to draw exactly what you want, then save as SVG.
You can open the .svg file in your code editor and you will see XML markup, including codes which you can copy into your HTML, like in #Miran's example:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" version="1.1" role="img" aria-hidden="true" focusable="false">
[copy the <path> elements here]
</svg>
Or save the .svg file somewhere and refer to it in your CSS:
/* Add calendar icon */
.wp-social-link.my-calendar-icon > a {
background-image: url(assets/images/my-calendar.svg);
background-repeat: no-repeat;
background-position: center;
background-size: 36px;
width: 54px;
height: 54px;
filter: invert(100%) brightness(100%) contrast(100%);
}
This question already has answers here:
Animate dashed SVG line
(3 answers)
Closed 5 years ago.
How can I make a dot line from starting begin to the end path (for example the 3 shape, with the dot line drawing from top to bottom)?
.box {
overflow: hidden;
outline: none;
width: 200px;
height: 200px;
position: relative;
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
z-index: 10;
background-color: white;
background-repeat: no-repeat;
animation: showDiag 2s linear forwards;
}
#keyframes showDiag {
from {
left: 0;
top: 0;
}
to {
left: 200px;
top: 200px;
}
}
<div class="box">
<svg class height="200" width="200">
<line fill="none" stroke="black" x1="0" y1="0" x2="200" y2="200" stroke-dasharray="5, 5" />
</svg>
<div class="mask"></div>
</div>
I have no idea how to do the fade out from top to bottom.
With a solid (not dotted) line it is quite easy. Here is a very good tutorial:
Animated line drawing in SVG
I bet all of you have seen that little trick where an SVG path is
animated to look like it's drawing itself. It's super cool. Jake
Archibald pioneered the technique and has a super good interactive
blog post on how it works. Brian Suda wrote about it on 24 Ways.
Polygon used it to great effect on a custom designed article and wrote
about it. Codrops has some neat examples.
I have very little to add, except my brain just kinda figured it out,
so I thought I would explain it one more time the way it clicked for
me.
here is something that i read and looks useful - https://css-tricks.com/svg-line-animation-works/
I would like to use HTML + CSS to draw a arc sector with fixed radix and length (e.g. 30px radius and 70% length).
I found so far most of the solution is to combined two pictures with position:absoulte. Unfortunately, my html codes will be embedded as an email template to send out, and I found that Gmail does not support absolute position. And that is also the reason why I would like to use inline style rather than header css.
Related question here:
HTML5 / CSS3 Circle with Partial Border
The similar output I am looking for.
http://dabblet.com/gist/3949571
Any help for it?
I'd use an SVG.
svg {
width: 150px;
height: 150px;
}
circle.inner {
stroke: rebeccapurple;
stroke-width: 3;
stroke-dasharray: 39% 139%;
stroke-dashoffset: 78%;
fill: pink;
}
<svg viewbox="0 0 100 100">
<circle class="inner" cx="40" cy="40" r="25" />
</svg>
you can use transparent borders and inset shadow to draw bg color :
/*demo*/
div {
display:flex;
align-items:center;
justify-content:center;/* center content not text */
text-align:center;
}
<div style="
box-sizing:border-box;
padding:1px;
margin:5px;
height:200px;
width:200px;
border:solid 20px transparent;
border-top-color:blue;
box-shadow:inset 0 0 0 100px lightblue;
border-radius:100%;"
>Some text <br/> too?</div>
Is it possible to create the shape produced by this Fiddle. But then with no JavaScript but CSS3 (with <div>) ?
Basically this:
for(var i = 0; i < coords.length; i += 1) {
if(coords[(i + 1)] != undefined) {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[(i + 1)].x, coords[(i + 1)].y);
ctx.stroke();
} else {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[0].x, coords[0].y);
ctx.stroke();
}
}
So you have points that needs to connect to each other?
Use svg, if you don't want to use canvas.
<svg width="100" height="100">
<path d="M0 0 l100 10 l-40 90z" fill="none" stroke="black" stroke-width="2" />
</svg>
Path command for 8,8,10,10,30,30,49,10 would be M8 8 L10 10 L30 40 L49 10z.
<svg width="49" height="40" viewBox="0 0 50 41">
<path d="M8 8 L10 10 L30 40 L49 10z" fill="none" stroke="black" stroke-width="2" />
</svg>
To apply a click event to the shape, you could use pointer-events: all on #test.
#test {
pointer-events: all;
}
<svg width="49" height="40" viewBox="0 0 50 41">
<path id="test" d="M8 8 L10 10 L30 40 L49 10z" fill="none" onclick="alert('Works')" stroke="black" stroke-width="2" />
</svg>
Note: Posting this answer just because you asked with CSS3, but the complexity and possible calculation overhead involved in this approach is proof enough why CSS shouldn't be used for this. Please do not use this approach.
A bit of explanation on how this was achieved:
A div is created with top and right border (1px black) and the other two borders are set to none.
This div is then skewed a bit to make it appear as though the edge on the right side is a bit slanted.
Inside the shape, a pseudo-element with only a right border is created and it is also skewed to produce the diagonal line from the right-bottom to the left-top. Transform origin is set as right-bottom to avoid positioning overhead.
An anchor tag is added within the parent div and the overflow is set to hidden so that only the portion within the shape is clickable.
The user select on the anchor tag are disabled to prevent a double click from selecting a blank space within the div.
Finally the whole container div is rotated a bit to make it look as though the triangle is not parallel to x-axis.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 50px;
width: 45px;
border: 1px solid black;
border-left: none;
border-bottom: none;
-webkit-transform: skew(-10deg) rotate(5deg);
-moz-transform: skew(-10deg) rotate(5deg);
transform: skew(-10deg) rotate(5deg);
overflow: hidden;
}
a {
display: block;
content: '';
margin-left: 0px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
height: 100%;
width: 100%;
}
div:after {
position: absolute;
top: 0px;
left: 0px;
content: '';
height: 50px;
width: 45px;
-webkit-transform: skew(42deg);
-webkit-transform-origin: left bottom;
-moz-transform: skew(42deg);
-moz-transform-origin: left bottom;
transform: skew(42deg);
transform-origin: left bottom;
border-right: 1px solid black;
}
<div>
</div>
Another option to create a skewed triangle shape would be to use clip-path like in below snippet. The shape is created by applying the same clip-path on the main container element and a pseudo-element which is smaller than the container.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 150px;
width: 150px;
background: black;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
div:after{
position: absolute;
content: '';
height: calc(100% - 5px);
width: calc(100% - 5px);
top: 2px;
left: 3px;
background: white;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
/* Just for demo */
div{
transition: all 1s;
}
div:hover{
height: 250px;
width: 250px;
}
<div id="clickme"></div>
You can do it by embeding SVG as CSS. Quote from:
http://css-tricks.com/using-svg/
"Another way to use SVG's is to convert them into Data URI's. Data URI's might not save you actual file size, but can be more efficient because the data is right there. It doesn't require an additional HTTPRequest.
Mobilefish.com has an online conversion tool for that (http://www.mobilefish.com/services/base64/base64.php). Simply paste in the contents of your SVG file and fill out the form and it will display the results in a textarea for you to copy. Remember to remove line breaks in the data it gives you back.
...
You can use that anywhere we've talked about so far (except inline because that just doesn't make sense) Just put the gibberish where it says [data] in these examples.
As CSS
.logo {
background: url(data:image/svg+xml;base64,[data]);
}
"
I'm trying to fit an svg into a div. The svg contains of a single path. I've set up viewBox and preserveAspectRatio correctly, I think, but a part of the path (which is supposed to fit entirely in the svg) is drawn outside the viewBox. Here's the fiddle, and here's the code:
html:
<div class='sparkline' class="ng-isolate-scope">
<svg viewBox="1 1 10 10" preserveAspectRatio="none">
<path d="M0,10L5,5L10,0"></path>
</svg>
</div>
css:
path {
stroke: blue;
stroke-width: 0.2;
fill: none;
}
.sparkline{
width: 200px;
height: 200px;
position:absolute;
top:0px;
left:0px;
border: 1px solid black;
margin: 20px;
}
svg{
width:100%;
height:100%;
display: block;
position: absolute;
top: 0px;
left: 0px;
}
I see no reason for the line to be shifted to the left, how can I overcome this?
Your code works as expected, but it possibly contains a typo. Provided that the viewBox is defined between 1 and 10, the line with 0 in X or/and Y should look shifted off the box.
Use viewBox="0 0 10 10" to fit the line into diagonal of the box.