Module: Compass::Core::SassExtensions::Functions::GradientSupport::Functions
- Includes:
- Sass::Script::Value::Helpers
- Included in:
- LinearGradient, RadialGradient, Sass::Script::Functions
- Defined in:
- lib/compass/core/sass_extensions/functions/gradient_support.rb
Instance Method Summary collapse
- #_build_linear_gradient(position_or_angle, *color_stops) ⇒ Object
- #_linear_gradient(position_or_angle, *color_stops) ⇒ Object
- #_linear_gradient_legacy(position_or_angle, *color_stops) ⇒ Object
- #color_stops(*args) ⇒ Object
- #color_stops_in_percentages(color_list) ⇒ Object
- #convert_angle_from_offical(deg) ⇒ Object
-
#grad_color_stops(color_list) ⇒ Object
returns color-stop() calls for use in webkit.
-
#grad_end_position(color_list, radial = bool(false)) ⇒ Object
returns the end position of the gradient from the color stop.
-
#grad_point(position) ⇒ Object
given a position list, return a corresponding position in percents otherwise, returns the original argument.
- #grad_position(color_list, index, default, radial = bool(false)) ⇒ Object
-
#linear_end_position(position_or_angle, start_point, end_target) ⇒ Object
only used for webkit.
- #linear_svg_gradient(color_stops, start) ⇒ Object
- #radial_gradient(position_or_angle, shape_and_size, *color_stops) ⇒ Object
- #radial_svg_gradient(color_stops, center) ⇒ Object
- #reverse_side_or_corner(position) ⇒ Object
Instance Method Details
#_build_linear_gradient(position_or_angle, *color_stops) ⇒ Object
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 595 def _build_linear_gradient(position_or_angle, *color_stops) if color_stop?(position_or_angle) color_stops.unshift(position_or_angle) position_or_angle = nil elsif list_of_color_stops?(position_or_angle) color_stops = position_or_angle.value + color_stops position_or_angle = nil end position_or_angle = nil if position_or_angle && !position_or_angle.to_bool # Support legacy use of the color-stops() function if color_stops.size == 1 && (stops = list_of_color_stops?(color_stops.first)) color_stops = stops end return [position_or_angle, color_stops] end |
#_linear_gradient(position_or_angle, *color_stops) ⇒ Object
612 613 614 615 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 612 def _linear_gradient(position_or_angle, *color_stops) position_or_angle, color_stops = _build_linear_gradient(position_or_angle, *color_stops) LinearGradient.new(position_or_angle, send(:color_stops, *color_stops)) end |
#_linear_gradient_legacy(position_or_angle, *color_stops) ⇒ Object
617 618 619 620 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 617 def _linear_gradient_legacy(position_or_angle, *color_stops) position_or_angle, color_stops = _build_linear_gradient(position_or_angle, *color_stops) LinearGradient.new(position_or_angle, send(:color_stops, *color_stops), true) end |
#color_stops(*args) ⇒ Object
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 542 def color_stops(*args) opts(list(args.map do |arg| if ColorStop === arg arg elsif Sass::Script::Value::Color === arg ColorStop.new(arg) elsif Sass::Script::Value::List === arg ColorStop.new(*arg.value) elsif Sass::Script::Value::String === arg && arg.value == "transparent" ColorStop.new(arg) elsif Sass::Script::Value::String === arg && arg.value == "currentColor" ColorStop.new(arg) else raise Sass::SyntaxError, "Not a valid color stop: #{arg.class.name}: #{arg}" end end, :comma)) end |
#color_stops_in_percentages(color_list) ⇒ Object
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 630 def color_stops_in_percentages(color_list) assert_type color_list, :List color_list = normalize_stops(color_list) max = color_list.value.last.stop last_value = nil color_list.value.map do |pos| next [pos.stop, pos.color] if pos.stop.is_a?(Sass::Script::Value::String) # have to convert absolute units to percentages for use in color stop functions. stop = pos.stop stop = stop.div(max).times(number(100, "%")) if stop.numerator_units == max.numerator_units && max.numerator_units != ["%"] # Make sure the color stops are specified in the right order. if last_value && stop.numerator_units == last_value.numerator_units && stop.denominator_units == last_value.denominator_units && (stop.value * 1000).round < (last_value.value * 1000).round raise Sass::SyntaxError.new("Color stops must be specified in increasing order. #{stop.value} came after #{last_value.value}.") end last_value = stop [stop, pos.color] end end |
#convert_angle_from_offical(deg) ⇒ Object
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 481 def convert_angle_from_offical(deg) if deg.is_a?(Sass::Script::Value::Number) return number((deg.value.to_f - 450).abs % 360, 'deg') else args = deg.value direction = [] if args[0] == identifier('to') if args.size < 2 direction = args else direction << opposite_position(args[1]) end else direction << identifier('to') args.each do |pos| direction << opposite_position(pos) end end return opts(list(direction, :space)) end end |
#grad_color_stops(color_list) ⇒ Object
returns color-stop() calls for use in webkit.
623 624 625 626 627 628 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 623 def grad_color_stops(color_list) stops = color_stops_in_percentages(color_list).map do |stop, color| Sass::Script::String.new("color-stop(#{stop.to_s}, #{ColorStop.color_to_s(color)})") end opts(list(stops, :comma)) end |
#grad_end_position(color_list, radial = bool(false)) ⇒ Object
returns the end position of the gradient from the color stop
673 674 675 676 677 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 673 def grad_end_position(color_list, radial = bool(false)) assert_type color_list, :List default = number(100) grad_position(color_list, number(color_list.value.size), default, radial) end |
#grad_point(position) ⇒ Object
given a position list, return a corresponding position in percents otherwise, returns the original argument
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 505 def grad_point(position) original_value = position position = unless position.is_a?(Sass::Script::Value::List) opts(list([position], :space)) else opts(list(position.value.dup, position.separator)) end # Handle unknown arguments by passing them along untouched. unless position.value.all?{|p| is_position(p) } return original_value end if (position.value.first.value =~ /top|bottom/) or (position.value.last.value =~ /left|right/) # browsers are pretty forgiving of reversed positions so we are too. position = opts(list(position.value.reverse, position.separator)) end if position.value.size == 1 if position.value.first.value =~ /top|bottom/ position = opts(list(identifier("center"), position.value.first, position.separator)) elsif position.value.first.value =~ /left|right/ position = opts(list(position.value.first, identifier("center"), position.separator)) end end position = opts(list(position.value.map do |p| case p.value when /top|left/ number(0, "%") when /bottom|right/ number(100, "%") when /center/ number(50, "%") else p end end, position.separator)) position end |
#grad_position(color_list, index, default, radial = bool(false)) ⇒ Object
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 679 def grad_position(color_list, index, default, radial = bool(false)) assert_type color_list, :List stop = color_list.value[index.value - 1].stop if stop && radial.to_bool orig_stop = stop if stop.unitless? if stop.value <= 1 # A unitless number is assumed to be a percentage when it's between 0 and 1 stop = stop.times(number(100, "%")) else # Otherwise, a unitless number is assumed to be in pixels stop = stop.times(number(1, "px")) end end if stop.numerator_units == ["%"] && color_list.value.last.stop && color_list.value.last.stop.numerator_units == ["px"] stop = stop.times(color_list.value.last.stop).div(number(100, "%")) end Compass::Logger.new.record(:warning, "Webkit only supports pixels for the start and end stops for radial gradients. Got: #{orig_stop}") if stop.numerator_units != ["px"] stop.div(Sass::Script::Value::Number.new(1, stop.numerator_units, stop.denominator_units)) elsif stop stop else default end end |
#linear_end_position(position_or_angle, start_point, end_target) ⇒ Object
only used for webkit
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 650 def linear_end_position(position_or_angle, start_point, end_target) end_point = grad_point(opposite_position(position_or_angle)) if end_target && end_target.numerator_units == ["px"] if start_point.value.first == end_point.value.first && start_point.value.last.value == 0 # this means top-to-bottom new_end_point = end_point.value.dup new_end_point[1] = number(end_target.value) end_point = opts(list(new_end_point, end_point.separator)) elsif start_point.value.last == end_point.value.last && start_point.value.first.value == 0 # this implies left-to-right new_end_point = end_point.value.dup new_end_point[0] = number(end_target.value) end_point = opts(list(new_end_point, end_point.separator)) end end end_point end |
#linear_svg_gradient(color_stops, start) ⇒ Object
705 706 707 708 709 710 711 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 705 def linear_svg_gradient(color_stops, start) converter = CSS3AngleToSVGConverter.new(start) stops = color_stops_in_percentages(color_stops) svg = linear_svg(stops, converter.x1, converter.y1, converter.x2, converter.y2) inline_image_string(svg.gsub(/\s+/, ' '), 'image/svg+xml') end |
#radial_gradient(position_or_angle, shape_and_size, *color_stops) ⇒ Object
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 560 def radial_gradient(position_or_angle, shape_and_size, *color_stops) # Have to deal with variable length/meaning arguments. if color_stop?(shape_and_size) color_stops.unshift(shape_and_size) shape_and_size = nil elsif list_of_color_stops?(shape_and_size) # Support legacy use of the color-stops() function color_stops = shape_and_size.value + color_stops shape_and_size = nil end shape_and_size = nil if shape_and_size && !shape_and_size.to_bool # nil out explictly passed falses # ditto for position_or_angle if color_stop?(position_or_angle) color_stops.unshift(position_or_angle) position_or_angle = nil elsif list_of_color_stops?(position_or_angle) color_stops = position_or_angle.value + color_stops position_or_angle = nil end position_or_angle = nil if position_or_angle && !position_or_angle.to_bool # Support legacy use of the color-stops() function if color_stops.size == 1 && list_of_color_stops?(color_stops.first) color_stops = color_stops.first.value end if position_or_angle.is_a?(Sass::Script::Value::List) && (i = position_or_angle.value.index {|word| word.is_a?(Sass::Script::Value::String) && word.value == "at"}) shape_and_size = list(position_or_angle.value[0..(i-1)], :space) shape_and_size. = position_or_angle = list(position_or_angle.value[(i+1)..-1], :space) position_or_angle. = end RadialGradient.new(position_or_angle, shape_and_size, send(:color_stops, *color_stops)) end |
#radial_svg_gradient(color_stops, center) ⇒ Object
713 714 715 716 717 718 719 720 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 713 def radial_svg_gradient(color_stops, center) cx, cy = *grad_point(center).value r = grad_end_position(color_stops, bool(true)) stops = color_stops_in_percentages(color_stops) svg = radial_svg(stops, cx, cy, r) inline_image_string(svg.gsub(/\s+/, ' '), 'image/svg+xml') end |
#reverse_side_or_corner(position) ⇒ Object
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
# File 'lib/compass/core/sass_extensions/functions/gradient_support.rb', line 463 def reverse_side_or_corner(position) position_array = position.nil? ? [identifier('top')] : position.value.dup if position_array.first == identifier('to') # Remove the 'to' element from the array position_array.shift # Reverse all the positions reversed_position = position_array.map do |pos| opposite_position(pos) end else # When the position does not have the 'to' element we don't need to # reverse the direction of the gradient reversed_position = position_array end opts(list(reversed_position, :space)) end |