Skip to content

Instantly share code, notes, and snippets.

@renekoch
Last active December 16, 2015 01:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renekoch/5354463 to your computer and use it in GitHub Desktop.
Save renekoch/5354463 to your computer and use it in GitHub Desktop.
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