2d and 3d transforms, version 2, closes 170

This commit is contained in:
Eric Meyer 2010-11-08 23:36:45 -07:00 committed by Chris Eppstein
parent 290aac3a7e
commit 782e6979ea

View File

@ -0,0 +1,546 @@
@import "shared";
// Note ----------------------------------------------------------------------
// Safari is the only browser that currently supports 3D transforms.
// Because of that it can be important to control whether a given 2D transform
// uses the full range of experimental browser prefixes, or only the 3D list.
// To make that easy, all 2D transforms include an browser-targeting toggle ($only3d)
// to switch between the two support lists. The toggle defaults to 'false' (2D),
// and also accepts 'true' (3D). Currently the lists are as follows:
// 2D: Mozilla, Webkit, Opera, Official
// 3D: Webkit, Official **(Only Safari Supports 3D perspective)**
// Available Transforms ------------------------------------------------------
// - Scale (2d and 3d)
// - Rotate (2d and 3d)
// - Translate (2d and 3d)
// - Skew (2d only)
// Transform Parameters ------------------------------------------------------
// - Transform Origin (2d and 3d)
// - Perspective (3d)
// - Perspective Origin (3d)
// - Transform Style (3d)
// - Backface Visibility (3d)
// Mixins --------------------------------------------------------------------
// transform-origin
// - shortcuts: transform-origin2d, transform-origin3d
// - helpers: apply-origin
// transform
// - shortcuts: transform2d, transform3d
// - helpers: simple-transform, create-transform
// perspective
// - helpers: perspective-origin
// transform-style
// backface-visibility
// scale
// - shortcuts: scaleX, scaleY, scaleZ, scale3d
// rotate
// - shortcuts: rotateX, rotateY, rotate3d
// translate
// - shortcuts: translateX, translateY, translateZ, translate3d
// skew
// - shortcuts: skewX, skewY
// Defaults ------------------------------------------------------------------
// Transform Origin
$default-originx : 50% !default;
$default-originy : 50% !default;
$default-originz : 50% !default;
// Scale
$default-scalex : 1.25 !default;
$default-scaley : $default-scalex !default;
$default-scalez : $default-scalex !default;
// Rotate
$default-rotate : 45deg !default;
// Rotate3d
$default-vectorx : 1 !default;
$default-vectory : 1 !default;
$default-vectorz : 1 !default;
// Translate
$default-transx : 1em !default;
$default-transy : $default-transx !default;
$default-transz : $default-transx !default;
// Skew
$default-skewx : 5deg !default;
$default-skewy : 5deg !default;
// Transform-origin ----------------------------------------------------------
// Transform-origin sent as a complete string
// @include apply-origin( origin [, 3D-only ] )
// where 'origin' is a string containing 1-3 (x/y/z) coordinates
// in percentages, absolute (px, cm, in, em etc..) or relative (left, top, right, bottom, center) units
@mixin apply-origin(
$origin,
$only3d: false
) {
@if $only3d {
@include experimental(transform-origin, $origin,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
} @else {
@include experimental(transform-origin, $origin,
-moz, -webkit, -o, not -ms, not -khtml, official
);
}
}
// Transform-origin sent as individual arguments
// @include transform-origin( [ origin-x, origin-y, origin-z, 3D-only ] )
// where the 3 'origin-' arguments represent x/y/z coordinates
// ** setting z coordinates triggers 3D support list, leave false for 2D support
@mixin transform-origin(
$originx: $default-originx,
$originy: $default-originy,
$originz: false,
$only3d: $originz
) {
$origin: unquote('');
@if $originx or $originy or $originz {
@if $originx { $origin: $originx; } @else { $origin: 50%; }
@if $originy { $origin: $origin $originy; } @else { @if $originz { $origin: $origin 50%; }}
@if $originz { $origin: $origin $originz; $only3d: true; }
@include apply-origin($origin, $only3d);
}
}
// Shortcut to target all browsers with 2D transform support
// @include transform-origin( [ origin-x, origin-y ] )
@mixin transform-origin2d(
$originx: $default-originx,
$originy: $default-originy
) {
@include transform-origin($originx, $originy);
}
// Shortcut to target all browsers with 3D transform support
// @include transform-origin( [ origin-x, origin-y, origin-z ] )
@mixin transform-origin3d(
$originx: $default-originx,
$originy: $default-originy,
$originz: $default-originz
) {
@include transform-origin($originx, $originy, $originz, true);
}
// Transform -----------------------------------------------------------------
// Transform sent as a complete string
// @include transform( transforms [, 3D-only ] )
// where 'transforms' is a string of all the transforms to be applied
@mixin transform(
$transform,
$only3d: false
) {
@if $only3d {
@include experimental(transform, $transform,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
} @else {
@include experimental(transform, $transform,
-moz, -webkit, -o, not -ms, not -khtml, official
);
}
}
// Shortcut to target all browsers with 2D transform support
@mixin transform2d($trans) {
@include transform($trans, false);
}
// Shortcut to target only browsers with 3D transform support
@mixin transform3d($trans) {
@include transform($trans, true);
}
// 3D Parameters -------------------------------------------------------------
// Set the perspective of 3D transforms on the children of an element
// @include perspective( perspective )
// where 'perspective' is a uniless number representing the depth of the z-axis
// the higher the perspective, the more exagerated the foreshortening.
// values from 500 to 1000 are more-or-less "normal" - a good starting-point.
@mixin perspective($p) {
@include experimental(perspective, $p,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
}
// Set the origin position for the perspective
// @include perspective-origin( [ origin-x, origin-y ] )
// where the two arguments represent x/y coordinates
@mixin perspective-origin(
$originx: 50%,
$originy: false
) {
$po: $originx;
@if $originy { $po: $po $originy; }
@include experimental(perspective-origin, $po,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
}
// Determine whether a 3D objects children also live in the given 3D space
// @include transform-style( [ style ] )
// where 'style' can be either 'flat' or 'preserves-3d'
// browsers default to flat, mixin defaults to preserves-3d
@mixin transform-style($ts: unquote("preserves-3d")) {
@include experimental(perspective-origin, $ts,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
}
// Determine the visibility of an element when it's back is turned
// @include backface-visibility( [ visibility ] )
// where 'visibility can be either 'visible' or 'hidden'
// browsers default to visible, mixin defaults to hidden
@mixin backface-visibility($bv: unquote("hidden")) {
@include experimental(backface-visibility, $bv,
not -moz, -webkit, not -o, not -ms, not -khtml, official
);
}
// Transform Partials --------------------------------------------------------
// These work well on their own, but they don't add to each other, they override.
// Use along with transform parameter mixins to adjust origin, perspective and style
// ---------------------------------------------------------------------------
// Scale ---------------------------------------------------------------------
// Scale an object along the x and y axis
// @include scale( [ scale-x, scale-y, perspective, 3D-only ] )
// where the 'scale-' arguments are unitless multipliers of the x and y dimensions
// and perspective, which works the same as the stand-alone perspective property/mixin
// but applies to the individual element (multiplied with any parent perspective)
@mixin scale(
$scalex: $default-scalex,
$scaley: $scalex,
$perspective: false,
$only3d: false
) {
$trans: scale($scalex, $scaley);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Scale an object along the x axis
// @include scaleX( [ scale-x, perspective, 3D-only ] )
@mixin scaleX(
$scale: $default-scalex,
$perspective: false,
$only3d: false
) {
$trans: scaleX($scale);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Scale an object along the y axis
// @include scaleY( [ scale-y, perspective, 3D-only ] )
@mixin scaleY(
$scale: $default-scaley,
$perspective: false,
$only3d: false
) {
$trans: scaleY($scale);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Scale an object along the z axis
// @include scaleZ( [ scale-z, perspective ] )
@mixin scaleZ(
$scale: $default-scalez,
$perspective: false
) {
$trans: scaleZ($scale);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Scale and object along all three axis
// @include scale3d( [ scale-x, scale-y, scale-z, perspective ] )
@mixin scale3d(
$scalex: $default-scalex,
$scaley: $default-scaley,
$scalez: $default-scalez,
$perspective: false
) {
$trans: scale3d($scalex, $scaley, $scalez);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Rotate --------------------------------------------------------------------
// Rotate an object around the z axis (2D)
// @include rotate( [ rotation, perspective, 3D-only ] )
// where 'rotation' is an angle set in degrees (deg) or radian (rad) units
@mixin rotate(
$rotate: $default-rotate,
$perspective: false,
$only3d: false
) {
$trans: rotate($rotate);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// A longcut for 'rotate' in case you forget that 'z' is implied
@mixin rotateZ(
$rotate: $default-rotate,
$perspective: false,
$only3d: false
) {
@include rotate($rotate, $perspective, $only3d);
}
// Rotate an object around the x axis (3D)
// @include rotateX( [ rotation, perspective ] )
@mixin rotateX(
$rotate: $default-rotate,
$perspective: false
) {
$trans: rotateX($rotate);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Rotate an object around the y axis (3D)
// @include rotate( [ rotation, perspective ] )
@mixin rotateY(
$rotate: $default-rotate,
$perspective: false
) {
$trans: rotateY($rotate);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Rotate an object around an arbitrary axis (3D)
// @include rotate( [ vector-x, vector-y, vector-z, rotation, perspective ] )
// where the 'vector-' arguments accept unitless numbers
// these numbers are not important on their own, but in relation to one another
// creating an axis from your transform-origin, along the axis of Xx = Yy = Zz
@mixin rotate3d(
$vectorx: $default-vectorx,
$vectory: $default-vectory,
$vectorz: $default-vectorz,
$rotate: $default-rotate,
$perspective: false
) {
$trans: rotate3d($vectorx, $vectory, $vectorz, $rotate);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Translate -----------------------------------------------------------------
// Move an object along the x or y axis (2D)
// @include translate( [ translate-x, translate-y, perspective, 3D-only ] )
// where the 'translate-' arguments accept any distance in percentages or absolute (px, cm, in, em etc..) units
@mixin translate(
$transx: $default-transx,
$transy: $default-transy,
$perspective: false,
$only3d: false
) {
$trans: translate($transx, $transy);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Move an object along the x axis (2D)
// @include translate( [ translate-x, perspective, 3D-only ] )
@mixin translateX(
$transx: $default-transx,
$perspective: false,
$only3d: false
) {
$trans: translateX($transx);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Move an object along the y axis (2D)
// @include translate( [ translate-y, perspective, 3D-only ] )
@mixin translateY(
$transy: $default-transy,
$perspective: false,
$only3d: false
) {
$trans: translateY($transy);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform($trans, $only3d);
}
// Move an object along the z axis (3D)
// @include translate( [ translate-z, perspective ] )
@mixin translateZ(
$transz: $default-transz,
$perspective: false
) {
$trans: translateZ($transz);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Move an object along the x, y and z axis (3D)
// @include translate( [ translate-x, translate-y, translate-z, perspective ] )
@mixin translate3d(
$transx: $default-transx,
$transy: $default-transy,
$transz: $default-transz,
$perspective: false
) {
$trans: translate3d($transx, $transy, $transz);
@if $perspective { $trans: perspective($perspective) $trans; }
@include transform3d($trans);
}
// Skew ----------------------------------------------------------------------
// Skew an element
// @include skew( [ skew-x, skew-y, 3D-only ] )
// where the 'skew-' arguments accept css angles in degrees (deg) or radian (rad) units
@mixin skew(
$skewx: $default-skewx,
$skewy: $default-skewy,
$only3d: false
) {
$trans: skew($skewx, $skewy);
@include transform($trans, $only3d);
}
// Skew an element along the x axiz
// @include skew( [ skew-x, 3D-only ] )
@mixin skewX(
$skewx: $default-skewx,
$only3d: false
) {
$trans: skewX($skewx);
@include transform($trans, $only3d);
}
// Skew an element along the y axis
// @include skew( [ skew-y, 3D-only ] )
@mixin skewY(
$skewy: $default-skewy,
$only3d: false
) {
$trans: skewY($skewy);
@include transform($trans, $only3d);
}
// Full transform mixins -----------------------------------------------------
// For settings any combination of transforms as arguments
// These are complex and not highly recommended for daily use
// They are mainly here for backwards-compatability purposes
// * they include origin adjustments
// * scale takes a multiplier (unitless), rotate and skew take degrees (deg)
// ---------------------------------------------------------------------------
// The full list of options
@mixin create-transform(
$perspective: false,
$scalex: false,
$scaley: false,
$scalez: false,
$rotatex: false,
$rotatey: false,
$rotatez: false,
$rotate3d: false,
$transx: false,
$transy: false,
$transz: false,
$skewx: false,
$skewy: false,
$originx: false,
$originy: false,
$originz: false,
$only3d: false
) {
$trans: unquote("");
// perspective
@if $perspective { $trans: perspective($perspective) ; }
// scale
@if $scalex and $scaley {
@if $scalez { $trans: $trans scale3d($scalex, $scaley, $scalez); }
@else { $trans: $trans scale($scalex, $scaley); }
} @else {
@if $scalex { $trans: $trans scaleX($scalex); }
@if $scaley { $trans: $trans scaleY($scaley); }
@if $scalez { $trans: $trans scaleZ($scalez); }
}
// rotate
@if $rotatex { $trans: $trans rotateX($rotatex); }
@if $rotatey { $trans: $trans rotateY($rotatey); }
@if $rotatez { $trans: $trans rotate($rotatez); }
@if $rotate3d { $trans: $trans rotate3d($rotate3d); }
// translate
@if $transx and $transy {
@if $transz { $trans: $trans translate3d($transx, $transy, $transz); }
@else { $trans: $trans translate($transx, $transy); }
} @else {
@if $transx { $trans: $trans translateX($transx); }
@if $transy { $trans: $trans translateY($transy); }
@if $transz { $trans: $trans translateZ($transz); }
}
// skew
@if $skewx and $skewy { $trans: $trans skew($skewx, $skewy); }
@else {
@if $skewx { $trans: $trans skewX($skewx); }
@if $skewy { $trans: $trans skewY($skewy); }
}
// apply it!
@include transform($trans, $only3d);
@include transform-origin($originx, $originy, $originz, $only3d);
}
// A simplified set of options
// backwards-compatible with the previous version of the 'transform' mixin
@mixin simple-transform(
$scale: false,
$rotate: false,
$transx: false,
$transy: false,
$skewx: false,
$skewy: false,
$originx: false,
$originy: false
) {
@include compact-transform(
false,
$scale, $scale, false,
false, false, $rotate, false,
$transx, $transy, false,
$skewx, $skewy,
$originx, $originy, false,
false
);
}