初學php,從簡單可見的對象開始

封裝了一下gd庫,用起來方便一些,通過寫這個庫,基本熟悉了php的語法

下面是庫shape.ini文件

<?php

	final class Range {
		public $location;
		public $length;

		public function __construct($location, $length) {
			$this->location = $location;
			$this->length = $length;
		}
	}
	
	final class Point {
		public $x, $y;
		
		public function __construct($x, $y) {
			$this->x = $x;
			$this->y = $y;
		}
	}
	
	final class Size {
		public $width, $height;
		
		public function __construct($w, $h) {
			$this->width = $w;
			$this->height = $h;
		}
	}
	
	final class Rect {
		public $x, $y, $width, $height;
		
		public function __construct($x, $y, $w, $h) {
			$this->x = $x;
			$this->y = $y;
			$this->width = $w;
			$this->height = $h;
		}
	}
	
	final class Color {
		public $red, $green, $blue;
		
		public function __construct($r, $g, $b) {
			$this->red = $r;
			$this->green = $g;
			$this->blue = $b;
		}
	}
	
	class Context {
		public $image;
		
		public function __construct($size, $color) {
			$this->image = imagecreatetruecolor($size->width, $size->height);
			imageantialias($this->image, true);
			$bgColor = imagecolorallocate($this->image, $color->red, $color->green, $color->blue);
			imagefilledrectangle($this->image, 0, 0, $size->width, $size->height, $bgColor);
		}
		
		public function echoPNG() {
			imagepng($this->image);
		}
		
		public function echoJPEG() {
			imagejpeg($this->image);
		}
		
		public function __destruct() {
			imagedestroy($this->image);
		}
	}

	class Shape {
		protected $context;
		protected $points;
		
		public $strokeColor;
		public $fillColor;
		private $lineWidth;
		
		function __set($name, $value) {
			if ($name == 'lineWidth') {
				$this->lineWidth = $value;
				imagesetthickness($this->context->image, $this->lineWidth);
			}
		}
		
		public function __construct($context) {
			$this->context = $context;
			$this->points = Array();
			$this->strokeColor = new Color(0, 0, 0);
			$this->lineWidth = 1;
			imagesetthickness($this->context->image, $this->lineWidth);
		}
		
		public function move($dx, $dy) {
			for ($i = 0; $i < count($this->points); ++$i) {
				$this->points[$i]->x += $dx;
				$this->points[$i]->y += $dy;
			}
		}
		
		public function draw() {
			$this->drawLines();
		}
		
		protected function drawLines() {
			if (isset($this->strokeColor)) {
				for ($i = 1; $i < count($this->points); ++$i) {
					$p1 = $this->points[$i-1];
					$p2 = $this->points[$i];
					$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
					imageline($this->context->image, $p1->x, $p1->y, $p2->x, $p2->y, $color);
				}
			}
		}
		
		protected function addPoint($point) {
			array_push($this->points, $point);
		}
	}
	
	class Line extends Shape {
		public function __construct($context, $point1, $point2) {
			parent::__construct($context);
			parent::addPoint($point1);
			parent::addPoint($point2);
		}
	}
	
	class Lines extends Shape {
		public function add($point1, $point2) {
			parent::addPoint($point1);
			parent::addPoint($point2);
		}
		
		protected function drawLines() {
			if (isset($this->strokeColor)) {
				for ($i = 1; $i < count($this->points); $i+=2) {
					$p1 = $this->points[$i-1];
					$p2 = $this->points[$i];
					$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
					imageline($this->context->image, $p1->x, $p1->y, $p2->x, $p2->y, $color);
				}
			}
		}
	}
	
	class Rectangle extends Shape {
		public function __construct($context, $rect) {
			parent::__construct($context);
			parent::addPoint(new Point($rect->x, $rect->y));
			parent::addPoint(new Point($rect->x+$rect->width, $rect->y));
			parent::addPoint(new Point($rect->x+$rect->width, $rect->y+$rect->height));
			parent::addPoint(new Point($rect->x, $rect->y+$rect->height));
		}
		
		protected function drawLines() {
			$p0 = $this->points[0];
			$p2 = $this->points[2];
			if (isset($this->fillColor) && isset($this->strokeColor)) {
				$color = imagecolorallocate($this->context->image, $this->fillColor->red, $this->fillColor->green, $this->fillColor->blue);
				imagefilledrectangle($this->context->image, $p0->x, $p0->y, $p2->x, $p2->y, $color);
				$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
				imagerectangle($this->context->image, $p0->x, $p0->y, $p2->x, $p2->y, $color);
			} else if (isset($this->strokeColor)) {
				$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
				imagerectangle($this->context->image, $p0->x, $p0->y, $p2->x, $p2->y, $color);
			} else if (isset($this->fillColor)) {
				$color = imagecolorallocate($this->context->image, $this->fillColor->red, $this->fillColor->green, $this->fillColor->blue);
				imagefilledrectangle($this->context->image, $p0->x, $p0->y, $p2->x, $p2->y, $color);
			}
		}
	}
	
	class Arc extends Shape {
		const Pie = IMG_ARC_PIE;
		const Chord = IMG_ARC_CHORD;
		const NoFill = IMG_ARC_NOFILL;
		const Edged = IMG_ARC_EDGED;
		
		public $style;
		
		public $width;
		public $height;
		public $start;
		public $end;
		
		public function __construct($context, $center, $width, $height, $start, $end) {
			parent::__construct($context);
			parent::addPoint($center);
			$this->width = $width;
			$this->height = $height;
			$this->start = $start;
			$this->end = $end;
			$this->style = Arc::Pie;
		}
		
		protected function drawLines() {
			$center = $this->points[0];
			if (isset($this->fillColor) && isset($this->strokeColor)) {
				$color = imagecolorallocate($this->context->image, $this->fillColor->red, $this->fillColor->green, $this->fillColor->blue);
				imagefilledarc($this->context->image, $center->x, $center->y, $this->width, $this->height, $this->start, $this->end, $color, $this->style);
				$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
				imagearc($this->context->image, $center->x, $center->y, $this->width, $this->height, $this->start, $this->end, $color);
			} else if (isset($this->strokeColor)) {
				$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
				imagearc($this->context->image, $center->x, $center->y, $this->width, $this->height, $this->start, $this->end, $color);
			} else if (isset($this->fillColor)) {
				$color = imagecolorallocate($this->context->image, $this->fillColor->red, $this->fillColor->green, $this->fillColor->blue);
				imagefilledarc($this->context->image, $center->x, $center->y, $this->width, $this->height, $this->start, $this->end, $color, $this->style);
			}
		}
	}
	
	class Ellipse extends Arc {
		public function __construct($context, $center, $width, $height) {
			parent::__construct($context, $center, $width, $height, 0, 360);
		}
	}
	
	class Circle extends Ellipse {
		public function __construct($context, $center, $radius) {
			parent::__construct($context, $center, $radius, $radius);
		}
	}
	
	class Text extends Shape {
		const Horizontal = 0;
		const Vertical = 1;
		
		public $orientaion;
		
		public $text;
		public $font;
		
		public function __construct($context, $point, $text) {
			parent::__construct($context);
			parent::addPoint($point);
			$this->text = $text;
			$this->font = 5;
			$this->orientaion = Text::Horizontal;
		}
		
		protected function drawLines() {
			$point = $this->points[0];
			$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
			if ($this->orientaion == Text::Horizontal)
				imagestring($this->context->image, $this->font, $point->x, $point->y, $this->text, $color);
			else
				imagestringup($this->context->image, $this->font, $point->x, $point->y, $this->text, $color);
		}
	}
	
	class OpenPolyline extends Shape {
		public function addPoint($point) {
			parent::addPoint($point);
		}
	}
	
	class ClosedPolyline extends OpenPolyline {
		protected function drawLines() {
			if (isset($this->strokeColor)) {
				parent::drawLines();
				$lastPoint = end($this->points);
				$point0 = $this->points[0];
				$color = imagecolorallocate($this->context->image, $this->strokeColor->red, $this->strokeColor->green, $this->strokeColor->blue);
				imageline($this->context->image, $lastPoint->x, $lastPoint->y, $point0->x, $point0->y, $color);
			}
		}
	}
	
	class Polygon extends ClosedPolyline {
		
		public function __construct($context) {
			parent::__construct($context);
			$this->fillColor = new Color(0, 0, 0);	
		}
		
		protected function drawLines() {
			if (isset($this->fillColor)) {
				$color = imagecolorallocate($this->context->image, $this->fillColor->red, $this->fillColor->green, $this->fillColor->blue);
				$points = Array();
				foreach ($this->points as $point) {
					array_push($points, $point->x);
					array_push($points, $point->y);
				}
				imagefilledpolygon($this->context->image, $points, count($this->points), $color);
			}
			parent::drawLines();
		}
	}
	
	class Axis extends Shape {
		const X = 0;
		const Y = 1;
		const Z = 2;
		
		private $notchLines;
		
		public function __construct($context, $orientation, $origin, $length, $n) {
			parent::__construct($context);
			$this->addPoint($origin);
			
			switch ($orientation) {
				case Axis::X:
					$this->addPoint(new Point($origin->x+$length, $origin->y));
					if ($n > 1) {
						$this->notchLines = new Lines($this->context);
						$dist = $length / $n;
						$x = $origin->x + $dist;
						for ($i = 0; $i < $n; ++$i) {
							$this->notchLines->add(new Point($x, $origin->y), new Point($x, $origin->y-5));
							$x += $dist;
						}
					}
					break;
				case Axis::Y:
					$this->addPoint(new Point($origin->x, $origin->y-$length));
					if ($n > 1) {
						$this->notchLines = new Lines($this->context);
						$dist = $length / $n;
						$y = $origin->y - $dist;
						for ($i = 0; $i < $n; ++$i) {
							$this->notchLines->add(new Point($origin->x, $y), new Point($origin->x+5, $y));
							$y -= $dist;
						}
					}
					break;
				case Axis::Z:
					break;
				default:
					break;
			}
		}
		
		protected function drawLines() {
			parent::drawLines();
			$this->notchLines->draw();
		}
	}
	
	class Func extends Shape {
		public function __construct($context, $func, $range, $point, $count, $xScale, $yScale) {
			parent::__construct($context);
			if (is_callable($func)) {
				$dist = ($range->length - $range->location) / $count;
				$r = $range->location;
				for ($i = 0; $i < $count; ++$i) {
					$result = call_user_func($func, $r);
					$this->addPoint(new Point($point->x+$r*$xScale, $point->y-$result*$yScale));
					$r += $dist;
				}
			}
		}
	}
?>

下面是測試文件test.php

<?php
	header("Content-Type:text/json; charset=utf-8");
	header("Content-Type: image/png");
	require_once 'shape.inc';

	$context = new Context(new Size(800, 600), new Color(0xcc, 0xcc, 0xcc));
	
	$line = new Line($context, new Point(300, 100), new Point(600, 50));
	$line->lineWidth = 2;
	$line->strokeColor = new Color(0xff, 0, 0);
	$line->draw();
	
	$rect = new Rectangle($context, new Rect(50, 50, 200, 100));
	$rect->draw();
	$rect->move(50, 50);
	$rect->draw();
	
	$arc = new Arc($context, new Point(500, 400), 200, 200, 0, 300);
	$arc->lineWidth = 2;
	$arc->draw();

	$ellipse = new Ellipse($context, new Point(200, 300), 300, 200);
	$ellipse->draw();
	
	$circle = new Circle($context, new Point(400, 200), 100);
	$circle->draw();
	
	$opl = new ClosedPolyline($context);
	$opl->addPoint(new Point(345, 232));
	$opl->addPoint(new Point(545, 232));
	$opl->addPoint(new Point(345, 332));
	$opl->addPoint(new Point(245, 432));
	$opl->addPoint(new Point(345, 532));
	$opl->draw();
	
	$polygon = new Polygon($context);
	$polygon->addPoint(new Point(170, 70));
	$polygon->addPoint(new Point(320, 140));
	$polygon->addPoint(new Point(270, 320));
	$polygon->addPoint(new Point(50, 330));
	$polygon->addPoint(new Point(65, 160));
	$polygon->lineWidth = 3;
	$polygon->strokeColor = new Color(0xff, 0, 0);
	$polygon->fillColor = new Color(0, 0, 0xff);
	$polygon->draw();
	
	$rect = new Rectangle($context, new Rect(350, 300, 300, 200));
	$rect->lineWidth = 3;
	$rect->strokeColor = new Color(0xff, 0, 0);
	$rect->draw();
	
	
	$arc = new Arc($context, new Point(500, 400), 300, 200, 0, 270);
	$arc->lineWidth = 2;
	$arc->fillColor = new Color(0, 0xcc, 0);
	$arc->draw();
	
	$circle = new Circle($context, new Point(400, 200), 100);
	$circle->fillColor = new Color(0xcc, 0xcc, 0);
	$circle->draw();
	
	
	$lines = new Lines($context);
	for ($i = 1; $i < 5; ++$i) {
		$lines->add(new Point(500, 50*$i), new Point(700, 50*$i));
	}
	$lines->draw();
	
	
	
	$xAxis = new Axis($context, Axis::X, new Point(100, 300), 600, 10);
	$xAxis->draw();
	$text = new Text($context, new Point(700, 300), 'x');
	$text->draw();
	$yAxis = new Axis($context, Axis::Y, new Point(400, 600), 600, 10);
	$yAxis->draw();
	$text = new Text($context, new Point(390, 0), 'y');
	$text->draw();
	
	
	$sineFunc = new Func($context, sin, new Range(0, 50), new Point(100, 350), 100, 30, 30);
	$sineFunc->draw();
	
	$cosineFunc = new Func($context, cos, new Range(0, 50), new Point(100, 300), 500, 30, 30);
	$cosineFunc->strokeColor = new Color(0, 0xff, 0xff);
	$cosineFunc->draw();
	
	$tanFunc = new Func($context, tan, new Range(0, 50), new Point(100, 300), 500, 30, 30);
	$tanFunc->draw();

	
	/*
	 * y = x;
	 */
	function line($x) {
		return $x;
	}
	
	/*
	 * y = x^2;
	 */
	function powerx($x) {
		return $x*$x;
	}
	
	/*
	 * 第一個參數是畫布
	 * 第二個參數是你定義的函數
	 * 第三個參數是x軸變化範圍[0-50)
	 * 第四個參數是原點在畫布的位置
	 * 第五個參數是精度
	 * 第六個參數是x軸縮放比例
	 * 第七哥參數是y軸縮放比例
	 */
	$func = new Func($context, powerx, new Range(-10, 10), new Point(400, 300), 1000, 30, 30);
	$func->draw();
	
	
	
	$context->echoPNG();
	
?>

效果


發佈了34 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章