I have this code:
<svg height="100" width="100">
<style>
.svg-circle {
-webkit-transform-origin: 50% 0;
transform-origin: 50% 0;
-webkit-transform: rotateY(0);
transform: rotateY(0);
}
.svg-circle:hover {
-webkit-transform: rotateY(360deg);
transform: rotateY(360deg);
-webkit-transition: all 0.7s;
transition: all 0.7s;
}
</style>
<circle class="svg-circle" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
It works well in modern browsers. Can I make it works in IE10/IE11? Or I need to use only Javascript?
After long researching I came to the conclusion the best way for cross-browser support — put image in <div> as background-image and apply CSS to it.
JSFiddle
.circle {
width: 100px;
height: 100px;
background: url(http://imgh.us/circle_5.svg) no-repeat;
background-size: 100px 100px;
-webkit-transform: rotateY(0);
transform: rotateY(0);
}
.circle:hover {
-webkit-transform: rotateY(360deg);
transform: rotateY(360deg);
-webkit-transition: all 0.7s;
transition: all 0.7s;
}
<div class="circle"></div>
Well, is it force on rotating the <circle/>?
Because you can easily rotate <svg></svg> in all browsers!
If yes, so you are in big trouble because in IE your problem is not only CSS3 support, you going to have some problem with JS, and that's because of rotateX or rotateY!
And even worst, you going to have some problem with animating it in jQuery!
So I used VELOCITY.JS to animating it and you can see this [ SAMPLE ] on IE and change rotateZ by rotateY! (to see rotateY is not working on SVG childs like path, circle, etc)
It seems you have to change your plan!
Hope to help! And by the way! by puting transition on hover state, you don't have it on hover-back!
Related
I would like to create the following webpage, where the navigation bar drops down on and is slanted.
So when a user opens the website its front page looks like
]1
Then when a user presses the "menu button" (which I have not drawn), the following menu bar appears (ideally slides down as an animation)
I really need help with designing the slanted navigation bar and adding the subsequent animation.
Thanks!
You can use an SVG shape as a background, and really any shape you want to make.
CodePen Link with an animation as well
HTML:
<div class="triangle-container">
<svg height="300" width="500">
<polygon points="0,-200 500,-200 500,100" class="triangle" />
Sorry, your browser does not support inline SVG.
</svg>
</div>
CSS:
body{
}
.triangle-container{
width: 500px;
margin: auto;
text-align:center;
border: 1px solid white;
&:hover, &:active{
.triangle{
transform: translate(0px, 200px);
}
}
.triangle{
fill: black;
transition: all 0.8s ease-in-out;
#keyframes mymove {
0% {opacity:0}
50% {opacity:1}
100% {opacity:0}
}
transform-origin: 250px 250px;
}
}
One way of doing it is if you have a triangle image, with a height of 0. And all of your menu items are off the top of the screen, out of view. When you want the menu to slide down, use jquery animate to increase image height and slide all of the menu items down.
const time = 700;
$("#triangleId").animate({
height: "+=10px"
}, time);
$("#menuItemOneId, #menuItemTwoId...").animate({
top: "+=10px"
}, time);
I made a little way using clip-path and css keyframes. This way you can avoid javascript and the code is responsive no pixels needed.
HTML
<html>
<body>
<div class = 'navbar'></div>
</body>
</html>
CSS
.navbar{
width: 100vw;
height: 25vh;
background-color: red;
clip-path: polygon(100% 0, 100% 100%,0% 0%);
animation: open 3s infinite;
}
#keyframes open{
0% {clip-path:polygon(100% 0, 100% 0,100% 0);}
100% {clip-path:polygon(100% 0, 100% 100%,0% 0%);}
}
Link to code pen for this:
https://codepen.io/mfortunato/pen/jOWmXvL
The output I want;
I want to make a sphere with names, but without curving/bending the names. I also want to make it spin in the direction of the mouse pointer.
If i use this rotate property, my words got curved.
#keyframes rotate {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
.circ{
border: none;
height: 200px;
width: 200px;
position: absolute;
border-radius: 50%;
transform-style: preserve-3d;
box-sizing: border-box;
}
#sphere{
animation: rotate 6s linear infinite;
transform-style: preserve-3d;
width: 400px;
height: 400px;
}
.circ:nth-child(1) {
transform: rotateX(0deg);
}
.circ:nth-child(2) {
transform: rotateX(30deg);
}
.circ:nth-child(3) {
transform: rotateX(60deg);
}
.circ:nth-child(4) {
transform: rotateX(90deg);
}
.circ:nth-child(5) {
transform: rotateX(120deg);
}
.circ:nth-child(6) {
transform: rotateX(150deg);
}
.circ:nth-child(7) {
transform: rotateX(180deg);
}
.circ:nth-child(8) {
transform: rotateX(210deg);
}
<div id="sphere">
<div class="circ">aaaaa</div>
<div class="circ">bbbbb</div>
<div class="circ">ccccc</div>
<div class="circ">ddddd</div>
<div class="circ">eeeee</div>
<div class="circ">ffffffff</div>
</div>
and so on..
TLDR: It's complicated.
Basically you want a game engine loop and some advanced visualization library like D3 or Pixi.js. You might could get away with straight css/html if you only have a few words, but it might be laggy Here's the approach I would take:
Give each word a coordinate in relation to the center of a 3d sphere.
Do some math and rotate your sphere towards the mouse. (You probably want to use a vector library like gl-matrix.)
Update each word's position by applying the sphere's rotation to it.
Apply camera lens transform to each word's location, or just scale them by z-distance to get a perspective effect.
Render words using whatever tech your library uses, like sprites or vectors.
What is the criteria?
In the following example, I am animating CSS transform, and when you click anywhere (while in Google Chrome) the animation is blocked by a 2-second-long while loop.
Why is the CSS transform animation blocked?
EDIT: Lately Chrome no longer blocks the transform while the main thread is blocked, indicating that they have moved the sort of animation in the following example off main thread.
Animating transform can happen on a separate thread, but it isn't clear exactly when. Sometimes it works.
In this first example, separate-thread transform animation does not happen (click on it to block the main thread and therefore pause the animation):
window.addEventListener('click', kill)
function kill() {
var start = +new Date;
while (+new Date - start < 2000){}
}
html, body, div {
width: 100%; height: 100%;
margin: 0; padding: 0;
/* background: #364659; */
/* background: #293442; */
background: #1E2630;
overflow: hidden;
}
#keyframes ShimmerEffect {
0% { transform: translate3d(-15%, -15%, 0) }
100% { transform: translate3d(-60%, -60%, 0) }
}
.shimmerSurface {
/* overflow: hidden; */
/* perspective: 100000px */
}
.shimmerSurfaceContent {
transform-style: preserve-3d;
background: linear-gradient(
-45deg,
rgba(0,0,0,0) 40%,
rgba(244,196,48,0.6) 50%,
rgba(0,0,0,0) 60%
);
background-repeat: repeat;
background-size: 100% 100%;
width: 400%; height: 400%;
animation: ShimmerEffect 1.8s cubic-bezier(0.75, 0.000, 0.25, 1.000) infinite;
}
<div class="shimmerSurface">
<div class="shimmerSurfaceContent"></div>
</div>
(codepen link)
EDIT: seems the example's animation is not blocked in Safari (though it chops the gradient), but is blocked only in Chrome and Firefox. How can we unblock the animation in Chrome and Firefox?
In next example, when you click anywhere to block the main thread (in Chrome), you will see that transform is animated on a separate thread because it continues to animate, while the stroke-offset animation is frozen because apparently stroke-offset animation is happening on the main thread:
window.addEventListener('click', kill)
function kill() {
var start = +new Date;
while (+new Date - start < 2000){}
}
.loader {
--path: #2F3545;
--dot: #5628EE;
--duration: 3s;
width: 44px;
height: 44px;
position: relative;
}
.loader:before {
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
position: absolute;
display: block;
background: var(--dot);
top: 37px;
left: 19px;
transform: translate(-18px, -18px);
-webkit-animation: dotRect var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
animation: dotRect var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
}
.loader svg {
display: block;
width: 100%;
height: 100%;
}
.loader svg rect,
.loader svg polygon,
.loader svg circle {
fill: none;
stroke: var(--path);
stroke-width: 10px;
stroke-linejoin: round;
stroke-linecap: round;
}
.loader svg polygon {
stroke-dasharray: 145 76 145 76;
stroke-dashoffset: 0;
-webkit-animation: pathTriangle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
animation: pathTriangle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
}
.loader svg rect {
stroke-dasharray: 192 64 192 64;
stroke-dashoffset: 0;
-webkit-animation: pathRect 3s cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
animation: pathRect 3s cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
}
.loader svg circle {
stroke-dasharray: 150 50 150 50;
stroke-dashoffset: 75;
-webkit-animation: pathCircle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
animation: pathCircle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
}
.loader.triangle {
width: 48px;
}
.loader.triangle:before {
left: 21px;
transform: translate(-10px, -18px);
-webkit-animation: dotTriangle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
animation: dotTriangle var(--duration) cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite;
}
#-webkit-keyframes pathTriangle {
33% {
stroke-dashoffset: 74;
}
66% {
stroke-dashoffset: 147;
}
100% {
stroke-dashoffset: 221;
}
}
#keyframes pathTriangle {
33% {
stroke-dashoffset: 74;
}
66% {
stroke-dashoffset: 147;
}
100% {
stroke-dashoffset: 221;
}
}
#-webkit-keyframes dotTriangle {
33% {
transform: translate(0, 0);
}
66% {
transform: translate(10px, -18px);
}
100% {
transform: translate(-10px, -18px);
}
}
#keyframes dotTriangle {
33% {
transform: translate(0, 0);
}
66% {
transform: translate(10px, -18px);
}
100% {
transform: translate(-10px, -18px);
}
}
#-webkit-keyframes pathRect {
25% {
stroke-dashoffset: 64;
}
50% {
stroke-dashoffset: 128;
}
75% {
stroke-dashoffset: 192;
}
100% {
stroke-dashoffset: 256;
}
}
#keyframes pathRect {
25% {
stroke-dashoffset: 64;
}
50% {
stroke-dashoffset: 128;
}
75% {
stroke-dashoffset: 192;
}
100% {
stroke-dashoffset: 256;
}
}
#-webkit-keyframes dotRect {
25% {
transform: translate(0, 0);
}
50% {
transform: translate(18px, -18px);
}
75% {
transform: translate(0, -36px);
}
100% {
transform: translate(-18px, -18px);
}
}
#keyframes dotRect {
25% {
transform: translate(0, 0);
}
50% {
transform: translate(18px, -18px);
}
75% {
transform: translate(0, -36px);
}
100% {
transform: translate(-18px, -18px);
}
}
#-webkit-keyframes pathCircle {
25% {
stroke-dashoffset: 125;
}
50% {
stroke-dashoffset: 175;
}
75% {
stroke-dashoffset: 225;
}
100% {
stroke-dashoffset: 275;
}
}
#keyframes pathCircle {
25% {
stroke-dashoffset: 125;
}
50% {
stroke-dashoffset: 175;
}
75% {
stroke-dashoffset: 225;
}
100% {
stroke-dashoffset: 275;
}
}
.loader {
display: inline-block;
margin: 0 16px;
}
html {
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: border-box;
}
*:before, *:after {
box-sizing: border-box;
}
body {
min-height: 100vh;
background: #F5F9FF;
display: flex;
justify-content: center;
align-items: center;
}
body .dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
}
body .dribbble img {
display: block;
height: 28px;
}
<div class="loader">
<svg viewBox="0 0 80 80">
<circle id="test" cx="40" cy="40" r="32"></circle>
</svg>
</div>
<div class="loader triangle">
<svg viewBox="0 0 86 80">
<polygon points="43 8 79 72 7 72"></polygon>
</svg>
</div>
<div class="loader">
<svg viewBox="0 0 80 80">
<rect x="8" y="8" width="64" height="64"></rect>
</svg>
</div>
Why does the first example's transform animation run on the main thread, while the second example's transform animation runs on a separate thread?
What are the criteria under which a transform is guaranteed to run in a separate thread (at least, in Chrome)?
Browser Threads
Each browser has at least three threads; precisely what is run on each depends on the browser. Modern browsers all have more than three now, but they still have three categories of threads that will always be separate. Why?
One will always be entirely separate and only accessible by the browser to handle things like scrolling, opening a new tab etc... At least one will always be for things like calculating and parsing and so will be run on the CPU. And at least one thread will run on the GPU as it is required for something to be shown on your screen.
Layers
For the GPU to know what it's showing on the screen it needs the layout rasterised in a bitmap format. But as things move around the screen it's best if we send the GPU a few bitmaps that can move around. We call these layers.
as #irdkwmnsb has pointed out we can use the layers tab in the developer tools to see exactly which elements have been split into separate bitmaps.
Explicitly Creating A Layer
For any HTML or SVG element that we know will transform, we can add the following CSS rule to ensure the element is separated into a separate bitmap layer and the transition shouldn't be blocked by other activity on the main thread:
will-change: transform
so adding the CSS rule
.shimmerSurfaceContent {
will-change: transform;
}
should stop the transition from being blocked in your first example.
Why Only In Some Browsers?
The reason some browsers may not automatically split this element into a separate layer is that there is a performance issue with creating too many bitmap layers so they are careful not to create too many. Also, some things don't look good when created as separate bitmaps and moved around so the browser may avoid it.
But for this example specifically, we can see from the two bitmap layers in this image that the top one has a semi-transparent edge. Things like this have previously caused aliasing problems for the GPU as it calculates the various shaded of yellow.
This may have been a reason for chrome to previously avoid separating it into a new bitmap layer.
I have adapted code from this page: Filling water animation to suit my needs as you can see below.
CSS
#banner {
width: 150px;
height: 150px;
background:red;
overflow: hidden;
-webkit-backface-visibility: hidden;
}
.rotate {
-ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
#banner .fill {
-webkit-transform: translate(0, -75px);
}
#banner #waveShape {
-webkit-animation-name: waveAction;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 1s;
width:300px;
height: 155px;
opacity:0.9;
fill: #fff;
#-webkit-keyframes waveAction {
0% {
-webkit-transform: translate(150px,0);
}
100% {
-webkit-transform: translate(0, 0);
}
}
HTML
<div id="banner">
<div class="fill">
<svg class="rotate" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="155px" viewBox="0 0 300 155" enable-background="new 0 0 300 155" xml:space="preserve">
<path fill="#04ACFF" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z"/>
</svg>
</div>
</div>
Also...
Please see a screenshot of the output here.
However, I'd like to go one step further and control the level the 'water' is filled via a javascript function.
Usually, I would just control the X and Y position of the DIV that contains the waving SVG but that doesn't appear to work here.
I'd like to use this as a loading infographic but at the moment I can only control the 'water' level using...
}
#banner .fill {
-webkit-transform: translate(0, -75px);
}
I can use values of 0px (0%) to -155px (100%) but ideally I'd like to be able to set a percentage, perhaps by passing a variable in??
NOTE: I've rotated the original SVG because I was struggling to create a new one that worked correctly.
Any help would be much appreciated, I know I'm going to kick myself when I see the solution!! Thankyou.
Get rid of the .rotate and #banner .fill transforms
If you give the svg an id, you can adjust the top margin of the svg using a %
eg
el.style.marginTop = "75%";
Working example: (tested in chrome)
<style type="text/css">
#banner {
width: 150px;
height: 150px;
background:red;
overflow: hidden;
-webkit-backface-visibility: hidden;
}
#water {
margin-top: 99%;
}
#banner #waveShape {
-webkit-animation-name: waveAction;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 1s;
animation-name: waveAction;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-duration: 1s;
width:300px;
height: 155px;
opacity:0.9;
fill: #fff;
}
#keyframes waveAction {
0% {
-webkit-transform: translate(-150px,0);
transform: translate(-150px,0);
}
100% {
-webkit-transform: translate(150, 0);
transform: translate(150, 0);
}
}
</style>
<script>
function fill(percent) {
var el=document.getElementById("water");
if (el == null) {
alert("missing element");
return;
}
el.style.marginTop = (100-percent)+"%";
}
</script>
<div id="banner">
<div class="fill">
<svg id="water" class="rotate" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="155px" viewBox="0 0 300 155" enable-background="new 0 0 300 155" xml:space="preserve">
<path fill="#04ACFF" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z"/>
</svg>
</div>
</div>
<script>
fill(25); //set fill to 25%
</script>
If that doesn't work you could try simply inserting an empty div before the svg and adjusting the height of that.
i'm new in javascript and especially in animation. The challenge for me is to make a letter oscilate back and forth max 30 degrees from the sides. The picture i uploaded is an example of the the animation, the letter will move from the upper right corner or from the pin but i think that is harder.
I need some guidance into this if anyone can help please reply.
Thanks in advance
because i'm new i cannot post images so here is the link: http://i.stack.imgur.com/byzUC.png
Well, this took far longer than I care to admit, and is only reliable in (from my own limited testing) Chromium 12+ and Firefox 5+ on Ubuntu 11.04 (it does not work in Opera 11). That being the case I'll show only the excerpts to cover Firefox and Chromium, though the linked JS Fiddle has vendor prefixes to at least try with Opera (even if it fails). Using the following mark-up:
<img src="http://i.stack.imgur.com/byzUC.png" id="envelope" />
The following CSS produces an (infinitely) oscillating envelope for you to adjust to your preferences:
#envelope {
-webkit-animation-name: oscillate;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 10;
-webkit-animation-direction: infinite;
-moz-animation-name: oscillate;
-moz-animation-duration: 10s;
-moz-animation-iteration-count: 10;
-moz-animation-direction: infinite;
}
#-webkit-keyframes oscillate {
0% {
-webkit-transform: rotate(0deg);
-webkit-transform-origin: 108px 23px;
}
33% {
-webkit-transform: rotate(15deg);
-webkit-transform-origin: 108px 23px;
}
100% {
-webkit-transform: rotate(-20deg);
-webkit-transform-origin: 108px 23px;
}
}
#-moz-keyframes oscillate {
0% {
-moz-transform: rotate(0deg);
-moz-transform-origin: 110px 26px;
}
33% {
-moz-transform: rotate(15deg);
-moz-transform-origin: 110px 26px;
}
100% {
-moz-transform: rotate(-20deg);
-moz-transform-origin: 110px 26px;
}
}
JS Fiddle demo.
Given the spectacular failure rate of this approach, though (it certainly doesn't work in Opera 11, and I can only imagine that it achieves nothing in IE...) I'd strongly suggest an animated gif for the sheer simplicity and cross-browser compliance.