jablonka.czprosek.czf

weathermap

Subversion Repositories:
[/] [HTML_ImageMap.class.php] - Blame information for rev 36

 

Line No. Rev Author Line
11simandl<?php
2// Copyright Howard Jones, 2005 howie@thingy.com
3// http://wotsit.thingy.com/haj/cacti/
4// Released under the GNU Public License
5 
6// A simple port of the guts of Apache's mod_imap
7// - if you have an image control in a form, it's not really defined what happens to USEMAP
8// attributes. They are allowed in HTML 4.0 and XHTML, but some testing shows that they're
9// basically ignored. So you need to use server-side imagemaps if you want to have a form
10// where you are choosing a verb from (for example) a <SELECT> and also specifying part of
11// an image with an IMAGE control.
12//
13//
14class HTML_ImageMap_Area
15{
16 var $href;
17 var $name;
18 var $id;
19 var $alt;
20 var $extrahtml;
21 
22 function common_html()
23 {
24 $h = "";
25 if($this->name != "")
26 {
27 $h .= " alt=\"".$this->name."\" ";
28 $h .= " id=\"".$this->name."\" ";
29 }
30 if($this->href != "")
31 {
32 $h .= " href=\"".$this->href."\" ";
33 }
34 if($this->extrahtml != "")
35 {
36 $h .= " ".$this->extrahtml." ";
37 }
38 return $h;
39 }
40 
41}
42 
43class HTML_ImageMap_Area_Polygon extends HTML_ImageMap_Area
44{
45 var $points = array();
46 var $minx,$maxx,$miny,$maxy; // bounding box
47 var $npoints;
48 
49 function asHTML()
50 {
51 foreach ($this->points as $point)
52 {
53 $flatpoints[] = $point[0];
54 $flatpoints[] = $point[1];
55 }
56 $coordstring = join(",",$flatpoints);
57 
58 return '<area'.$this->common_html().' shape="poly" coords="'.$coordstring.'" />';
59 }
60 
61 function asJSON()
62 {
63 $json = "{ shape:'poly', npoints:".$this->npoints.", name:'".$this->name."',";
64 
65 $xlist = '';
66 $ylist = '';
67 foreach ($this->points as $point)
68 {
69 $xlist .= $point[0].",";
70 $ylist .= $point[1].",";
71 }
72 $xlist = rtrim($xlist,", ");
73 $ylist = rtrim($ylist,", ");
74 $json .= " x: [ $xlist ], y:[ $ylist ], minx: ".$this->minx.", miny: ".$this->miny.", maxx:".$this->maxx.", maxy:".$this->maxy."}";
75 
76 return($json);
77 }
78 
79 function hitTest($x,$y)
80 {
81 $c = 0;
82 // do the easy bounding-box test first.
83 if( ($x < $this->minx) || ($x>$this->maxx) || ($y<$this->miny) || ($y>$this->maxy))
84 {
85 return false;
86 }
87 
88 // Algotithm from from
89 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html#The%20C%20Code
90 for ($i = 0, $j = $this->npoints-1; $i < $this->npoints; $j = $i++)
91 {
92 // print "Checking: $i, $j\n";
93 $x1 = $this->points[$i][0];
94 $y1 = $this->points[$i][1];
95 $x2 = $this->points[$j][0];
96 $y2 = $this->points[$j][1];
97 
98 // print "($x,$y) vs ($x1,$y1)-($x2,$y2)\n";
99 
100 if (((($y1<=$y) && ($y<$y2)) || (($y2<=$y) && ($y<$y1))) &&
101 ($x < ($x2 - $x1) * ($y - $y1) / ($y2 - $y1) + $x1))
102 {
103 $c = !$c;
104 }
105 }
106 
107 return ($c);
108 }
109 
110 function HTML_ImageMap_Area_Polygon ( $name="", $href="",$coords)
111 {
112 $c = $coords[0];
113 
114 $this->name = $name;
115 $this->href= $href;
116 $this->npoints = count($c)/2;
117 
118 if( intval($this->npoints) != ($this->npoints))
119 {
120 die("Odd number of points!");
121 }
122 
123 for ($i=0; $i<count($c); $i+=2)
124 {
125 $x = intval($c[$i]);
126 $y = intval($c[$i+1]);
127 $point = array($x,$y);
128 $xlist[] = $x; // these two are used to get the bounding box in a moment
129 $ylist[] = $y;
130 $this->points[] = $point;
131 }
132 
133 $this->minx = min($xlist);
134 $this->maxx = max($xlist);
135 $this->miny = min($ylist);
136 $this->maxy = max($ylist);
137 
138 // print $this->asHTML()."\n";
139 }
140 
141}
142 
143class HTML_ImageMap_Area_Rectangle extends HTML_ImageMap_Area
144{
145 var $x1,$x2,$y1,$y2;
146 
147 function HTML_ImageMap_Area_Rectangle ( $name="", $href="",$coords)
148 {
149 
150 $c = $coords[0];
151 
152 $x1 = $c[0];
153 $y1 = $c[1];
154 $x2 = $c[2];
155 $y2 = $c[3];
156 
157 // sort the points, so that the first is the top-left
158 if($x1>$x2)
159 {
160 $this->x1=$x2;
161 $this->x2=$x1;
162 }
163 else
164 {
165 $this->x1=$x1;
166 $this->x2=$x2;
167 }
168 
169 if($y1>$y2)
170 {
171 $this->y1=$y2;
172 $this->y2=$y1;
173 }
174 else
175 {
176 $this->y1=$y1;
177 $this->y2=$y2;
178 }
179 
180 $this->name = $name;
181 $this->href = $href;
182 }
183 
184 function hitTest($x,$y)
185 {
186 return ( ($x > $this->x1) && ($x < $this->x2) && ($y > $this->y1) && ($y < $this->y2) );
187 }
188 
189 function asHTML()
190 {
191 $coordstring = join(",",array($this->x1,$this->y1,$this->x2,$this->y2));
192 return '<area'.$this->common_html().' shape="rect" coords="'.$coordstring.'" />';
193 
194 }
195 
196 function asJSON()
197 {
198 $json = "{ shape:'rect', ";
199 
200 $json .= " x1:".$this->x1.", y1:".$this->y1.", x2:".$this->x2.", y2:".$this->y2.",name:'".$this->name."'}";
201 
202 return($json);
203 }
204 
205}
206 
207class HTML_ImageMap_Area_Circle extends HTML_ImageMap_Area
208{
209 var $centx,$centy, $edgex, $edgey;
210 
211 function asHTML()
212 {
213 $coordstring = join(",",array($this->centx,$this->centy,$this->edgex,$this->edgey) );
214 return '<area'.$this->common_html().' shape="circle" coords="'.$coordstring.'" />';
215 }
216 
217 function hitTest($x,$y)
218 {
219 $radius1 = ($this->edgey - $this->centy) * ($this->edgey - $this->centy)
220 + ($this->edgex - $this->centx) * ($this->edgex - $this->centx);
221 
222 $radius2 = ($this->edgey - $y) * ($this->edgey - $y)
223 + ($this->edgex - $x) * ($this->edgex - $x);
224 
225 return ($radius2 <= $radius1);
226 }
227 
228 function HTML_ImageMap_Area_Circle($name="", $href="",$coords)
229 {
230 $c = $coords[0];
231 
232 $this->name = $name;
233 $this->href = $href;
234 $this->centx = $c[0];
235 $this->centy = $c[1];
236 $this->edgex = $c[2];
237 $this->edgey = $c[3];
238 }
239}
240 
241class HTML_ImageMap
242{
243 var $shapes;
244 var $nshapes;
245 var $name;
246 
247 function HTML_ImageMap($name="")
248 {
249 $this->Reset();
250 $this->name = $name;
251 }
252 
253 function Reset()
254 {
255 $this->shapes = array();
256 $this->nshapes = 0;
257 $this->name = "";
258 }
259 
260 // add an element to the map - takes an array with the info, in a similar way to HTML_QuickForm
261 function addArea($element)
262 {
263 if (is_object($element) && is_subclass_of($element, 'html_imagemap_area')) {
264 $elementObject = &$element;
265 } else {
266 $args = func_get_args();
267 $className = "HTML_ImageMap_Area_".$element;
268 $elementObject =& new $className($args[1],$args[2],array_slice($args, 3));
269 }
270 
271 $this->shapes[] =& $elementObject;
272 $this->nshapes++;
273 // print $this->nshapes." shapes\n";
274 }
275 
276 // do a hit-test based on the current map
277 // - can be limited to only match elements whose names match the filter
278 // (e.g. pick a building, in a campus map)
279 function hitTest($x,$y,$namefilter="")
280 {
281 $preg = '/'.$namefilter.'/';
282 foreach ($this->shapes as $shape)
283 {
284 if($shape->hitTest($x,$y))
285 {
286 if( ($namefilter == "") || ( preg_match($preg,$shape->name) ) )
287 {
288 return $shape->name;
289 }
290 }
291 }
292 return false;
293 }
294 
295 // update a property on all elements in the map that match a name
296 // (use it for retro-actively adding in link information to a pre-built geometry before generating HTML)
297 // returns the number of elements that were matched/changed
298 function setProp($which, $what, $where)
299 {
300 
301 $count = 0;
302 for($i=0; $i<count($this->shapes); $i++)
303 {
304 // this USED to be a substring match, but that broke some things
305 // and wasn't actually used as one anywhere.
306 if( ($where == "") || ( $this->shapes[$i]->name==$where) )
307 {
308 switch($which)
309 {
310 case 'href':
311 $this->shapes[$i]->href= $what;
312 break;
313 case 'extrahtml':
314 $this->shapes[$i]->extrahtml= $what;
315 break;
316 }
317 $count++;
318 }
319 }
320 return $count;
321 }
322 
323 // Return the imagemap as an HTML client-side imagemap for inclusion in a page
324 function asHTML()
325 {
326 $html = '<map';
327 if($this->name != "")
328 {
329 $html .= ' name="'.$this->name.'"';
330 }
331 $html .=">\n";
332 foreach ($this->shapes as $shape)
333 {
334 $html .= $shape->asHTML();
335 $html .= "\n";
336 }
337 $html .= "</map>\n";
338 
339 return $html;
340 }
341 
342 function subJSON($namefilter="",$reverseorder=false)
343 {
344 $json = '';
345 
346 $preg = '/'.$namefilter.'/';
347 foreach ($this->shapes as $shape)
348 {
349 if( ($namefilter == "") || ( preg_match($preg,$shape->name) ))
350 {
351 if($reverseorder)
352 {
353 $json = $shape->asJSON().",\n".$json;
354 }
355 else
356 {
357 $json .= $shape->asJSON().",\n";
358 }
359 }
360 }
361 $json = rtrim($json,"\n, ");
362 $json .= "\n";
363 
364 return $json;
365 }
366 
367 // return HTML for a subset of the map, specified by the filter string
368 // (suppose you want some partof your UI to have precedence over another part
369 // - the imagemap is checked from top-to-bottom in the HTML)
370 function subHTML($namefilter="",$reverseorder=false)
371 {
372 $html = "";
373 $preg = '/'.$namefilter.'/';
374 
375 foreach ($this->shapes as $shape)
376 {
377 if( ($namefilter == "") || ( preg_match($preg,$shape->name) ))
378 {
379 if($reverseorder)
380 {
381 $html = $shape->asHTML()."\n".$html;
382 }
383 else
384 {
385 $html .= $shape->asHTML()."\n";
386 }
387 
388 }
389 }
390 return $html;
391 }
392 
393}
394// vim:ts=4:sw=4:
395?>

Powered by WebSVN 2.2.1