How to Increase (Animate) the Width of the Square on Both Ends

animate width of a box towards left

You can do it by animating the box's margin-left and width at the same time. Alternatively, if your box is absolutely positioned, animate it's left property and width at the same time.

HTML

<div id="loading"></div>

CSS

#loading {
margin-left: 200px;
width: 0;
height: 10px;
background: red;
}

jQuery

$('#loading').animate({width: 200, marginLeft: 0}, {duration: 1000});

You can see it in action here.

Keep div width after expanding it with hover (CSS)

Set an extremely high transition time for the shrinking animation part, which will give the effect of not shrinking. No js required, just setting it to something like 3600s (maybe try even higher?) which will be an hour will give you a visually static for a long time. I couldn't find the maximum time but it seems to work.





div.container{

width: 400px;

height: 250px;

border: 1px solid;

clear: both;

}


.square{

width: 100px;

height: 100px;

background: black;

float: left;

position: relative;

transition:width 5s;

-webkit-transition:width 5s;

}


.grow {

width: 0px;

height: 100px;

float: left;

background: black;

position: relative;

transition:width 3600s;

-webkit-transition:width 3600s;

background: green;

}


.square:hover + .grow{

width: 200px;

transition:width 0.5s;

-webkit-transition:width 0.5s;

}
<div class="container">

<div class="square"></div>

<div class="grow"></div>

</div>

Expand div from the middle instead of just top and left using CSS

The key is to transition the margin by a formula. There is a little "wiggle" that is annoying during the transition if it is floated.

EDITED ADDING OPTIONS

Option 1: Expands within space reserved around it http://jsfiddle.net/xcWge/14/:

#square {
width: 10px;
height: 10px;
margin: 100px; /*for centering purposes*/
-webkit-transition: width 1s, height 1s, margin 1s;
-moz-transition: width 1s, height 1s, margin 1s;
-ms-transition: width 1s, height 1s, margin 1s;
transition: width 1s, height 1s, margin 1s;
}
#square:hover {
width: 100px;
height: 100px;
margin: 55px; /* initial margin - (width change (and/or height change)/2), so here 100px is initial margin, and the change is (100px final W/H - 10px initial W/H = 90px change, so 100px - (90px / 2 [= 45px]) = 55px) */
}

Option 2: Expands over elements around it http://jsfiddle.net/xcWge/18/:

#square {
width: 10px;
height: 10px;
margin: 0; /*for centering purposes*/
-webkit-transition: width 1s, height 1s, margin 1s;
-moz-transition: width 1s, height 1s, margin 1s;
-ms-transition: width 1s, height 1s, margin 1s;
transition: width 1s, height 1s, margin 1s;
}
#square:hover {
width: 110px;
height: 110px;
margin: -50px; /* 0 - (110px - 10px [= 100px]) / 2 = -50px */
}

Option 3: Expands over elements before it in flow and shifts elements after it http://jsfiddle.net/xcWge/22/:

#square {
width: 10px;
height: 10px;
margin: 0;
position: relative;
top: 0;
left: 0;
-webkit-transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
-moz-transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
-ms-transition: width 1s, height 1s, top 1s, left 1s, margin 1s ;
transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
}
#square:hover {
width: 110px;
height: 110px;
top: -50px; /* initial top[0] - (new height[110px] - initial height[10px] [=100px])/2 [=50px] = -50px) */
left: -50px; /* initial left[0] - (new width[110px] - initial width[10px] [=100px])/2 [=50px] = -50px) */
margin-right: -50px;
margin-bottom: -50px;
}

ADDED NON-SQUARE EXAMPLE

A comment was made this does not work for a non-square (same width/height), but that just means one has to adjust differently for each direction during the transition. So here is Option 2 (with non-square) that starts as a rectangle, and the width expands twice as much as the height (so changes rectangle shape even) during the transition: Expands over elements around it http://jsfiddle.net/xcWge/2131/

#rectangle {
width: 110px;
height: 10px;
margin: 0; /*for centering purposes*/
-webkit-transition: width 1s, height 1s, margin 1s;
-moz-transition: width 1s, height 1s, margin 1s;
-ms-transition: width 1s, height 1s, margin 1s;
transition: width 1s, height 1s, margin 1s;
}
#rectangle:hover {
width: 310px;
height: 110px;
margin: -50px -100px; /* initial margin - ((initial margin - width change (or height change))/2) */
}

If the width were only changing by 100px also (so from 110px to 210px), then just a margin: -50px would have still worked.

how to make a CSS animation end point the right edge of the browser

solution is to use both left and margin-left

JSFIDDLE DEMO

.square
{
width: 30px;
height: 3px;
background: red;
position: relative;
animation: colors 2s;
-webkit-animation: colors 2s;
animation-iteration-count: infinite;
-webkit-animation-iteration-count: infinite;
top: 0px;
margin-left:-30px;
}

@keyframes colors {
0% {left: 30px;}
99% { left: 100%;}
}

@-webkit-keyframes colors {
0% {left: 30px;}
99% { left: 100%;}
}

How to animate svg rect to grow

Instead of animating two attributes simultaneously, I think you'll find it much easier to use a transform attribute to get the coordinate system you wanted in the first place.

In this example, the animated <rect> elements are wrapped in the following <g> element:

<g transform="scale(1,-1) translate(0,-200)">
...
</g>

The scale transform turns all the y coordinates upside down, and the translate transform shifts the coordinates so that y=0 is at the bottom of the SVG canvas.





<svg version="1.1" xmlns="http://www.w3.org/2000/svg"

width="400" height="200" viewBox="0 0 400 200">

<g transform="scale(1,-1) translate(0,-200)">

<rect x="50" y="0" fill="#f00" width="100" height="100">

<animate attributeName="height" from="0" to="100" dur="0.5s" fill="freeze" />

</rect>

<rect x="150" y="0" fill="#f70" width="100" height="200">

<animate attributeName="height" from="0" to="200" dur="0.5s" fill="freeze" />

</rect>

<rect x="250" y="0" fill="#ec0" width="100" height="150">

<animate attributeName="height" from="0" to="150" dur="0.5s" fill="freeze" />

</rect>

</g>

</svg>

Circle to rectangle transformation animation

If you want both the scaling up and corner radius reduction to happen at the same time, you can simplify the code from my other answer significantly.

You now no longer need to 'chain' the animations together, so you can add them both to a single CAAnimationGroup and run them concurrently.

The properties we use will remain almost identical, except with the addition of a groupAnim property and deletion of the cornerRadiusUndoAnim.

class ViewController2: UIViewController {

let animLayer = CALayer() // the layer that is going to be animated
let cornerRadiusAnim = CABasicAnimation(keyPath: "cornerRadius") // the corner radius reducing animation
let widthAnim = CABasicAnimation(keyPath: "bounds.size.width") // the width animation
let groupAnim = CAAnimationGroup() // the combination of the corner and width animation
let animDuration = NSTimeInterval(1.0) // the duration of one 'segment' of the animation
let layerSize = CGFloat(100) // the width & height of the layer (when it's a square)

...

We can now just add the setup for the CAAnimationGroup, adding both our corner radius animation and our scaling animation

override func viewDidLoad() {
super.viewDidLoad()

let rect = view.frame

animLayer.backgroundColor = UIColor.blueColor().CGColor // color of the layer, feel free to change
animLayer.frame = CGRect(x: rect.width-layerSize*0.5, y: rect.height-layerSize*0.5, width: layerSize, height: layerSize)
animLayer.cornerRadius = layerSize*0.5;
animLayer.anchorPoint = CGPoint(x: 1, y: 1) // sets so that when the width is changed, it goes to the left
view.layer.addSublayer(animLayer)

// decreases the corner radius
cornerRadiusAnim.duration = animDuration
cornerRadiusAnim.fromValue = animLayer.cornerRadius
cornerRadiusAnim.toValue = 0;
cornerRadiusAnim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) // timing function to make it look nice

// increases the width
widthAnim.duration = animDuration
widthAnim.fromValue = animLayer.frame.size.width
widthAnim.toValue = rect.size.width
widthAnim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) // timing function to make it look nice

// adds both animations to a group animation
groupAnim.animations = [cornerRadiusAnim, widthAnim]
groupAnim.duration = animDuration;
groupAnim.autoreverses = true; // auto-reverses the animation once completed

}

Finally, we can run the group animation when the view gets touched, and both animations will run concurrently together (and auto-reverse when done).

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
animLayer.addAnimation(groupAnim, forKey: "anims") // runs both animations concurrently
}

Result

Sample Image


Full project: https://github.com/hamishknight/Circle-to-Rect-Animation



Related Topics



Leave a reply



Submit