PDA

View Full Version : website color generation script wanted (php)



rubah
01-16-2009, 01:46 AM
I could do this, but I'm kinda lazy feeling, and I have this feeling that someone more comfortable with regex could do it easier and faster and better than I.

Here's the scenario: There's a website form where a user enters four colors in hex (with or without the # and with or without capital letters)

Those colors get the # stripped off and are divided into three two character strings apiece.

convert them to decimal.

Then follow a certain pattern to add the strings together and divide by two (essentially creating "inbetween" colors)

then this would be output to the page in a nice table.

Mostly it's just the regex I don't want to do. I'm comfortable with tables and forms and stuff, but things like preg_replace give me the willies.

anyone interested to be my slave for the day? :D

o_O
01-16-2009, 04:28 AM
Here's something I whipped up. The CSS formatting is horrible but the amount of it in there was annoying me since it's not the point of the code so I packed it all together. :D


<?php
// declarations
$cols = Array($_POST['colourone'], $_POST['colourtwo'], $_POST['colourthree'], $_POST['colourfour']);
$colours = Array(); $final = Array();

// remove # symbol
foreach ($cols as $colour) array_push($colours, preg_replace('/#/', '', $colour));

// nested for loop to only calculate midpoint between unique unordered pairs
for ($i = 0; $i < count($colours); $i++) {
for ($j = $i+1; $j < count($colours); $j++) {
$rgb_one = getRgb($colours[$i]);
$rgb_two = getRgb($colours[$j]);
$rgb_three = getMidColour($rgb_one, $rgb_two);
$triplet = Array(implode($rgb_one), implode($rgb_three), implode($rgb_two));
array_push($final, $triplet);
}
}

// returns array containing individual RGB components in hex
function getRgb($col) {
return Array(
substr($col, 0, 2),
substr($col, 2, 2),
substr($col, 4, 2)
);
}

// calculates the midpoint between two colours
// double conversion is performed to convert from a string for arithmetic
function getMidColour($rgb_one, $rgb_two) {
$red = dechex((hexdec('0x'. $rgb_one[0]) + hexdec('0x'. $rgb_two[0])) / 2);
$green = dechex((hexdec('0x'. $rgb_one[1]) + hexdec('0x'. $rgb_two[1])) / 2);
$blue = dechex((hexdec('0x'. $rgb_one[2]) + hexdec('0x'. $rgb_two[2])) / 2);

return Array($red, $green, $blue);
}
?>

<html>
<head>
<title>Colour generator</title>
&lt;style>
body { background: #FAFAFF; font-family: Tahoma; margin: 35px; }
td { border: 1px solid black; }
tr.headings>td { border: 0px; font-size: 10px; text-align: center; }
.swatchtable { border: 1px dotted black; padding: 10px; }
tr.swatches>td { width: 70px; height: 50px; }
.formdiv { float: left; border: 1px dotted black; padding: 10px; width: 500px; }
</style>
</head>

<body>
<?php if ($_POST['submit']) { ?>
<div style="float: right;">
<h3>Here is your colour table:</h3>
<table class="swatchtable">
<tr class="headings">
<td>First</td>
<td>Middle</td>
<td>Second</td>
</tr>
<?php foreach ($final as $triplet) { ?>
<tr class="swatches">
<td style="background: #<?= $triplet[0] ?>;">&nbsp;</td>
<td style="background: #<?= $triplet[1] ?>;">&nbsp;</td>
<td style="background: #<?= $triplet[2] ?>;">&nbsp;</td>
</tr>
<?php } ?>
</table>
</div>
<?php } ?>

<br /><br />
<div class="formdiv">
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" name="colours">
<h3>Enter four colours in hex:</h3>
<input type="text" size="7" name="colourone" />
<input type="text" size="7" name="colourtwo" />
<input type="text" size="7" name="colourthree" />
<input type="text" size="7" name="colourfour" />
<input type="submit" name="submit" value="Submit" />
</form>
</div>
</body>
</html>

rubah
01-16-2009, 05:57 AM
heeeeh, fun :D I got the algorithm wrong though, it's a bit way more complicated.

Fire Element WIP by =ElvenCrystaline on deviantART (http://elvencrystaline.deviantart.com/art/Fire-Element-WIP-109178729)

essentially it's creating the palette in that image. I guess you'd really need to start with six colors, light medium and dark for your two hues. then hopefully the table would resemble that. we also need to tell the user what order to input the colors in.

BUT YOU DON"T HAVE TO DO THIS ALL MIKE IT"S OKAY I LOVE YOU ENOUGH FOR WHAT YOU'VE SHOWN ME NOW. I just wanted to make sure I remember this in future.

o_O
01-19-2009, 03:21 AM
Ok, well I did it for fun anyway (now that the weekend's over and I'm back at work). My colour averaging algorithm is obviously not perfect, but if you have an algorithm you'd rather use then it's pretty trivial to change. There's substantially more code here though, so I tried to put some more comments in. :p
<?php
// declarations including default colours
$cols = ($_POST['submit'])?Array($_POST['colourone'], $_POST['colourtwo'], $_POST['colourthree'], $_POST['colourfour']):Array('003b97', 'c6dcff', '9c1803', 'f7fdb7');
$colours = Array(); $final = Array();

// remove # symbol
foreach ($cols as $colour) array_push($colours, preg_replace('/#/', '', $colour));

// returns array containing individual RGB components in hex
function getRgb($col) {
return Array(
substr($col, 0, 2),
substr($col, 2, 2),
substr($col, 4, 2));
}

// calculates the midpoint between two colours
// double conversion is performed to convert from a string for arithmetic
function getMidColour($rgb_one, $rgb_two) {
$red = dechex((hexdec('0x'. $rgb_one[0]) + hexdec('0x'. $rgb_two[0])) / 2);
$green = dechex((hexdec('0x'. $rgb_one[1]) + hexdec('0x'. $rgb_two[1])) / 2);
$blue = dechex((hexdec('0x'. $rgb_one[2]) + hexdec('0x'. $rgb_two[2])) / 2);

return Array($red, $green, $blue);
}

// generates a gradient of $numCols resolution between two colours $rgb_one and $rgb_two
/*
Algorithm to generate gradient:
Each hex colour is split up into its RGB components and converted to decimal to prevent the script from failing due to
division by zero, inaccurately rounded or negative hex numbers. Then the difference of each RGB component is divided by
the resolution of the gradient to generate an even interval. Then the original colour is sampled at intervals corresponding
to the calculate interval, providing a smooth (hopefully) transition between the two colours.
*/
function getSpectrum($rgb_one, $rgb_two, $numCols) {
$one = Array(hexdec($rgb_one[0]), hexdec($rgb_one[1]), hexdec($rgb_one[2]));
$two = Array(hexdec($rgb_two[0]), hexdec($rgb_two[1]), hexdec($rgb_two[2]));
// add first colour
$spectrum = Array(Array(dechex($one[0]), dechex($one[1]), dechex($one[2])));
// calculate avg colour step
$avg = Array(
($two[0] - $one[0]) / $numCols,
($two[1] - $one[1]) / $numCols,
($two[2] - $one[2]) / $numCols);
// push in-between colours onto array
for ($i = 1; $i < $numCols; $i++) {
array_push($spectrum, Array(
dechex($one[0] + $i * $avg[0]),
dechex($one[1] + $i * $avg[1]),
dechex($one[2] + $i * $avg[2])));
}
// append last colour
array_push($spectrum, Array(dechex($two[0]), dechex($two[1]), dechex($two[2])));
return $spectrum;
}

// formats the data from getSpectrum() into HTML-friendly hex codes
function formatColours($spectrum) {
$formatted = Array();
foreach ($spectrum as $col) {
$colour = '#';
$colour .= (strlen($col[0]) == 1)?'0'.$col[0]:$col[0];
$colour .= (strlen($col[1]) == 1)?'0'.$col[1]:$col[1];
$colour .= (strlen($col[2]) == 1)?'0'.$col[2]:$col[2];
array_push($formatted, $colour);
}
return $formatted;
}

//
$spec1 = getSpectrum(getRgb($colours[1]),getMidColour(getRgb($colours[0]), getRgb($colours[1])), 4);
$spec2 = getSpectrum(getMidColour(getRgb($colours[0]), getRgb($colours[1])), getMidColour(getRgb($colours[0]), getRgb($colours[2])), 4);
$spec3 = getSpectrum(getMidColour(getRgb($colours[1]), getRgb($colours[3])), getMidColour(getRgb($colours[0]), getRgb($colours[1])), 4);
$spec4 = getSpectrum(getMidColour(getRgb($colours[0]), getRgb($colours[1])), getRgb($colours[0]), 4);
$spec5 = getSpectrum(getMidColour(getRgb($colours[1]), getRgb($colours[3])), getMidColour(getRgb($colours[2]), getRgb($colours[3])), 4);
$spec6 = getSpectrum(getMidColour(getRgb($colours[2]), getRgb($colours[3])), getRgb($colours[2]), 4);
$spec7 = getSpectrum(getRgb($colours[3]), getMidColour(getRgb($colours[2]), getRgb($colours[3])), 4);
$spec8 = getSpectrum(getMidColour(getRgb($colours[2]), getRgb($colours[3])), getMidColour(getRgb($colours[0]), getRgb($colours[2])), 4);
$spec9 = getSpectrum($spec5[1], $spec2[1], 4);
$spec10 = getSpectrum($spec5[2], $spec2[2], 4);
$spec11 = getSpectrum($spec5[3], $spec2[3], 4);

$spec1f = formatColours($spec1);
$spec2f = formatColours($spec2);
$spec3f = formatColours($spec3);
$spec4f = formatColours($spec4);
$spec5f = formatColours($spec5);
$spec6f = formatColours($spec6);
$spec7f = formatColours($spec7);
$spec8f = formatColours($spec8);
$spec9f = formatColours($spec9);
$spec10f = formatColours($spec10);
$spec11f = formatColours($spec11);
?>

<html>
<head>
<title>Colour generator</title>
&lt;style>
body { background: #FAFAFF; font-family: Tahoma; margin: 35px; }
table { border: 1px dotted black; padding: 10px; background: #EDEDFF}
td { border: 0px solid black; }
td.swatch { border: 1px solid black; height: 15px; width: 15px; }
.formdiv { float: left; border: 1px dotted black; background: EDEDFF; padding: 10px; width: 500px; }
</style>

&lt;script language="javascript">
function resizeSwatches(elem) {
var elements = document.getElementsByClassName('swatch');
for (var i = 0; i < elements.length; i++) {
elements[i].style.width=elem.value;
elements[i].style.height=elem.value;
}
}
</script>
</head>

<body>
<div style="float: right;">
<h3>Here is your colour table:</h3>
<table>
<?php // displaying all of the colour information from each spectrum
for ($i = 0; $i < 4; $i++) { ?>
<tr>
<td colspan="8"></td>
<td class="swatch" style="background: <?php echo $spec1f[$i]; ?>"></td>
</tr>
<?php } ?>

<tr>
<td colspan="4"></td>
<?php foreach ($spec3f as $col) { ?>
<td class="swatch" style="background: <?php echo $col; ?>"></td>
<?php } for ($i = 1; $i < 5; $i++) { ?>
<td class="swatch" style="background: <?php echo $spec4f[$i]; ?>"></td>
<?php } ?>
</tr>

<tr>
<td colspan="4"></td>
<?php foreach ($spec9f as $col) { ?>
<td class="swatch" style="background: <?php echo $col; ?>"></td>
<?php } ?>

</tr>
<tr>
<td colspan="4"></td>
<?php foreach ($spec10f as $col) { ?>
<td class="swatch" style="background: <?php echo $col; ?>"></td>
<?php } ?>
</tr>

<tr>
<td colspan="4"></td>
<?php foreach ($spec11f as $col) { ?>
<td class="swatch" style="background: <?php echo $col; ?>"></td>
<?php } ?>
</tr>

<tr>
<?php foreach ($spec7f as $col) { ?>
<td class="swatch" style="background: <?php echo $col; ?>"></td>
<?php } for ($i = 1; $i < 5; $i++) { ?>
<td class="swatch" style="background: <?php echo $spec8f[$i]; ?>"></td>
<?php } ?>
</tr>

<?php for ($i = 1; $i < 5; $i++) { ?>
<tr>
<td colspan="4"></td>
<td class="swatch" style="background: <?php echo $spec6f[$i]; ?>"></td>
</tr>
<?php } ?>

<tr>
<td colspan="100%">
<span style="float: right;">
Swatch size:
<select onchange="resizeSwatches(this);">
<?php for ($i = 1; $i < 100; $i++)
if ($i == 15) echo "<option value=\"$i\" selected=\"selected\">$i</option>";
else echo "<option value=\"$i\">$i</option>";
?>
</select>
</span>
</td>
</tr>
</table>
</div>

<br /><br />
<div class="formdiv">
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" name="colours">
<h3>Enter four colours in hex:</h3>
<input type="text" size="7" name="colourone" />
<input type="text" size="7" name="colourtwo" />
<input type="text" size="7" name="colourthree" />
<input type="text" size="7" name="colourfour" />
<input type="submit" name="submit" value="Submit" />
</form>
</div>
</body>
</html>EDIT: Ok, well I decided there wasn't enough Javascript or comments, and there was too much CSS so I fixed it up a little. :p

rubah
01-19-2009, 07:02 PM
omg, mike you are so amazing :D *showers hugs upon you*