Sass file to set cross browser background gradient
@mixin gradient($color1, $color2, $dir : "h", $height: 100){ | |
$webkit: right top; | |
$others: left; | |
$repeat: repeat-y; | |
@if ($dir == "horz") or ($dir == "h") or ($dir == "horizontal") { | |
$webkit: left bottom; | |
$others: top; | |
$repeat: repeat-x; | |
} | |
$url: "path/to/gradient.php" | |
+ "?c1=" + red($color1) + "," + green($color1) + "," + blue($color1) | |
+ "&c2=" + red($color2) + "," + green($color2) + "," + blue($color2) | |
+ "&height="+ $height | |
+ "&direction=" + $dir | |
+ "&output="; | |
background: url($url + "svg") $repeat; | |
*background: url($url + "png") $repeat; | |
background: -webkit-gradient(linear, left top, $webkit, from($color1), to($color2)); | |
background: -moz-linear-gradient($others, $color1, $color2); | |
background: -ms-linear-gradient($others, $color1, $color2); | |
background: linear-gradient($others, $color1, $color2); | |
background-image:-o-linear-gradient($others, $color1, $color2); | |
} | |
@mixin hgradient($color1, $color2, $height: 100){ | |
@include gradient($color1, $color2, "h", $height); | |
} | |
@mixin vgradient($color1, $color2, $height: 100){ | |
@include gradient($color1, $color2, "v", $height); | |
} | |
<?php | |
$c1 = $_REQUEST['c1']; | |
$c2 = $_REQUEST['c2']; | |
$output = strtolower($_REQUEST['output']); | |
$direction = strtolower($_REQUEST['direction']); | |
$is_horz = substr($direction, 0, 1) == 'h'; | |
$size = (int) $_REQUEST['height']; | |
if (empty($c1)) { | |
$c1 = 1; | |
} | |
if (empty($c2)) { | |
$c2 = 1; | |
} | |
header('Pragma: public'); | |
header('Cache-Control: max-age=' . (120 * 3600)); | |
header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime('-1month'))); | |
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime('+3months'))); | |
switch($output){ | |
case 'svg' : | |
case 'xml' : outputXML($c1, $c2, $is_horz); break; | |
default : outputBitmap($c1, $c2, $is_horz, $size, $output); | |
}//switch - output | |
exit; | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
function outputXML($c1, $c2, $is_horz = TRUE){ | |
header('Content-Type: image/svg+xml'); | |
$xml = <<<XML | |
<?xml version="1.0" encoding="utf-8"?> | |
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> | |
<defs> | |
<linearGradient id="g" x1="0%" y1="0%" x2="{X}" y2="{Y}"> | |
<stop offset="0%" style="stop-color:{C1};"/> | |
<stop offset="100%" style="stop-color:{C2};"/> | |
</linearGradient> | |
</defs> | |
<rect x="0" y="0" width="100%" height="100%" fill="url(#g)"/> | |
</svg> | |
XML; | |
echo str_replace( | |
array("{C1}", "{C2}", "{X}", "{Y}"), | |
array("rgb($c1)", "rgb($c2)", ($is_horz ? '0%' : '100%'), ($is_horz ? '100%' : '0%')), | |
$xml | |
); | |
}//function outputXML | |
function outputBitmap($c1, $c2, $is_horz, $size, $output){ | |
if ($is_horz){ | |
$img = new gd_gradient_fill(intval(ceil($size / 2)), $size, 'horizontal', $c1, $c2); | |
}else{ | |
$img = new gd_gradient_fill($size, intval(ceil($size / 2)), 'vertical', $c1, $c2); | |
}//if else - direction | |
$img->output($output); | |
}//function outputBitmap | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Script Name: GD Gradient Fill | |
Script URI: http://planetozh.com/blog/my-projects/images-php-gd-gradient-fill/ | |
Description: Creates a gradient fill of any shape (rectangle, ellipse, vertical, horizontal, diamond) | |
Author: Ozh | |
Version: 1.1 | |
Author URI: http://planetozh.com/ | |
*/ | |
/* Release history : | |
* 1.1 | |
* - changed : more nicely packaged as a class | |
* - fixed : not displaying proper gradient colors with image dimension greater than 255 (because of a limitation in imagecolorallocate) | |
* - added : optional parameter 'step', more options for 'direction' | |
* 1.0 | |
* - initial release | |
*/ | |
/* Usage : | |
* | |
* require_once('/path/to/gd-gradient-fill.php'); | |
* $image = new gd_gradient_fill($width,$height,$direction,$startcolor,$endcolor,$step); | |
* | |
* Parameters : | |
* - width and height : integers, dimesions of your image. | |
* - direction : string, shape of the gradient. | |
* Can be : vertical, horizontal, rectangle (or square), ellipse, ellipse2, circle, circle2, diamond. | |
* - startcolor : string, start color in 3 or 6 digits hexadecimal. | |
* - endcolor : string, end color in 3 or 6 digits hexadecimal. | |
* - step : integer, optional, default to 0. Step that breaks the smooth blending effect. | |
* Returns a resource identifier. | |
* | |
* Examples : | |
* | |
* 1. | |
* require_once('/home/ozh/www/includes/gd-gradient-fill.php'); | |
* $image = new gd_gradient_fill(200,200,'horizontal','#fff','#f00'); | |
* | |
* 2. | |
* require_once('c:/iis/inet/include/gd-gradient-fill.php'); | |
* $myimg = new gd_gradient_fill(80,20,'diamond','#ff0010','#303060'); | |
* | |
*/ | |
class gd_gradient_fill{ | |
private $image; | |
private $width; | |
private $height; | |
private $direction; | |
private $startcolor; | |
private $endcolor; | |
private $step; | |
// Constructor. Creates, fills and returns an image | |
function __construct($width, $height, $direction, $startcolor, $endcolor, $step = 0) { | |
$this->width = $width; | |
$this->height = $height; | |
$this->direction = $direction; | |
$this->startcolor = $startcolor; | |
$this->endcolor = $endcolor; | |
$this->step = intval(abs($step)); | |
$this->image = imagecreatetruecolor($this->width, $this->height); | |
$this->fill(); | |
} | |
//constructor | |
// Displays the image with a portable function that works with any file type | |
// depending on your server software configuration | |
public function output($format) { | |
switch ($format) { | |
case 'png' : | |
header("Content-type: image/png"); | |
imagepng($this->image); | |
return 1; | |
case 'gif' : | |
header("Content-type: image/gif"); | |
imagegif($this->image); | |
return 1; | |
case 'jpg': | |
case 'jpeg': | |
header("Content-type: image/jpeg"); | |
imagejpeg($this->image, "", 0.5); | |
return 1; | |
case 'wbmp' : | |
header("Content-type: image/vnd.wap.wbmp"); | |
imagewbmp($this->image); | |
return 1; | |
default : | |
return 0; | |
} | |
//switch - format | |
} | |
//function output | |
// The main function that draws the gradient | |
private function fill() { | |
switch ($this->direction) { | |
case 'vertical': | |
$line_numbers = imagesx($this->image); | |
$line_width = imagesy($this->image); | |
list($r1, $g1, $b1) = $this->hex2rgb($this->startcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->endcolor); | |
break; | |
case 'horizontal': | |
$line_numbers = imagesy($this->image); | |
$line_width = imagesx($this->image); | |
list($r1, $g1, $b1) = $this->hex2rgb($this->startcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->endcolor); | |
break; | |
case 'ellipse': | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$rh = $height > $width ? 1 : $width / $height; | |
$rw = $width > $height ? 1 : $height / $width; | |
$line_numbers = min($width, $height); | |
$center_x = $width / 2; | |
$center_y = $height / 2; | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
imagefill($this->image, 0, 0, imagecolorallocate($this->image, $r1, $g1, $b1)); | |
break; | |
case 'ellipse2': | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$rh = $height > $width ? 1 : $width / $height; | |
$rw = $width > $height ? 1 : $height / $width; | |
$line_numbers = sqrt(pow($width, 2) + pow($height, 2)); | |
$center_x = $width / 2; | |
$center_y = $height / 2; | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
break; | |
case 'circle': | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$line_numbers = sqrt(pow($width, 2) + pow($height, 2)); | |
$center_x = $width / 2; | |
$center_y = $height / 2; | |
$rh = $rw = 1; | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
break; | |
case 'circle2': | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$line_numbers = min($width, $height); | |
$center_x = $width / 2; | |
$center_y = $height / 2; | |
$rh = $rw = 1; | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
imagefill($this->image, 0, 0, imagecolorallocate($this->image, $r1, $g1, $b1)); | |
break; | |
case 'square': | |
case 'rectangle': | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$line_numbers = max($width, $height) / 2; | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
break; | |
case 'diamond': | |
list($r1, $g1, $b1) = $this->hex2rgb($this->endcolor); | |
list($r2, $g2, $b2) = $this->hex2rgb($this->startcolor); | |
$width = imagesx($this->image); | |
$height = imagesy($this->image); | |
$rh = $height > $width ? 1 : $width / $height; | |
$rw = $width > $height ? 1 : $height / $width; | |
$line_numbers = min($width, $height); | |
break; | |
default: | |
return 0; | |
} | |
for ($i = 0; $i < $line_numbers; $i = $i + 1 + $this->step) { | |
// old values : | |
$old_r = $r; | |
$old_g = $g; | |
$old_b = $b; | |
// new values : | |
$r = ($r2 - $r1 != 0) ? intval($r1 + ($r2 - $r1) * ($i / $line_numbers)) : $r1; | |
$g = ($g2 - $g1 != 0) ? intval($g1 + ($g2 - $g1) * ($i / $line_numbers)) : $g1; | |
$b = ($b2 - $b1 != 0) ? intval($b1 + ($b2 - $b1) * ($i / $line_numbers)) : $b1; | |
// if new values are really new ones, allocate a new color, otherwise reuse previous color. | |
// There's a "feature" in imagecolorallocate that makes this function | |
// always returns '-1' after 255 colors have been allocated in an image that was created with | |
// imagecreate (everything works fine with imagecreatetruecolor) | |
if ("$old_r,$old_g,$old_b" != "$r,$g,$b") { | |
$fill = imagecolorallocate($this->image, $r, $g, $b); | |
} | |
switch ($this->direction) { | |
case 'horizontal': | |
imagefilledrectangle( | |
$this->image, | |
0, | |
$i, | |
$line_width, | |
$i + $this->step, | |
$fill | |
); | |
break; | |
case 'vertical': | |
imagefilledrectangle( | |
$this->image, | |
$i, | |
0, | |
$i + $this->step, | |
$line_width, | |
$fill | |
); | |
break; | |
case 'ellipse': | |
case 'ellipse2': | |
case 'circle': | |
case 'circle2': | |
imagefilledellipse( | |
$this->image, | |
$center_x, | |
$center_y, | |
($line_numbers - $i) * $rh, | |
($line_numbers - $i) * $rw, | |
$fill | |
); | |
break; | |
case 'square': | |
case 'rectangle': | |
imagefilledrectangle( | |
$this->image, | |
$i * $width / $height, | |
$i * $height / $width, | |
$width - ($i * $width / $height), | |
$height - ($i * $height / $width), | |
$fill | |
); | |
break; | |
case 'diamond': | |
imagefilledpolygon( | |
$this->image, | |
array( | |
$width / 2, $i * $rw - 0.5 * $height, | |
$i * $rh - 0.5 * $width, $height / 2, | |
$width / 2, 1.5 * $height - $i * $rw, | |
1.5 * $width - $i * $rh, $height / 2 | |
), | |
4, | |
$fill | |
); | |
break; | |
default: | |
return 0; | |
} | |
//switch - direction | |
} | |
//for - line_numbers | |
return 1; | |
} | |
//function fill | |
// new 255,0,255 | |
// old :#ff00ff -> array(255,0,255) or #f0f -> array(255,0,255) | |
private function hex2rgb($color) { | |
return explode(',', $color); | |
$color = str_replace('#', '', $color); | |
$s = strlen($color) / 3; | |
return array( | |
hexdec(str_repeat(substr($color, 0, $s), 2 / $s)), | |
hexdec(str_repeat(substr($color, $s, $s), 2 / $s)), | |
hexdec(str_repeat(substr($color, 2 * $s, $s), 2 / $s)), | |
); | |
} | |
//function hex2rgb | |
}//class gd_gradient_fill |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment