Permalink
Browse files

Add preliminary support for rgba opacity in simple 2-stop linear grad…

…ients. Enhance VmlShape abstract away the shape regeneration from markup when o:opacity2 is changed.
  • Loading branch information...
1 parent 47dc9d8 commit 7e028235f2c9b5f2aa7baa910acc11ce9058b96f Jason Johnston committed Nov 13, 2011
Showing with 72 additions and 23 deletions.
  1. +9 −0 sources/BackgroundRenderer.js
  2. +2 −14 sources/BoxShadowOutsetRenderer.js
  3. +22 −9 sources/VmlShape.js
  4. +39 −0 tests/gradient-tests.html
View
9 sources/BackgroundRenderer.js
@@ -292,6 +292,15 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
'color2', stops[stopCount - 1].color.colorValue( el ),
'colors', vmlColors.join( ',' )
);
+
+ // Set opacity; right now we only support this for two-stop gradients, multi-stop
+ // opacity will require chopping up each segment into its own shape.
+ if ( stopCount === 2 ) {
+ shape.setFillAttrs(
+ 'opacity', stops[0].color.alpha(),
+ 'o:opacity2', stops[1].color.alpha()
+ );
+ }
},
View
16 sources/BoxShadowOutsetRenderer.js
@@ -71,25 +71,13 @@ PIE.BoxShadowOutsetRenderer = PIE.RendererBase.newRenderer( {
alpha *= focusAdjustRatio * focusAdjustRatio; //this is a rough eyeball-adjustment, could be refined
}
- // Inner focus opacity: VML does not allow opacity2 to be modified via the VML DOM,
- // so we must trigger regeneration of the VML shape via markup.
- if ( alpha !== shape.lastOpacity2 ) {
- if( shape.getShape() ) {
- me.deleteShape( 'shadow' + i );
- shape = me.getShape( 'shadow' + i, me.shapeZIndex + ( .5 - i / 1000 ) );
- }
- if( alpha < 1 ) {
- shape.setFillAttrs( 'o:opacity2', alpha );
- }
- shape.lastOpacity2 = alpha;
- }
-
shape.setFillAttrs(
'type', 'gradienttitle', //makes the VML gradient follow the shape's outline - hooray for undocumented features?!?!
'color2', color,
'focusposition', focusX + ',' + focusY,
'focussize', ( 1 - focusX * 2 ) + ',' + ( 1 - focusY * 2 ),
- 'opacity', 0
+ 'opacity', 0,
+ 'o:opacity2', alpha
);
} else {
shape.setFillAttrs(
View
31 sources/VmlShape.js
@@ -22,21 +22,39 @@ PIE.VmlShape = (function() {
fill[ name ][ 'x' ] = 1; //Can be any value, just has to be set to "prime" it so the next line works. Weird!
fill[ name ] = value;
}
+ },
+
+ 'o:opacity2': function( fill, name, value ) {
+ // The VML DOM does not allow dynamic setting of o:opacity2, so we must regenerate
+ // the entire shape from markup instead.
+ var me = this;
+ if( value !== me.lastOpacity2 ) {
+ me.getShape().insertAdjacentHTML( 'afterEnd', me.getMarkup() );
+ me.destroy();
+ me.lastOpacity2 = value;
+ }
}
};
function createSetter( objName ) {
return function() {
var args = arguments,
- i = 0, len = args.length,
- obj = this.getShape(),
- name, setter;
+ i, len = args.length,
+ obj, name, setter;
+ // Store the property locally
+ obj = this[ attrsPrefix + objName ] || ( this[ attrsPrefix + objName ] = {} );
+ for( i = 0; i < len; i += 2 ) {
+ obj[ args[ i ] ] = args[ i + 1 ];
+ }
+
+ // If there is a rendered VML shape already, set the property directly via the VML DOM
+ obj = this.getShape();
if( obj ) {
if( objName ) {
obj = obj[ objName ];
}
- for( ; i < len; i += 2 ) {
+ for( i = 0; i < len; i += 2 ) {
name = args[ i ];
setter = objectSetters[ name ]; //if there is a custom setter for this property, use it
if ( setter ) {
@@ -45,11 +63,6 @@ PIE.VmlShape = (function() {
obj[ name ] = args[ i + 1 ];
}
}
- } else {
- obj = this[ attrsPrefix + objName ] || ( this[ attrsPrefix + objName ] = {} );
- for( ; i < len; i += 2 ) {
- obj[ args[ i ] ] = args[ i + 1 ];
- }
}
}
}
View
39 tests/gradient-tests.html
@@ -184,6 +184,39 @@
}
+ #opacity {
+ background: url(background2.gif);
+ }
+ #opacity1 {
+ background: -webkit-linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2));
+ background: -moz-linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2));
+ background: -ms-linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2));
+ background: -o-linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2));
+ -pie-background: linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2));
+ }
+ #opacity1:hover {
+ background: -webkit-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 0.8));
+ background: -moz-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 0.8));
+ background: -ms-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 0.8));
+ background: -o-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 0.8));
+ -pie-background: linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 0.8));
+ }
+ #opacity2 {
+ background: -webkit-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -moz-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -ms-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -o-linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ -pie-background: linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ }
+ #opacity2:hover {
+ background: -webkit-linear-gradient(left, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -moz-linear-gradient(left, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -ms-linear-gradient(left, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ background: -o-linear-gradient(left, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ -pie-background: linear-gradient(left, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1));
+ }
+
+
</style>
</head>
<body>
@@ -235,5 +268,11 @@
<p id="lineup2">element 2</p>
</div>
+ <div class="section" id="opacity">
+ <h1>Color-stop opacity</h1>
+ <p id="opacity1">linear-gradient(top, rgba(0, 0, 255, 1), rgba(0, 0, 255, 0.2))</p>
+ <p id="opacity2">linear-gradient(top, rgba(0, 0, 255, 0.2), rgba(0, 0, 255, 1))</p>
+ </div>
+
</body>
</html>

0 comments on commit 7e02823

Please sign in to comment.