<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Paper Ball Designs</title>
	<atom:link href="http://www.paperballdesigns.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.paperballdesigns.com</link>
	<description>Your Choice for Graphic and Web Design</description>
	<lastBuildDate>Sun, 29 Apr 2012 15:08:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Translucent Rectangle with Rounded Corners Using PHP</title>
		<link>http://www.paperballdesigns.com/development-resources/457</link>
		<comments>http://www.paperballdesigns.com/development-resources/457#comments</comments>
		<pubDate>Tue, 07 Feb 2012 21:52:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development Resources]]></category>

		<guid isPermaLink="false">http://www.paperballdesigns.com/?p=457</guid>
		<description><![CDATA[So recently I worked on a project where I had to create a watermark for an image on the fly, using user-submitted text and then merge it with a background image. I hadn&#8217;t had much opportunity to play with the &#8230; <a href="http://www.paperballdesigns.com/development-resources/457">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So recently I worked on a project where I had to create a watermark for an image on the fly, using user-submitted text and then merge it with a background image. I hadn&#8217;t had much opportunity to play with the PHP GD library before now (only for graphs and whatnot), but it&#8217;s pretty awesome! I ran into a snag though, in that I needed my watermark to be translucent with opaque text and I needed a transparent background (for the rounded corners). I found an easy function for creating a rounded rectangle by merging two rectangles and four circles, but I couldn&#8217;t apply a translucent color directly to this or else the overlaps would have different opacities. I tried merging them, saving them as an image, and then changing that image&#8217;s opacity, but I could never get the combination of a translucent object with a clear background. So I decided to brush off the old trigonometry and make my own rounded rectangle (or at least pretty close) with the imagefilledpolygon function in PHP. I then just applied this and some text to an image, and voila! awesome watermark. So I just made a quick php function and thought I&#8217;d share it with you (I guessed on things like width and height of the characters, but I&#8217;m sure smarter people will have a good formula for calculating that stuff). Incidentally, I had to make another part of the logo as a trapezoid with rounded corners and wow, I underestimated how hard that would be! <a title="Example Rounded Rectangle" href="http://www.paperballdesigns.com/example-rounded-rectangle" target="_blank">Here&#8217;s</a> a page with an example using the function call</p>
<p>&nbsp;</p>
<pre>&lt;?php
$myPath = get_bloginfo('stylesheet_directory').'/images/rectangle.png';
rounded_rectangle(10, 10, 30, 20, 'ff0000', 10, 10, 'rectangle.png', 'test text', '#00ff00'); ?&gt;
&lt;img src="&lt;?php echo $myPath; ?&gt;"&gt;</pre>
<pre>&lt;?php 

function rounded_rectangle($left, $top, $padding_x, $padding_y, $color, $opacity, $corner_radius, $name, $text, $text_color){

	$width = $left + strlen($text)*9 + 2*$padding_x;
	$height = $top + 26 + 2*$padding_y;
	if(substr($color, 0, 1) == "#"){
		$color = substr($color, 1);
	}

	$r = substr($color,0,2);
	$g = substr($color,2,2);
	$b = substr($color,4,2);

	$r = hexdec($r);
	$g = hexdec($g);
	$b = hexdec($b);

	if(substr($text_color, 0, 1) == "#"){
		$text_color = substr($text_color, 1);
	}

	$text_r = substr($text_color,0,2);
	$text_g = substr($text_color,2,2);
	$text_b = substr($text_color,4,2);

	$text_r = hexdec($text_r);
	$text_g = hexdec($text_g);
	$text_b = hexdec($text_b);

	$opacity = (100 - $opacity)/100 * 127;

	$final_image = imagecreatetruecolor($left + $width, $top + $height);
	imagesavealpha($final_image, true);
	$trans_color = imagecolorallocatealpha($final_image, 0, 0, 0, 127);
	imagefill($final_image, 0, 0, $trans_color);

	$rectangle_color = imagecolorallocatealpha($final_image, $r, $g, $b, $opacity);

	$points_array = array(
		$left, $top + $corner_radius, //starting from top left corner before radius
		$left + $corner_radius - cos(deg2rad(22.5))*$corner_radius, $top + $corner_radius - sin(deg2rad(22.5))*$corner_radius,
		$left + $corner_radius - cos(deg2rad(45))*$corner_radius, $top + $corner_radius - sin(deg2rad(45))*$corner_radius,
		$left + $corner_radius - cos(deg2rad(67.5))*$corner_radius, $top + $corner_radius - sin(deg2rad(67.5))*$corner_radius,
		$left + $corner_radius, $top,

		$left + $width - $corner_radius, $top,
		$left + $width - $corner_radius + cos(deg2rad(67.5))*$corner_radius, $top + $corner_radius - sin(deg2rad(67.5))*$corner_radius,
		$left + $width - $corner_radius + cos(deg2rad(45))*$corner_radius, $top + $corner_radius - sin(deg2rad(45))*$corner_radius,
		$left + $width - $corner_radius + cos(deg2rad(22.5))*$corner_radius, $top + $corner_radius - sin(deg2rad(22.5))*$corner_radius,
		$left + $width, $top + $corner_radius,

		$left + $width, $top + $height - $corner_radius,
		$left + $width - $corner_radius + cos(deg2rad(22.5))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(22.5))*$corner_radius,
		$left + $width - $corner_radius + cos(deg2rad(45))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(45))*$corner_radius,
		$left + $width - $corner_radius + cos(deg2rad(67.5))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(67.5))*$corner_radius,
		$left + $width - $corner_radius, $top + $height,

		$left + $corner_radius, $top + $height,
		$left + $corner_radius - cos(deg2rad(67.5))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(67.5))*$corner_radius,
		$left + $corner_radius - cos(deg2rad(45))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(45))*$corner_radius,
		$left + $corner_radius - cos(deg2rad(22.5))*$corner_radius, $top + $height - $corner_radius + sin(deg2rad(22.5))*$corner_radius,
		$left, $top + $height - $corner_radius

	);

	$rectangle = imagefilledpolygon($final_image, $points_array, 20, $rectangle_color);

	$text_color = imagecolorallocatealpha($final_image, $text_r, $text_g, $text_b, 0);
	$font = 'wp-content/themes/paperballdesigns/arial.ttf';
	imagettftext($final_image, 20, 0, $left + $padding_x, $top + 26 + $padding_y, $text_color, $font, $text);

	imagepng($final_image, 'wp-content/themes/paperballdesigns/images/'.$name);

	/*
if(!empty($path)){
		imagepng($final_image, $path);
	}else{
		header('Content-Type: image/png');
		imagepng($final_image);
	}
*/
	//imagedestroy($final_image);
}
?&gt;</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paperballdesigns.com/development-resources/457/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accessible Slider</title>
		<link>http://www.paperballdesigns.com/development-resources/415</link>
		<comments>http://www.paperballdesigns.com/development-resources/415#comments</comments>
		<pubDate>Tue, 31 Jan 2012 19:57:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development Resources]]></category>

		<guid isPermaLink="false">http://www.paperballdesigns.com/?p=415</guid>
		<description><![CDATA[So for a while there I was getting sort of pigeon-holed into making jQuery image sliders, and I was getting pretty good at them. Each client needed something slightly different so I had to put in a decent amount of &#8230; <a href="http://www.paperballdesigns.com/development-resources/415">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So for a while there I was getting sort of pigeon-holed into making jQuery image sliders, and I was getting pretty good at them. Each client needed something slightly different so I had to put in a decent amount of thought for each one (much more interesting than plugging and praying). One client in particular of ours was a university incredibly dedicated to accessibility, so we were tasked to create a well-designed, easy to use by page creators (this was all in Dreamweaver), and highly accessible. The last aspect was the most difficult, as it ruled out a lot of things I took for granted (background images, toggling display, etc.) and had to degrade nicely when javascript and css was turned off. So after all my toiling, I thought I&#8217;d share the code that I came up with for the slider. It rotates on a timer, pauses when a user hovers over the slider or the controls gain focus, and seems to be compatible with screen readers. The basic premise is that the image scrolling works very much like other sliders (just holding them offscreen and sliding them in) while the text is just grabbed from the various (hidden) text boxes to repopulate the one visible text area (which has the aria-live property). A lot of the code is just styling so you can modify most of it, the most important things are the overflow, display, and position properties and obviously the javascript. Anyway, <a href="http://www.paperballdesigns.com/example-slider" target="_blank">here&#8217;s</a> a working version of it for you to mess with, I hope it helps!</p>
<pre>&lt;style&gt;
#heroContainer{
	position: relative;
	margin-top: 18px;
	width: 960px;
	}

#imageScrollerContainer{
	border-top: 5px solid #29551a;
	height: 332px;
	padding-top: 1px;
	}

#heroTextVisible{
	width: 214px;
	height: 338px;
	overflow: hidden;
	display: none;
	position: absolute;
	right: 0px;
	top: 0;
	z-index: 2;
	background-color: #ffffff;
	font-family: "Calibri", Arial, Helvetica, sans-serif;
	padding-left: 18px;
	}

#heroTextVisible.heroTextVisibleOn{
	display: block;
	}

#imageScrollerContainer{
	width: 100%;
	margin-right: 18px;
	display:block;
	position: relative;
	z-index: 100;
	}

#imageScrollerWindow{
	width: 100%;
	position: absolute;
	left: 0;
	overflow: hidden;
	display: block;
	height: 100%;
	z-index: 0;
	}

.heroBlock{
	position: absolute;
	width: 100%;
	height: 100%;
	left: 0;
	display: block;
	z-index: 0;
	}

.scrollerImage{
	 width: 100%;
	 background-position: top left;
	 background-repeat: no-repeat;
	 height: 100%;
	 position: absolute;
	 z-index: -1;
	 display: block;
	 overflow: hidden;
	}

#imageArrowLeft,
#imageArrowRight{
	width: 50px;
	height: 50px;
	display: block;
	z-index: 200;
	position:absolute;
	top: 140px;
	cursor: pointer;
	overflow: hidden;
	}

#imageArrowRight{
	right: 207px;
	background-position: top right;
	}

#imageArrowRight img{
	top: 0px;
	right: 0px;
	position: absolute;
	}

#imageArrowLeft{
	left: -25px;
	background-position: top left;
	}

#imageArrowLeft img{
	top: 0px;
	left: 0px;
	position: absolute;
	}

#imageArrowRight:hover img,
#imageArrowRight:focus img{
	top: -50px;
	}

#imageArrowLeft:hover img,
#imageArrowLeft:focus img{
	top: -50px;
	}

.heroTextHolder{
	width: 214px;
	height: 313px;
	overflow: hidden;
	display: block;
	position: absolute;
	right: 0px;
	top: 0;
	z-index: 1;
	background-color: #ffffff;
	font-family: "Calibri", Arial, Helvetica, sans-serif;
	}

.heroTextHolder.heroTextHolderOff{
	display: none;
	}

.articleDate{
	color: #6a6a6a;
	text-transform: uppercase;
	text-align:left;
	margin-top: 15px;
	margin-left: 5px;
	font-size: 16px;
	display: block;
	}

#heroTextVisible h2,
.heroTextHolder h2{
	text-align: left;
	text-transform: uppercase;
	margin-left: 5px;
	font-size: 18px;
	color: #29551a;
	}

#heroTextVisible p,
.heroTextHolder p{
	text-align: left;
	margin-left: 14px;
	margin-right: 5px;
    overflow: hidden;
    max-height: 170px;
    line-height: 21px;
    font-size: 16px;
    font-family:"Times New Roman", Times, serif;
	}

#heroTextVisible a,
.heroTextHolder a{
	text-decoration: none;
	font-style:italic;
	color: #6a6a6a;
	float: left;
	margin-left: 15px;
	font-family:"Times New Roman", Times, serif;
	}

&lt;/style&gt;

&lt;div id="heroContainer"&gt;

    &lt;a id="imageArrowLeft" tabindex="3" href="javascript:void(0);"&gt;
        &lt;img src="images/leftRightBig.png" alt="Previous Article" /&gt;
    &lt;/a&gt; 

    &lt;a id="imageArrowRight" tabindex="3" href="javascript:void(0);"&gt;
        &lt;img src="images/leftRightBig.png" alt="Next Article" /&gt;
    &lt;/a&gt;

    &lt;div id="imageScrollerContainer"&gt;

    	&lt;div id="heroTextVisible" aria-live="polite"&gt;
    		&lt;div class="articleDate"&gt;&lt;/div&gt;
            &lt;h2&gt;&lt;/h2&gt;
            &lt;p&gt;&lt;/p&gt;
            &lt;a href="#"&gt;&lt;/a&gt;
            &lt;a id="readAllStories" href="#"&gt;Read All Stories &gt;&lt;/a&gt;
        &lt;/div&gt;&lt;!--heroTextVisible--&gt;

        &lt;div id="imageScrollerWindow"&gt;
            &lt;div class="heroBlock heroBlockActive"&gt;
                &lt;div class="scrollerImage"&gt;
                	&lt;img src="images/hero1.jpg" alt="hero1" width="730" height="333" /&gt;
                &lt;/div&gt;
                &lt;div class="heroTextHolder"&gt;
                    &lt;div class="articleDate heroContentActive"&gt;Aug 1 2011&lt;/div&gt;
                    &lt;h2 class="heroContentActive"&gt;Hero 1&lt;/h2&gt;
                    &lt;p class="heroContentActive"&gt;
                       This is the Text for Hero 1.
                    &lt;/p&gt;
                    &lt;a href="#" class="heroContentActive"&gt;Continue Reading &gt;&lt;/a&gt;
                &lt;/div&gt;&lt;!--heroTextHolder--&gt;
            &lt;/div&gt;&lt;!--heroBlock--&gt;

            &lt;div class="heroBlock"&gt;
                &lt;div class="scrollerImage"&gt;
                	&lt;img src="images/hero2.jpg" alt="hero2" width="730" height="333" /&gt;
                &lt;/div&gt;
                &lt;div class="heroTextHolder"&gt;
                    &lt;div class="articleDate"&gt;Aug 2 2011&lt;/div&gt;
                    &lt;h2&gt;Hero 2&lt;/h2&gt;
                    &lt;p&gt;
                       This is the Text for Hero 2.
                    &lt;/p&gt;
                    &lt;a href="#"&gt;
                        Continue Reading &gt;
                    &lt;/a&gt;
                &lt;/div&gt;&lt;!--heroTextHolder--&gt;
            &lt;/div&gt;&lt;!--heroBlock--&gt;

            &lt;div class="heroBlock"&gt;
                &lt;div class="scrollerImage"&gt;
                	&lt;img src="images/hero3.jpg" alt="hero3" width="730" height="333" /&gt;
                &lt;/div&gt;
                &lt;div class="heroTextHolder"&gt;
                    &lt;div class="articleDate"&gt;Aug 3 2011&lt;/div&gt;
                    &lt;h2&gt;Hero 3&lt;/h2&gt;
                    &lt;p&gt;
                        This is the Text for Hero 3.
                    &lt;/p&gt;
                    &lt;a href="#"&gt;
                        Continue Reading &gt;
                    &lt;/a&gt;
                &lt;/div&gt;&lt;!--heroTextHolder--&gt;
            &lt;/div&gt;&lt;!--heroBlock--&gt;

            &lt;div class="heroBlock"&gt;
                &lt;div class="scrollerImage"&gt;
                	&lt;img src="images/hero4.jpg" alt="hero4" width="730" height="333" /&gt;
                &lt;/div&gt;
                &lt;div class="heroTextHolder"&gt;
                    &lt;div class="articleDate"&gt;Aug 4 2011&lt;/div&gt;
                    &lt;h2&gt;Hero 4&lt;/h2&gt;
                    &lt;p&gt;
                        This is the Text for Hero 4.
                    &lt;/p&gt;
                    &lt;a href="#"&gt;
                        Continue Reading &gt;
                    &lt;/a&gt;
                &lt;/div&gt;&lt;!--heroTextHolder--&gt;
            &lt;/div&gt;&lt;!--heroBlock--&gt;

            &lt;div class="heroBlock"&gt;
            	&lt;div class="scrollerImage"&gt;
            		&lt;img src="images/hero5.jpg" alt="hero5" width="730" height="333" /&gt;
            	&lt;/div&gt;
                &lt;div class="heroTextHolder"&gt;
                    &lt;div class="articleDate"&gt;Aug 5 2011&lt;/div&gt;
                    &lt;h2&gt;Hero 5&lt;/h2&gt;
                    &lt;p&gt;
                       This is the Text for Hero 5.
                    &lt;/p&gt;
                    &lt;a href="#"&gt;
                        Continue Reading &gt;
                    &lt;/a&gt;
                &lt;/div&gt;&lt;!--heroTextHolder--&gt;
            &lt;/div&gt;&lt;!--heroBlock--&gt;

        &lt;/div&gt;&lt;!--imageScrollerWindow--&gt;

    &lt;/div&gt;&lt;!--heroTextVisible--&gt;

&lt;/div&gt;&lt;!--heroContainer--&gt;&lt;!-- #EndLibraryItem --&gt;&lt;!-- #BeginEditable "widgets" --&gt;

&lt;script type="text/javascript"&gt;
$(document).ready(function(){

var scrollCount = 1;
var rightToggle = true;
var leftToggle = true;
var imageCount = $('#imageScrollerWindow').children().length;
var nextImage = 2;
var prevImage = imageCount;

$('#heroTextVisible').addClass('heroTextVisibleOn');
$('.heroTextHolder').addClass('heroTextHolderOff');
$('.heroBlock:nth-child(1) .scrollerImage').addClass('scrollerImageCurrent');
$('.heroBlock:nth-child(2) .scrollerImage').addClass('scrollerImageNext');
$('.heroBlock:nth-child('+prevImage+') .scrollerImage').addClass('scrollerImagePrevious');

$('.scrollerImage').not('.scrollerImageCurrent').css('left', '100%');

$('#heroTextVisible .articleDate').html($('.heroBlockActive .heroTextHolder .articleDate').html());
$('#heroTextVisible h2').html($('.heroBlockActive .heroTextHolder h2').html());
$('#heroTextVisible p').html($('.heroBlockActive .heroTextHolder p').html());
$('#heroTextVisible a').not('#readAllStories').html($('.heroBlockActive .heroTextHolder a').html());
$('#heroTextVisible a').not('#readAllStories').attr('href', $('.heroBlockActive .heroTextHolder a').attr('href'));

function scrollRight(){
	if(rightToggle==true){
		nextImage = (scrollCount+2)%imageCount;
		if(nextImage==0){nextImage=imageCount;}
		leftToggle=false;
		rightToggle=false;

		$('#heroTextVisible').children().stop(true, true).fadeTo(500, 0, function(){
			$('.heroBlockActive').removeClass('heroBlockActive');
			$('.heroBlock:nth-child('+scrollCount+')').addClass('heroBlockActive');
			$('#heroTextVisible .articleDate').html($('.heroBlockActive .heroTextHolder .articleDate').html());
			$('#heroTextVisible h2').html($('.heroBlockActive .heroTextHolder h2').html());
			$('#heroTextVisible p').html($('.heroBlockActive .heroTextHolder p').html());
			$('#heroTextVisible a').not('#readAllStories').html($('.heroBlockActive .heroTextHolder a').html());
			$('#heroTextVisible a').not('#readAllStories').attr('href', $('.heroBlockActive .heroTextHolder a').attr('href'));
			$('#heroTextVisible').children().fadeTo(500, 1);
		});

		$('.scrollerImageCurrent').animate({left: '-100%'}, 1000, function(){
			$('.scrollerImagePrevious').not(this).removeClass('scrollerImagePrevious');
			$(this).removeClass('scrollerImageCurrent').addClass('scrollerImagePrevious');
		});
		$('.scrollerImageNext').css('left', '100%').animate({left: '0%'}, 1000, function(){
			$(this).removeClass('scrollerImageNext').addClass('scrollerImageCurrent');
			$('.heroBlock:nth-child('+nextImage+') .scrollerImage').addClass('scrollerImageNext');
			leftToggle=true;
			rightToggle=true;
		});

		scrollCount++;
		scrollCount=scrollCount%imageCount;
		if(scrollCount==0){scrollCount=imageCount;}
	}
	else{}

}

function scrollLeft(){
	if(leftToggle==true){
		prevImage = (scrollCount-2+imageCount)%imageCount;
		if(prevImage==0){prevImage=imageCount;}
		leftToggle=false;
		rightToggle=false;

		$('#heroTextVisible').children().stop(true, true).fadeTo(500, 0, function(){
			$('.heroBlockActive').removeClass('heroBlockActive');
			$('.heroBlock:nth-child('+scrollCount+')').addClass('heroBlockActive');
			$('#heroTextVisible .articleDate').html($('.heroBlockActive .heroTextHolder .articleDate').html());
			$('#heroTextVisible h2').html($('.heroBlockActive .heroTextHolder h2').html());
			$('#heroTextVisible p').html($('.heroBlockActive .heroTextHolder p').html());
			$('#heroTextVisible a').not('#readAllStories').html($('.heroBlockActive .heroTextHolder a').html());
			$('#heroTextVisible a').not('#readAllStories').attr('href', $('.heroBlockActive .heroTextHolder a').attr('href'));
			$('#heroTextVisible').children().fadeTo(500, 1);
		});

		$('.scrollerImageCurrent').animate({left: '100%'}, 1000, function(){
			$('.scrollerImageNext').not(this).removeClass('scrollerImageNext');
			$(this).removeClass('scrollerImageCurrent').addClass('scrollerImageNext');
		});
		$('.scrollerImagePrevious').css('left', '-100%').animate({left: '0%'}, 1000, function(){
			$(this).removeClass('scrollerImagePrevious').addClass('scrollerImageCurrent');;
			$('.heroBlock:nth-child('+prevImage+') .scrollerImage').addClass('scrollerImagePrevious');
			leftToggle=true;
			rightToggle=true;
		});

		scrollCount--;
		scrollCount=scrollCount%imageCount;
		if(scrollCount==0){scrollCount=imageCount;}
	}
	else{}

}

		$('#imageArrowRight').click(function(){
			scrollRight();
		});

		$('#imageArrowLeft').click(function(){
			scrollLeft();
		});

		$('#smallNext').click(function(){
			scrollRight();
		});

		$('#smallPrev').click(function(){
			scrollLeft();
		});

		var imageScrollerTimer = 0;
		imageScrollerTimer = setInterval(scrollRight, 9000);
		var pause = null;

		$('#imageScrollerContainer, #imageArrowRight, #imageArrowLeft').hover(function(){
			if(!pause){
				clearInterval (imageScrollerTimer);
			}
		}, function(){
			if(!pause){
				clearInterval (imageScrollerTimer);
				imageScrollerTimer = setInterval(scrollRight, 9000);
			}
		});

		$('#imageArrowRight, #imageArrowLeft, #heroTextVisible a').focus(function(){
			if(!pause){
				clearInterval (imageScrollerTimer);
			}
		});

		$('#imageArrowRight, #imageArrowLeft, #heroTextVisible a').blur(function(){
			if(!pause){
				clearInterval (imageScrollerTimer);
				imageScrollerTimer = setInterval(scrollRight, 9000);
			}
		});

	});
&lt;/script&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.paperballdesigns.com/development-resources/415/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mosaic PHP problem</title>
		<link>http://www.paperballdesigns.com/development-resources/384</link>
		<comments>http://www.paperballdesigns.com/development-resources/384#comments</comments>
		<pubDate>Fri, 09 Dec 2011 22:50:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development Resources]]></category>

		<guid isPermaLink="false">http://www.paperballdesigns.com/?p=384</guid>
		<description><![CDATA[So I set a problem for myself, not thinking that it would be terribly hard. Turns out it&#8217;s quite a thinker and it was really enjoyable to work through, so I thought I&#8217;d share the problem and my solution&#8230;I&#8217;d love &#8230; <a href="http://www.paperballdesigns.com/development-resources/384">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I set a problem for myself, not thinking that it would be terribly hard. Turns out it&#8217;s quite a thinker and it was really enjoyable to work through, so I thought I&#8217;d share the problem and my solution&#8230;I&#8217;d love to see other solutions (I&#8217;m sure there are some super useful php functions of which I am unaware).</p>
<p>The idea was to create a random mosaic grid pattern, so various sizes of squares that fit perfectly inside a larger square (I was thinking it could be a cool image gallery tool, but who knows). Check out the final result (not styled or anything) <a href="http://www.paperballdesigns.com/grid-test" target="_blank">here</a>, I&#8217;ll paste the whole code first and then try to go through it piece by piece.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre>&lt;?php 

function get_random_color(){
	for($i=0; $i&lt;6; $i++){
		$c .= dechex(rand(0,15));
	}
	return "#$c";
}

$width = 8;
$height = 8;
$gridList = array();
$areaTaken = 0;
$limit = 6;
$gridArray = array(array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0),
		array(0,0,0,0,0,0,0,0));

while ($areaTaken&lt;($width*$height)){

	$size = rand(1, $limit);
	$possibleX=array();
	$tried=0;

	foreach($gridArray as $row=&gt;$colArray){
		$spaceCount = array_count_values($colArray);
		if($spaceCount[0]&gt;=$size){
			$startCol=0;
			while($startCol &lt;= (8-$size)){
				if($colArray[$startCol]==0){
					$col=$startCol;
					$freeX=0;
					while(($col&lt;($startCol+$size)) &amp;&amp; ($freeX&lt;$size)){
						if($colArray[$col]==0){
							$freeX++;
						}
						else{
							$freeX=0;
							break;
						}
						$col++;
					}
					if($freeX==$size){
						$freeX=0;
						$possibleX[$row][]=$startCol;
					}
				}
				$startCol++;
			}
		}
		else{
			$tried++;
		}
		if($tried&gt;(8-$size)){
			$limit=$size-1;
			break;
		}

	}

	$goodSpot==0;
	foreach($possibleX as $row=&gt;$columns){
		foreach($columns as $column){
			$i=intval($row)+1;
			$freeY = 1;
			$spotX = -1;
			$spotY = -1;
			while(($i&lt;(intval($row)+$size)) &amp;&amp; ($freeY&lt;$size)){
				if(isset($possibleX[$i]) &amp;&amp; in_array($column, $possibleX[$i])){
					$freeY++;
				}
				else{
					$freeY = 1;
					break;
				}
				$i++;
			}
			if($freeY==$size){
				$goodSpot=1;
				$spotX=intval($column);
				$spotY=intval($row);
				break;
			}
		}
		if($goodSpot==1){
			break;
		}
	}
	if($goodSpot==1){
		$gridList[] = array('size'=&gt;$size,
						'color'=&gt;get_random_color(),
						'posX'=&gt;$spotX,
						'posY'=&gt;$spotY);
		$areaTaken = $areaTaken + pow($size, 2);
		$takeY=$spotY;
		while($takeY&lt;($spotY+$size)){
			$takeX=$spotX;
			while($takeX&lt;($spotX+$size)){
				$gridArray[$takeY][$takeX]=1;
				$takeX++;
			}
			$takeY++;
		}
		$goodSpot=0;
		/*
foreach($gridArray as $row=&gt;$columns){
			echo'&lt;br&gt;Row: '.$row.': ';
			foreach($columns as $column){
				echo $column.' , ';
			}
		}
*/
	}

}

foreach($gridList as $div){
	echo '&lt;div style="background-color:'.$div['color'].';
		position:absolute;
		display: block;
		width:'.($div['size']*12.5).'%;
		height:'.($div['size']*12.5).'%;
		left:'.($div['posX']*12.5).'%;
		top:'.($div['posY']*12.5).'%;"&gt;
		&lt;/div&gt;';
}

?&gt;</pre>
<p>&nbsp;</p>
<p>Okay, so my reasoning was this: break up the parent div into an 8&#215;8 grid, build an array of available spots out of this grid, make squares of random sizes (but whole numbers on the unit grid, just to make it look a little cleaner), check to see whether there was a spot for them, assign them that spot, and then mark those spaces as full.</p>
<p>The first piece in the php code is the get_random_color function which I found in the comments on some manual page on <a href="http://www.php.net" target="_blank">php.net</a>, but after this it&#8217;s all my own stuff. First we set some parameters: the width and height of our parent div (just using 8 to make the grid easier), the area taken up by child divs (0 to start with), the maximum size a div can be (set to 6 units here), and then the $gridArray which lists all the possible spots in our 8&#215;8 unit grid (I know I should probably use while loops to make this automated so I could change the size but you can figure that out).</p>
<p>Next we set up the overall while loop, to be repeated as long as there is empty space in the grid. Within this we create a random size for our child div, we set up an array of possible spots it could occupy(only taking into account its width at this point), and we create a variable to keep track of the number of rows in the grid that we have tried to find a spot wide enough to house our child div. For each row in the $gridArray we first check whether there are even enough empty spots (not necessarily adjacent) to hold the width of our div. If there aren&#8217;t enough, we skip the row and marked that we tried one of the rows with no luck. If this happens enough times we drop the size of the $limit variable so that we only create divs that can actually fit.</p>
<p>If there are enough spaces, we set up the $startCol variable which will keep track of the cell we start counting from (think of it as where the top left corner of the div would go) and, if this starting point is actually an empty spot, start checking the cells to the right of this. If it is zero (empty) we increment the $freeX variable to say that, starting from $startCol, there are $freeX empty spots in a row. If we hit an occupied spot before we get enough empty spots to house the width of our child div, we move on to the next starting point. If we do have enough spots, the starting point we began counting from is saved in an array as a possible location that the div could occupy in that row.</p>
<p>Now that we have a list of possible spots in each row based on width, we can check to see if there are enough adjacent rows with that same starting spot to hold the height of the div. We set up the $goodSpot variable to indicate whether we have a valid place to put the div, then we loop over the array. For each row, we have a list of possible x-values for the left side of our div, so for each of these values we set up the $i variable to keep track of which row we&#8217;re on, the $freeY variable keeps track of how many adjacent rows have this starting point listed as a possibility, and the $spotX and $spotY are set up just to hold the x and y coordinates in case we come up with a place to put our div. So as we loop through, if the next row contains the same x-coordinate as a possibility, we increment the $freeY variable. Otherwise we stop the loop and move on to the next possible x-coordinate listed. If we get through all the values in the first row with no luck, we move on to the next row and try again. If we find a suitable spot for the child div, we immediately break the loop and add the information to the $gridList array that we set up at the very beginning. We record the size, get a random color to make it look cool, and get the newly found x and y coordinates for its top left corner.</p>
<p>Then we add the area of our child div to the amount of area being taken up, and mark the spots it will take up as occupied in our $gridArray. To do this we start at the top left corner and, for each row that will be taken up, change the values of the newly occupied spots in the grid array to 1.</p>
<p>Finally for each of the rows in our $gridList we create an absolutely positioned div, give it a color and a size (multiplying by 12.5% to change from our easy units to a percentage of the parent div), and position it where we determined it would fit. There we go, just a puzzle to solve really, but it turned out kinda cool. How would you solve the problem?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paperballdesigns.com/development-resources/384/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

