New background image mixin with gradient support and up to 10 images.
This commit is contained in:
parent
1fe22d7257
commit
9aea35738d
@ -1,6 +1,24 @@
|
||||
@import "shared";
|
||||
@import "compass/utilities/general/hacks";
|
||||
|
||||
@mixin background-image(
|
||||
$image-1, $image-2: false, $image-3: false,
|
||||
$image-4: false, $image-5: false, $image-6: false,
|
||||
$image-7: false, $image-8: false, $image-9: false, $image-10: false
|
||||
) {
|
||||
$images: compact($image-1, $image-2, $image-3, $image-4 ,$image-5, $image-6, $image-7, $image-8, $image-9, $image-10);
|
||||
@if $experimental-support-for-webkit and prefixed(-webkit, $images) {
|
||||
background-image: -webkit($images);
|
||||
}
|
||||
@if $experimental-support-for-mozilla and prefixed(-moz, $images) {
|
||||
background-image: -moz($images);
|
||||
}
|
||||
@if $experimental-support-for-svg and prefixed(-svg, $images) {
|
||||
background-image: -svg($images);
|
||||
}
|
||||
background-image: $images;
|
||||
}
|
||||
|
||||
// The linear gradient mixin works best across browsers if you use percentage-based color stops.
|
||||
//
|
||||
// Examples:
|
||||
@ -50,7 +68,7 @@
|
||||
@if $experimental-support-for-mozilla {
|
||||
background-image: #{$background}-moz-linear-gradient($start, $color-stops);
|
||||
}
|
||||
background-image: #{$background}linear-gradient($start, $color-stops);
|
||||
background-image: #{$background}#{linear}-gradient($start, $color-stops);
|
||||
}
|
||||
|
||||
// Emit a IE-Specific filters that renders a simple linear gradient.
|
||||
@ -104,5 +122,5 @@
|
||||
@if $experimental-support-for-mozilla {
|
||||
background-image: #{$background}-moz-radial-gradient($center-position, circle, $color-stops);
|
||||
}
|
||||
background-image: #{$background}radial-gradient($center-position, circle, $color-stops);
|
||||
background-image: #{$background}#{radial}-gradient($center-position, circle, $color-stops);
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ end
|
||||
|
||||
%w(
|
||||
selectors enumerate urls display if
|
||||
inline_image image_size gradient_support
|
||||
font_files constants lists colors trig
|
||||
inline_image image_size constants gradient_support
|
||||
font_files lists colors trig
|
||||
).each do |func|
|
||||
require "compass/sass_extensions/functions/#{func}"
|
||||
end
|
||||
|
@ -9,13 +9,16 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
values.map{|v| v.inspect}.join(", ")
|
||||
end
|
||||
def to_s
|
||||
inspect
|
||||
values.map{|v| v.to_s}.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
class ColorStop < Sass::Script::Literal
|
||||
attr_accessor :color, :stop
|
||||
def initialize(color, stop = nil)
|
||||
unless Sass::Script::Color === color || Sass::Script::Funcall === color
|
||||
raise Sass::SyntaxError, "Expected a color. Got: #{color}"
|
||||
end
|
||||
self.color, self.stop = color, stop
|
||||
end
|
||||
def inspect
|
||||
@ -35,7 +38,103 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
end
|
||||
end
|
||||
|
||||
class RadialGradient < Sass::Script::Literal
|
||||
attr_accessor :position_or_angle, :shape_or_size, :color_stops
|
||||
def initialize(position_or_angle, shape_or_size, color_stops)
|
||||
unless color_stops.values.size >= 2
|
||||
raise Sass::SyntaxError, "At least two color stops are required for a radial-gradient"
|
||||
end
|
||||
self.position_or_angle = position_or_angle
|
||||
self.shape_or_size = shape_or_size
|
||||
self.color_stops = color_stops
|
||||
end
|
||||
def inspect
|
||||
to_s
|
||||
end
|
||||
def to_s
|
||||
s = "radial-gradient("
|
||||
s << position_or_angle.to_s << ", " if position_or_angle
|
||||
s << shape_or_size.to_s << ", " if shape_or_size
|
||||
s << color_stops.to_s
|
||||
s << ")"
|
||||
end
|
||||
def to_webkit
|
||||
args = [
|
||||
grad_point(position_or_angle),
|
||||
"0",
|
||||
grad_point(position_or_angle),
|
||||
grad_end_position(color_stops, Sass::Script::Bool.new(true)),
|
||||
grad_color_stops(color_stops)
|
||||
]
|
||||
Sass::Script::String.new("-webkit-gradient(radial, #{args.join(', ')})")
|
||||
|
||||
end
|
||||
def to_moz
|
||||
Sass::Script::String.new("-moz-#{to_s}")
|
||||
end
|
||||
def to_svg
|
||||
# XXX Add shape support if possible
|
||||
radial_svg_gradient(color_stops, position_or_angle)
|
||||
end
|
||||
end
|
||||
|
||||
class LinearGradient < Sass::Script::Literal
|
||||
attr_accessor :color_stops, :position_or_angle
|
||||
def initialize(position_or_angle, color_stops)
|
||||
unless color_stops.values.size >= 2
|
||||
raise Sass::SyntaxError, "At least two color stops are required for a linear-gradient"
|
||||
end
|
||||
self.position_or_angle = position_or_angle
|
||||
self.color_stops = color_stops
|
||||
end
|
||||
def inspect
|
||||
to_s
|
||||
end
|
||||
def to_s
|
||||
s = "linear-gradient("
|
||||
s << position_or_angle.to_s << ", " if position_or_angle
|
||||
s << color_stops.to_s
|
||||
s << ")"
|
||||
end
|
||||
def to_webkit
|
||||
args = [
|
||||
grad_point(position_or_angle),
|
||||
grad_point(opposite_position(position_or_angle)),
|
||||
grad_color_stops(color_stops)
|
||||
]
|
||||
Sass::Script::String.new("-webkit-gradient(linear, #{args.join(', ')})")
|
||||
end
|
||||
def to_moz
|
||||
Sass::Script::String.new("-moz-#{to_s}")
|
||||
end
|
||||
def to_svg
|
||||
linear_svg_gradient(color_stops, position_or_angle)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module Functions
|
||||
|
||||
def radial_gradient(position_or_angle, shape_or_size, *color_stops)
|
||||
if color_stop?(shape_or_size)
|
||||
color_stops.unshift(shape_or_size)
|
||||
shape_or_size = nil
|
||||
end
|
||||
if color_stop?(position_or_angle)
|
||||
color_stops.unshift(position_or_angle)
|
||||
position_or_angle = nil
|
||||
end
|
||||
RadialGradient.new(position_or_angle, shape_or_size, send(:color_stops, *color_stops))
|
||||
end
|
||||
|
||||
def linear_gradient(position_or_angle, *color_stops)
|
||||
if color_stop?(position_or_angle)
|
||||
color_stops.unshift(position_or_angle)
|
||||
position_or_angle = nil
|
||||
end
|
||||
LinearGradient.new(position_or_angle, send(:color_stops, *color_stops))
|
||||
end
|
||||
|
||||
# returns color-stop() calls for use in webkit.
|
||||
def grad_color_stops(color_list)
|
||||
stops = color_stops_in_percentages(color_list).map do |stop, color|
|
||||
@ -132,24 +231,7 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
when Sass::Script::String
|
||||
# We get a string as the result of concatenation
|
||||
# So we have to reparse the expression
|
||||
color = stop = nil
|
||||
expr = Sass::Script::Parser.parse(arg.value, 0, 0)
|
||||
case expr
|
||||
when Sass::Script::Color
|
||||
color = expr
|
||||
when Sass::Script::Funcall
|
||||
color = expr
|
||||
when Sass::Script::Operation
|
||||
unless expr.instance_variable_get("@operator") == :concat
|
||||
# This should never happen.
|
||||
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
||||
end
|
||||
color = expr.instance_variable_get("@operand1")
|
||||
stop = expr.instance_variable_get("@operand2")
|
||||
else
|
||||
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
||||
end
|
||||
ColorStop.new(color, stop)
|
||||
parse_color_stop(arg)
|
||||
else
|
||||
raise Sass::SyntaxError, "Not a valid color stop: #{arg}"
|
||||
end
|
||||
@ -174,6 +256,26 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
inline_image_string(svg.gsub(/\s+/, ' '), 'image/svg+xml')
|
||||
end
|
||||
|
||||
# Returns a comma-delimited list after removing any non-true values
|
||||
def compact(*args)
|
||||
List.new(*args.reject{|a| !a.to_bool})
|
||||
end
|
||||
|
||||
%w(webkit moz o ms svg).each do |prefix|
|
||||
class_eval <<-RUBY
|
||||
def _#{prefix}(*args)
|
||||
args.map!{|a| a.is_a?(List) ? a.values : a}.flatten!
|
||||
List.new(*args.map!{|a| a.respond_to?(:to_#{prefix}) ? a.to_#{prefix} : a})
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def prefixed(prefix, *args)
|
||||
method = prefix.value.sub(/^-/,"to_").to_sym
|
||||
args.map!{|a| a.is_a?(List) ? a.values : a}.flatten!
|
||||
Sass::Script::Bool.new(args.any?{|a| a.respond_to?(method)})
|
||||
end
|
||||
|
||||
private
|
||||
def normalize_stops!(color_list)
|
||||
positions = color_list.values
|
||||
@ -208,11 +310,41 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def assert_list(value)
|
||||
return if value.is_a?(List)
|
||||
raise ArgumentError.new("#{value.inspect} is not a list of color stops. Expected: color_stops(<color> <number>?, ...)")
|
||||
end
|
||||
|
||||
def parse_color_stop(arg)
|
||||
return ColorStop.new(arg) if arg.is_a?(Sass::Script::Color)
|
||||
return nil unless arg.is_a?(Sass::Script::String)
|
||||
color = stop = nil
|
||||
expr = Sass::Script::Parser.parse(arg.value, 0, 0)
|
||||
case expr
|
||||
when Sass::Script::Color
|
||||
color = expr
|
||||
when Sass::Script::Funcall
|
||||
color = expr
|
||||
when Sass::Script::Operation
|
||||
unless [:concat, :space].include?(expr.instance_variable_get("@operator"))
|
||||
# This should never happen.
|
||||
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
||||
end
|
||||
color = expr.instance_variable_get("@operand1")
|
||||
stop = expr.instance_variable_get("@operand2")
|
||||
else
|
||||
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
||||
end
|
||||
ColorStop.new(color, stop)
|
||||
end
|
||||
|
||||
def color_stop?(arg)
|
||||
parse_color_stop(arg)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
def linear_svg(color_stops, x1, y1, x2, y2)
|
||||
gradient = <<-EOG
|
||||
<linearGradient id="grad" x1="#{x1}" y1="#{y1}" x2="#{x2}" y2="#{y2}">
|
||||
@ -248,4 +380,14 @@ module Compass::SassExtensions::Functions::GradientSupport
|
||||
EOS
|
||||
end
|
||||
end
|
||||
class LinearGradient < Sass::Script::Literal
|
||||
include Functions
|
||||
include Compass::SassExtensions::Functions::Constants
|
||||
include Compass::SassExtensions::Functions::InlineImage
|
||||
end
|
||||
class RadialGradient < Sass::Script::Literal
|
||||
include Functions
|
||||
include Compass::SassExtensions::Functions::Constants
|
||||
include Compass::SassExtensions::Functions::InlineImage
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,8 @@
|
||||
require 'test_helper'
|
||||
require 'fileutils'
|
||||
require 'compass'
|
||||
require 'compass/logger'
|
||||
require 'sass/plugin'
|
||||
|
||||
class CompassTest < Test::Unit::TestCase
|
||||
include Compass::TestCaseHelper
|
||||
|
@ -1,3 +1,24 @@
|
||||
.bg-simple-image {
|
||||
background-image: url("foo.png"); }
|
||||
|
||||
.bg-linear-gradient {
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
|
||||
background-image: -moz-linear-gradient(top left, #dddddd 0%, #aaaaaa 100%);
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8bGluZWFyR3JhZGllbnQgaWQ9ImdyYWQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9saW5lYXJHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
|
||||
background-image: linear-gradient(top left, #dddddd 0%, #aaaaaa 100%); }
|
||||
|
||||
.bg-radial-gradient {
|
||||
background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
|
||||
background-image: -moz-radial-gradient(center center, #dddddd 0%, #aaaaaa 100px);
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjeD0iNTAlIiBjeT0iNTAlIiByPSIxMDAiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9yYWRpYWxHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
|
||||
background-image: radial-gradient(center center, #dddddd 0%, #aaaaaa 100px); }
|
||||
|
||||
.bg-all-gradient-types {
|
||||
background-image: url('/images/4x6.png?busted=true'), -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa)), -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
|
||||
background-image: url('/images/4x6.png?busted=true'), -moz-linear-gradient(top left, #dddddd 0%, #aaaaaa 100%), -moz-radial-gradient(center center, #dddddd 0%, #aaaaaa 100px);
|
||||
background-image: url('/images/4x6.png?busted=true'), url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8bGluZWFyR3JhZGllbnQgaWQ9ImdyYWQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9saW5lYXJHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g'), url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjeD0iNTAlIiBjeT0iNTAlIiByPSIxMDAiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9yYWRpYWxHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
|
||||
background-image: url('/images/4x6.png?busted=true'), linear-gradient(top left, #dddddd 0%, #aaaaaa 100%), radial-gradient(center center, #dddddd 0%, #aaaaaa 100px); }
|
||||
|
||||
.linear-1 {
|
||||
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
|
||||
background-image: -moz-linear-gradient(top, #dddddd 0%, #aaaaaa 100%);
|
||||
|
@ -1,5 +1,18 @@
|
||||
@import compass/css3
|
||||
|
||||
$experimental-support-for-svg: true
|
||||
.bg-simple-image
|
||||
+background-image(url('foo.png'))
|
||||
|
||||
.bg-linear-gradient
|
||||
+background-image(linear-gradient(top left, #ddd, #aaa))
|
||||
|
||||
.bg-radial-gradient
|
||||
+background-image(radial-gradient(center center, #ddd, #aaa 100px))
|
||||
|
||||
.bg-all-gradient-types
|
||||
+background-image(image-url("4x6.png"), linear-gradient(top left, #ddd, #aaa), radial-gradient(center center, #ddd, #aaa 100px))
|
||||
$experimental-support-for-svg: false
|
||||
.linear-1
|
||||
+linear-gradient(color-stops(#dddddd, #aaaaaa))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user