(SOFT) SOFT (2011 год)

OpenSource Freeware FotoSlider on Flex 3 and jQuery.

To view this page ensure that Adobe Flash Player version 10.0.0 or greater is installed.

Велосипедные и лыжные маршруты из Жулебино



В начале 2011-го года я познакомился с платформой Flex и написал Мой первый фото-слайдер на Flex 4. В дальнейшем проект фотослайдера для компании VOTPUSK.RU стал развиваться своим путем - у него появились оооочень специфические параметры и режимы работы, кроме того у этого фотослайдера весьма специфический стиль.


Я решил сделать более универсальный фотослайдер, который бы в отличие от фотослайдера для компании вотпуск.ру


Надеюсь, тот кто внимательно прочитал эти отличия OpenSource слайдера и слайдера Вотпуска, тот поймет, что при некоторой внешней похожести (и глобально-общем принципе построения) - у этих продуктов нет практически ничего общего в областях применения (и в нынешнем состоянии этих двух слайдров у них совпадает всего 20% программного кода слайдера). В сущности у этих слайдров общими остались только строки 146-167.


Итак, перейдем к рассмотрению кода моего OpenSource-фотослайдера:


   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
   3:                 xmlns:s="library://ns.adobe.com/flex/spark" 
   4:                 xmlns:mx="library://ns.adobe.com/flex/mx"
   5:                 applicationComplete="application1_applicationCompleteHandler(event)">
   6:      
   7:      <fx:Script>
   8:          
   9:          <![CDATA[
  10:              import flash.filters.DropShadowFilter;
  11:              import mx.collections.ArrayCollection;
  12:              import mx.containers.HBox;
  13:              import mx.controls.Alert;
  14:              import mx.controls.Image;
  15:              import mx.core.UIComponent;
  16:              import mx.events.FlexEvent;
  17:              import mx.rpc.events.ResultEvent;
  18:              import spark.components.BorderContainer;
  19:              import spark.core.NavigationUnit;
  20:              
  21:              
  22:              [Bindable]
  23:              public var BestFoto:mx.collections.ArrayCollection ;
  24:              public var params:Object;
  25:              public var ShadowFilter : DropShadowFilter ;
  26:              public var BgColor:String;
  27:              public var CurrentLoadImageNum:int
  28:              public var RequestTimer:Timer = new Timer(500, 100);
  29:              
  30:              protected function application1_applicationCompleteHandler(event:FlexEvent):void
  31:              {
  32:                  BestFoto= new mx.collections.ArrayCollection();
  33:                  params = mx.core.FlexGlobals.topLevelApplication.parameters;
  34:                  if (!params.hasOwnProperty("BestFotoList")) {
  35:                      // "http://imageslider.vb-net.com/getimagename.ashx?all=1"
  36:                      Alert.show("flashvars parameters 'BestFotoList' not set.");
  37:                      return;
  38:                  }
  39:                  if (!params.hasOwnProperty("BaseUrl")) {
  40:                      // http://imageslider.vb-net.com/ImageSlider/
  41:                      Alert.show("flashvars parameters 'BaseURL' not set.");
  42:                      return;
  43:                  }
  44:                  if (!params.hasOwnProperty("Color")) {
  45:                      // "#FDF5E6"
  46:                      BgColor="#FFFFFF";
  47:                  }
  48:                      else{
  49:                      BgColor=params.Color;
  50:                  }
  51:                  GetFoto.url=params.BestFotoList; 
  52:                  this.setStyle( "backgroundColor", BgColor)
  53:                  
  54:                  try    {
  55:                      ExternalInterface.addCallback("containerresize", FlashContainerResize);
  56:                  }
  57:                  catch (e:Error){
  58:                  }
  59:                  
  60:                  ShadowFilter  = ShadowEffect();
  61:                  go_left.filters = [ ShadowFilter ];
  62:                  go_right.filters = [ ShadowFilter ];
  63:                  
  64:                  try
  65:                  {
  66:                      GetFoto.send();
  67:                  }
  68:                  catch(e:Error){
  69:                      return;
  70:                  }
  71:   
  72:                  try    {
  73:                      ExternalInterface.call("flashresize");
  74:                  }
  75:                  catch (e:Error){
  76:                  }
  77:              }
  78:              
  79:              protected function FlashContainerResize (width1:int,heigth1:int):void {
  80:                  HGroup1.width=width1-80;
  81:              }
  82:              
  83:              protected function GetFotoReadEnd(event:ResultEvent):void
  84:              {
  85:                  var i:int;
  86:                  BestFoto = event.result.BestFotoNumbers.BestFoto;
  87:                  HGroup1.visible=false;
  88:                                          
  89:                  if (BestFoto.list.length>10){
  90:                      AddMyElement(0,10);
  91:                      var BorderContainerTmp:BorderContainer = HGroup1.getElementAt(4) as BorderContainer;
  92:                      var ImageTmp:Image=    BorderContainerTmp.getElementAt(0) as Image;
  93:                      ImageTmp.addEventListener("complete",ImageLoad_completeHandler);
  94:                  }
  95:                  else {
  96:                      AddMyElement(0,BestFoto.list.length);
  97:                      HGroup1.visible=true;
  98:                  }
  99:              }
 100:              
 101:              protected function ImageLoad_completeHandler(event:Event):void
 102:              {
 103:                  HGroup1.visible=true;
 104:                  RequestTimer.start();
 105:                  CurrentLoadImageNum=10;
 106:                  RequestTimer.addEventListener(TimerEvent.TIMER, Timer_completeHandler);
 107:              }
 108:              
 109:              protected function Timer_completeHandler(event:Event):void
 110:              {
 111:                  AddMyElement(CurrentLoadImageNum,CurrentLoadImageNum+10);    
 112:                  CurrentLoadImageNum+=10
 113:              }
 114:              
 115:              protected function AddMyElement (From:int, To:int):void {
 116:                  var j:int;
 117:                  for (j=From;j<To;j++) {
 118:                      if (j<BestFoto.list.length){
 119:                          var NewBorderContainer:BorderContainer = new BorderContainer;
 120:                          NewBorderContainer.width = 152;
 121:                          NewBorderContainer.height = 108;
 122:                          NewBorderContainer.setStyle("backgroundColor", 0xD4D0C8);
 123:                          NewBorderContainer.setStyle("borderColor", 0xD4D0C8);
 124:                          NewBorderContainer.filters = [ ShadowFilter ];
 125:                  
 126:                          var NewImage:Image = new Image;
 127:                          NewImage.width=150;
 128:                          NewImage.height=100;
 129:                          NewImage.maintainAspectRatio =false;
 130:                          NewImage.addEventListener(MouseEvent.CLICK,NewImage_clickHandler);
 131:                          NewImage.addEventListener(MouseEvent.ROLL_OVER,NewImage_MouseOverHandler);
 132:                          NewImage.addEventListener(MouseEvent.MOUSE_OUT,NewImage_MouseOutHandler);
 133:                          NewImage.source=params.BaseUrl + BestFoto[j].Small;
 134:                          NewImage.data=params.BaseUrl + BestFoto[j].Big;
 135:                          NewImage.setStyle('mouseDownEffect', GlowImage);
 136:                          NewImage.verticalCenter=0;
 137:                          NewImage.horizontalCenter=0;
 138:                      
 139:                          NewBorderContainer.addElement(NewImage);
 140:                          HGroup1.addElement(NewBorderContainer);
 141:                      }
 142:                      else RequestTimer.stop();
 143:                  }
 144:              }
 145:              
 146:              protected function scrollToThere(dir:uint):void {
 147:                  var value:Number = HGroup1.getHorizontalScrollPositionDelta(dir);
 148:                  if (value != 0) {
 149:                      pth.valueBy = value;
 150:                      anim.play();
 151:                  }
 152:                  else
 153:                  {
 154:                      if(dir == NavigationUnit.PAGE_RIGHT)
 155:                      {
 156:                          value = HGroup1.getHorizontalScrollPositionDelta(NavigationUnit.HOME);
 157:                          pth.valueBy = value;
 158:                          anim.play();
 159:                      }
 160:                      if(dir == NavigationUnit.PAGE_LEFT)
 161:                      {
 162:                          value = HGroup1.getHorizontalScrollPositionDelta(NavigationUnit.END);
 163:                          pth.valueBy = value;
 164:                          anim.play();
 165:                      }
 166:                  }
 167:              }
 168:   
 169:              protected function NewImage_clickHandler(event:MouseEvent):void
 170:              {
 171:                  var Image1:Image=event.currentTarget as Image;
 172:                  var url:String = Image1.data.toString();
 173:                  //var request:flash.net.URLRequest = new URLRequest(url);
 174:                  try { 
 175:                      ExternalInterface.call("requestimage",url);
 176:                      //navigateToURL(request, "_blank");
 177:                  }
 178:                  catch (e:Error) {
 179:                      return;
 180:                  }
 181:              }
 182:   
 183:              
 184:              protected function NewImage_MouseOverHandler(event:MouseEvent):void
 185:              {
 186:                  var Image1:Image=event.currentTarget as Image
 187:                  Image1.buttonMode = true;
 188:                  Image1.useHandCursor = true;
 189:                  var NewBorderContainer:BorderContainer = Image1.parent.parent.parent as BorderContainer
 190:                  NewBorderContainer.setStyle("backgroundColor", 0x3380DD);
 191:                  NewBorderContainer.setStyle("borderColor", 0x3380DD);
 192:              
 193:              }
 194:              
 195:              protected function NewImage_MouseOutHandler(event:MouseEvent):void
 196:              {
 197:                  var Image1:Image=event.currentTarget  as Image
 198:                  Image1.buttonMode = false;
 199:                  Image1.useHandCursor = false;
 200:                  var NewBorderContainer:BorderContainer = Image1.parent.parent.parent as BorderContainer
 201:                  NewBorderContainer.setStyle("backgroundColor", 0xD4D0C8);
 202:                  NewBorderContainer.setStyle("borderColor", 0xD4D0C8);
 203:              }
 204:          
 205:   
 206:              protected function go_right_mouseOverHandler(event:MouseEvent):void
 207:              {
 208:                  go_right.useHandCursor = true;
 209:                  go_right.buttonMode= true;
 210:              }
 211:   
 212:              protected function go_left_mouseOverHandler(event:MouseEvent):void
 213:              {
 214:                  go_left.useHandCursor = true;
 215:                  go_left.buttonMode= true;
 216:              }
 217:   
 218:              protected function ShadowEffect():flash.filters.DropShadowFilter
 219:              {
 220:                  var filter : DropShadowFilter = new DropShadowFilter();
 221:                  filter.blurX = 4;
 222:                  filter.blurY = 4;
 223:                  filter.quality = 2;
 224:                  filter.alpha = 0.5;
 225:                  filter.angle = 45;
 226:                  filter.color = 0x202020;
 227:                  filter.distance = 6;
 228:                  filter.inner = false;
 229:                  return filter
 230:              }
 231:   
 232:          ]]>
 233:      </fx:Script>
 234:          
 235:      <fx:Declarations>    
 236:          <!-- Place non-visual elements (e.g., services, value objects) here -->
 237:          <s:HTTPService id="GetFoto" result="GetFotoReadEnd(event)" />
 238:   
 239:          <s:Animate id="anim" target="{HGroup1}" duration="500">
 240:              <s:motionPaths>
 241:                  <s:SimpleMotionPath id="pth" property="horizontalScrollPosition" />
 242:              </s:motionPaths>
 243:          </s:Animate>
 244:      
 245:          <mx:Glow id="GlowImage" duration="1000" alphaFrom="0.3" alphaTo="1.0" blurXFrom="50.0" blurXTo="0.0" blurYFrom="50.0" blurYTo="0.0" color="0x3380DD"/>
 246:   
 247:      </fx:Declarations>
 248:      
 249:      <s:layout>
 250:          <s:HorizontalLayout gap="10" verticalAlign="middle" columnWidth="740"/>
 251:      </s:layout>
 252:      
 253:      <s:Button label="&lt;" id="go_left"
 254:                click="scrollToThere(NavigationUnit.PAGE_LEFT);"
 255:                width="30" mouseOver="go_left_mouseOverHandler(event)" />
 256:      
 257:      <s:HGroup id="HGroup1" x="52" y="101" width="652" height="125" gap="20" verticalAlign="middle"  variableColumnWidth="false" 
 258:                clipAndEnableScrolling="true" columnWidth="160">
 259:      </s:HGroup>
 260:      
 261:      <s:Button label="&gt;" id="go_right"
 262:                click="scrollToThere(NavigationUnit.PAGE_RIGHT);"
 263:                width="30"  mouseOver="go_right_mouseOverHandler(event)"/>
 264:   
 265:  </s:Application>

Все с самого начала я описывать не буду - отсылаю вас к описанию первой прикидки слайдера вотпуска - Мой первый фото-слайдер на Flex 4 - пройдусь только по ключевым отличиям. Этот слайдер требует всего три понятных параметра, из которых один - цвет фона слайдера, а смысл двух других вполне понятен (строки 33-52). Параметр BestFotoList указывает URL хандлера, который обходит файловую систему и формирует список рисунков для отображения фотослайдером.

Такой хандлер я описал (фактически это серверная часть фотослайдера) - Как сделать простейший Web-handler формирующий XML. Второй параметр BaseUrl - это базовая часть URL (чтобы читать фотки с разнух доменов и не гонять лишнее по сети). Примеры обоих параметров вы видите в коде.

В строках 218-230 определен эффект тени, а в строке 245 фильтр Glow, который используеся для вспышки при клике на фото. Строки 146-167 анимированная прокрутка рисунков.

Основная процедура добавления рисунков 115-144. А вот цепляется она хитро - по таймеру. Сначала загружается фасад слайдера, потом реквесты выдаются по тикам таймера - чтобы не подвисал браузер и канал.



Еще одна важная фишка этого слайдера - то что он не только взаимодействует с сервером, но и активнейшим образом взаиможействует со страничкой - строки 169-181, 79-81, 72-76, 54-58. Это взаимодействие я более ли менее описывал на страничке - Как с помощью jQuery сделать флеш-ролик резиновым. Рисункок конечно показывается на страничке - чтобы он кешировался в браузере, чтобы его можно было просмотреть в полном размере, скопировать или назначить в один клик обоями рабочего стола. Как вы понимаете, показывать рисунок внутри плеера нет смысла вообще - и я назначения таких слайдров не понимаю.

Теперь перейдем к рассмотрению собственно кода странички. В основном все осмысленные операции тут выполняются jQuery:

Это исходный шаблон странички (ANT вперемешку с jQuery).


   1:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2:  <!-- saved from url=(0014)about:internet -->
   3:  <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
   4:  <!-- 
   5:      Smart developers always View Source. 
   6:      
   7:      This application was built using Adobe Flex, an open source framework
   8:      for building rich Internet applications that get delivered via the
   9:      Flash Player or to desktops via Adobe AIR. 
  10:      
  11:      Learn more about Flex at http://flex.org 
  12:      // -->
  13:  <head>
  14:      <title>${title}</title>
  15:      <meta name="google" value="notranslate">
  16:      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  17:      <!-- Include CSS to eliminate any default margins/padding and set the height of the html element and 
  18:               the body element to 100%, because Firefox, or any Gecko based browser, interprets percentage as 
  19:               the percentage of the height of its parent container, which has to be set explicitly.  Fix for
  20:               Firefox 3.6 focus border issues.  Initially, don't display flashContent div so it won't show 
  21:               if JavaScript disabled.
  22:          -->
  23:      <style type="text/css" media="screen"> 
  24:              html, body    { height:100%; }
  25:              body { margin:0; padding:0; overflow:auto; text-align:center; 
  26:                     background-color: ${bgcolor}; }   
  27:              object:focus { outline:none; }
  28:              #flashContent { display:none; }
  29:      </style>
  30:      <!-- Enable Browser History by replacing useBrowserHistory tokens with two hyphens -->
  31:      <!-- BEGIN Browser History required section ${useBrowserHistory}>
  32:          <link rel="stylesheet" type="text/css" href="history/history.css" />
  33:          <script type="text/javascript" src="history/history.js"></script>
  34:          <!${useBrowserHistory} END Browser History required section -->
  35:      <script type="text/javascript" src="swfobject.js"></script>
  36:      <script type="text/javascript">
  37:              <!-- For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. --> 
  38:              var swfVersionStr = "${version_major}.${version_minor}.${version_revision}";
  39:              <!-- To use express install, set to playerProductInstall.swf, otherwise the empty string. -->
  40:              var xiSwfUrlStr = "${expressInstallSwf}";
  41:              var flashvars = {};
  42:              flashvars.BestFotoList="http://imageslider.vb-net.com/getimagename.ashx?all=1";
  43:              flashvars.BaseUrl="http://imageslider.vb-net.com/ImageSlider/";
  44:              flashvars.Color="#FDF5E6"
  45:              var params = {};
  46:              params.quality = "high";
  47:              params.bgcolor = "${bgcolor}";
  48:              params.allowscriptaccess = "always";
  49:              params.allowfullscreen = "true";
  50:              var attributes = {};
  51:              attributes.id = "${application}";
  52:              attributes.name = "${application}";
  53:              attributes.align = "middle";
  54:              swfobject.embedSWF(
  55:                  "${swf}.swf", "flashContent", 
  56:                  "${width}", "${height}", 
  57:                  swfVersionStr, xiSwfUrlStr, 
  58:                  flashvars, params, attributes);
  59:              <!-- JavaScript enabled so display the flashContent div in case it is not replaced with a swf object. -->
  60:              swfobject.createCSS("#flashContent", "display:block;text-align:left;");
  61:      </script>
  62:      <script type="text/javascript" src="jquery-1.4.4.min.js"></script>
  63:      <script type="text/javascript" src="dropshadow.jquery.plugin.js"></script>
  64:      <script type="text/javascript">
  65:          $(document).ready(function () {
  66:              $(window).resize(flashresize);
  67:          });
  68:   
  69:      </script>
  70:      <script type="text/javascript">
  71:              function flashresize () {
  72:                  var ContentContainer = $("#ContentContainer")[0];
  73:                  var ${application} = $("#${application}")[0];
  74:                  ${application}.containerresize(ContentContainer.clientWidth, ContentContainer.clientHeight);
  75:                  setshadow();
  76:              }
  77:      </script>
  78:      <script type="text/javascript">
  79:          function requestimage(url) {
  80:              $("#bigimage")[0].src = url;
  81:              setshadow();
  82:          }
  83:      </script>
  84:   
  85:      <script type="text/javascript">
  86:          function setshadow() {
  87:              $('.drop_shadow_layer').remove();
  88:              $('.shadow').dropshadow({
  89:                  shadowColor: '#808080',
  90:                  shadowLayer: -100,
  91:                  distance: '6px',
  92:                  blur: '3px'
  93:              });
  94:          }
  95:      </script>
  96:  </head>
  97:  <body style="background-color:#FDF5E6">
  98:      <!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough 
  99:               JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
 100:               when JavaScript is disabled.
 101:          -->
 102:      <table cellpadding="0" cellspacing="0" border="0" style="width: 100%; height: 126px;">
 103:          <tr>
 104:              <td>
 105:                  <a href="//www.vb-net.com/bike/" target="_blank"><span style="color: Blue; font-size: 20px;
 106:                      text-decoration: none;">Велосипедные и лыжные маршруты из Жулебино</span></a>
 107:              </td>
 108:          </tr>
 109:          <tr>
 110:              <td id="ContentContainer" style="width: 100%; height: 126px;">
 111:                  <div id="flashContent">
 112:                      <p>
 113:                          To view this page ensure that Adobe Flash Player version ${version_major}.${version_minor}.${version_revision}
 114:                          or greater is installed.
 115:                      </p>
 116:                      <script type="text/javascript">
 117:                          var pageHost = ((document.location.protocol == "https:") ? "https://" : "http://");
 118:                          document.write("<a href='http://www.adobe.com/go/getflashplayer'><img src='"
 119:                                  + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /></a>"); 
 120:                      </script>
 121:                  </div>
 122:                  <noscript>
 123:                      <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="${width}" height="${height}"
 124:                          id="${application}">
 125:                          <param name="movie" value="${swf}.swf" />
 126:                          <param name="quality" value="high" />
 127:                          <param name="flashvars" value="BestFotoList='http://imageslider.vb-net.com/getimagename.ashx?all=1'&BaseUrl='http://imageslider.vb-net.com/ImageSlider/'&Color='#FDF5E6'" />
 128:                          <param name="bgcolor" value="${bgcolor}" />
 129:                          <param name="allowScriptAccess" value="always" />
 130:                          <param name="allowFullScreen" value="true" />
 131:                          <!--[if !IE]>-->
 132:                          <object type="application/x-shockwave-flash" data="${swf}.swf" width="${width}" height="${height}">
 133:                              <param name="quality" value="high" />
 134:                              <param name="bgcolor" value="${bgcolor}" />
 135:                              <param name="allowScriptAccess" value="always" />
 136:                              <param name="allowFullScreen" value="true" />
 137:                              <!--<![endif]-->
 138:                              <!--[if gte IE 6]>-->
 139:                              <p>
 140:                                  Either scripts and active content are not permitted to run or Adobe Flash Player
 141:                                  version ${version_major}.${version_minor}.${version_revision} or greater is not
 142:                                  installed.
 143:                              </p>
 144:                              <!--<![endif]-->
 145:                              <a href="http://www.adobe.com/go/getflashplayer">
 146:                                  <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"
 147:                                      alt="Get Adobe Flash Player" />
 148:                              </a>
 149:                              <!--[if !IE]>-->
 150:                          </object>
 151:                          <!--<![endif]-->
 152:                      </object>
 153:                  </noscript>
 154:              </td>
 155:          </tr>
 156:          <tr>
 157:              <td>
 158:                  <div style="height: 20px">
 159:                  </div>
 160:                  <img id="bigimage" style="width: 800px" class="shadow" />
 161:              </td>
 162:          </tr>
 163:      </table>
 164:  </body>
 165:  </html>

Итоговый шаблон получившейся (после прохода FlexBuilder) странички вы можете постмотреть здесь - //www.vb-net.com/flex3/fotoslider.html. Плагин jQuery для отрисовки тени иногда подглючивает - вам ничто не мешает его выбросить вообще.



Comments ( )
Link to this page: //www.vb-net.com/Foto_Slider/index.htm
< THANKS ME>