效果很炫的投影(純CSS+JS)

來源:互聯網
上載者:User
文章目錄
  • OpenLaszlo DHTML CSS 3 demo – to Flash or not to Flash, is no question!
OpenLaszlo DHTML CSS 3 demo – to Flash or not to Flash, is no question!

by Raju Bitter on August 25, 2009

Since the OpenLaszlo DHTML runtime has been released, I’ve been wondering if there’ll ever be the time for me to say: “I can imagine that Flash won’t be a necessity for visually very appealing RIAs!” That time has come, thanks to the incredible work on great open source projects like the Firefox browser or Webkit.

Judge for yourself, here are two versions (DHTML/JavaScript and SWF9) of a demo application, that was inspired by Zachary Johnson’s great CSS3 text-shadow demo. This is the OpenLaszlo DHTML/JavaScript version of the demo, and as always with the advanced CSS features, you need a modern browser for it to work (I’ve successfully tested with Firefox 3.5+, Safari 4.x or Webkit Nighly Build, Google Chrome and Opera 10):

Please upgrade your browser

And in case you wonder, what the SWF9 version of this application looks like, here it is. Even after so many years of working with OpenLaszlo it’s still surprising to see how well the platform renders applications across runtimes.

I believe this demo underlines what I’ve said in my previous blog, that OpenLaszlo can be one of the key technologys to drive adoption of standards like HTML 5 and CSS3 extensions in the RIA space, providing a backup version of an application in Flash for Internet Explorer 6/7 and older browsers. And who would choose Flash, if you can get exact the same visual results with open standards!

Update: Some people have requested the source code for this example. This is the main LZX file, and here is a link to the ZIP file containing the graphic resources as well. I ran tested with OpenLaszlo 4.5.1 and Trunk.

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <!-- * GPL_COPYRIGHT_BEGIN ***********************************************   
  3. * Copyright 2009 Raju Bitter   
  4. * Use is subject to license terms.   
  5. * This program is free software: you can redistribute it and/or modify   
  6. * it under the terms of the GNU General Public License as published by   
  7. * the Free Software Foundation, either version 3 of the License, or   
  8. * any later version.   
  9. *   
  10. * This program is distributed in the hope that it will be useful,   
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of   
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   
  13. * GNU General Public License for more details.   
  14. *   
  15. * You should have received a copy of the GNU General Public License   
  16. * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. * GPL_COPYRIGHT__END ****************************************************** -->   
  18. <canvas width="600" height="400" bgcolor="#FFFFFF" proxied="true">   
  19.   <!-- Resources -->   
  20.   <resource name="spotlightRes" src="spotlight.png" />   
  21.   <resource name="openlaszloRes" src="OpenLaszlo-Header.png" />   
  22.   <!-- reposition boxes depending on mouse x-pos -->   
  23.   <handler name="onmousemove" reference="lz.GlobalMouse"><![CDATA[   
  24. var posX = canvas.getMouse('x');   
  25. var posY = canvas.getMouse('y');   
  26. if (posX>0 &amp;amp;&amp;amp; posY>0 &amp;amp;&amp;amp; posX<canvas.width &amp;amp;&amp;amp; posY<canvas.height) {   
  27.       spotlight.setAttribute("x", (posX-spotlight.width/2));   
  28.       spotlight.setAttribute("y", (posY-spotlight.height/2));   
  29. // Calculate angel and distance
  30. var xx = posX - canvas.width/2;   
  31. var yy = (posY - canvas.height/2);   
  32. var distance = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));   
  33. var angle = Math.atan(yy/xx)/(Math.PI/180);   
  34. if (xx<0){   
  35.         angle+=180   
  36.       }   
  37. if(xx>=0 &amp;amp;&amp;amp; yy<0) {   
  38.         angle+=360   
  39.       }   
  40.       theText.setAttribute("distance", distance/2);   
  41.       theText.setAttribute("angle", angle+180);   
  42.     }   
  43.   ]]>   
  44.   </handler>   
  45.   <class name="demotext" extends="text">   
  46.       <!-- AS3 import statements -->   
  47.       <switch>   
  48.         <when property="$as3">   
  49.           <passthrough>   
  50. import flash.filters.DropShadowFilter;   
  51.           </passthrough>   
  52.         </when>   
  53.       </switch>   
  54.       <!-- Shadow distance -->   
  55.       <attribute name="distance" value="12" />   
  56.       <!-- Shadow angle -->   
  57.       <attribute name="angle" value="0" />   
  58.       <!-- blur X  -->   
  59.       <attribute name="blurx" value="5" />   
  60.       <!-- blur Y -->   
  61.       <attribute name="blury" value="5" />   
  62.       <!-- xoffset for CSS DropBox -->   
  63.       <attribute name="__xoffset" value="0" />   
  64.       <!-- yoffset for CSS DropBox -->   
  65.       <attribute name="__yoffset" value="0" />   
  66.       <!-- Reference to the Flash DropShadowFilter object -->   
  67.       <attribute name="shadowfilter" value="null" />   
  68.       <handler name="oninit">   
  69. this.addBoxShadow()   
  70.       </handler>   
  71.       <method name="addBoxShadow">   
  72. if ($dhtml) {   
  73. // lz.text clipping active, which would cut off the shadow in DHTML
  74. // Workaround for http://jira.openlaszlo.org/jira/browse/LPP-8415
  75. this.getMCRef().style.overflow = "visible";   
  76. this.getMCRef().firstChild.style.overflow = "visible";   
  77. this.getMCRef().firstChild.style.clip = "";   
  78. this.cssCalculateOffset();   
  79. var cssString = "#333 "+ __xoffset +"px "+ __yoffset+"px "+ blurx + "px";   
  80.           Debug.write(cssString);   
  81. this.getMCRef().style.textShadow = cssString;   
  82.         } else {   
  83. /* DropShadowFilter constructor values:
  84.            *  [distance:Number]
  85.            *  [angle:Number]
  86.            *  [color:Number]
  87.            *  [alpha:Number]
  88.            *  [blurX:Number]
  89.            *  [blurY:Number]
  90.            *  [strength:Number]
  91.            *  [quality:Number]
  92.            *  [inner:Boolean]
  93.            *  [knockout:Boolean]
  94.            *  [hideObject:Boolean])
  95.            */
  96. this.shadowfilter = new flash.filters.DropShadowFilter(this.distance, this.angle,   
  97.               0x333333, 0.95, this.blurx, this.blury, 1, 2, false, false, false);   
  98. // Have to remove mask on sprite for SWF8 runtime
  99. // Workaround for http://jira.openlaszlo.org/jira/browse/LPP-8426
  100. if ($as2) {   
  101. this.sprite.removeMask();   
  102.           }   
  103.           updateSWFFilter();   
  104.         }   
  105.       </method>   
  106.       <handler name="onangle">   
  107. if ($as2 || $as3) {   
  108. this.shadowfilter.angle = this.angle;   
  109. this.shadowfilter.distance = this.distance;   
  110. this.shadowfilter.blurX = this.blurx;   
  111. this.shadowfilter.blurY = this.blurx;   
  112.           updateSWFFilter();   
  113.         } else if ($dhtml) {   
  114. this.cssCalculateOffset();   
  115. var cssString = "#333 "+ __xoffset +"px "+ __yoffset+"px "+ blurx + "px";   
  116. this.getMCRef().style.textShadow = cssString;   
  117.         }   
  118.       </handler>   
  119.       <method name="updateSWFFilter">   
  120. this.sprite.getMCRef().filters = [this.shadowfilter];   
  121.       </method>   
  122.       <method name="cssCalculateOffset">   
  123. // CSS3 doesn't use angle, but x/y offset. So we need to
  124. // translate from angle and distance to x and y offset for CSS3.
  125. // Math.cos and Math.cos are based on radians, not degrees
  126. var radians = this.angle * Math.PI/180;   
  127. this.__xoffset = Math.round(Math.cos(radians) * this.distance);   
  128. this.__yoffset = Math.round(Math.sin(radians) * this.distance);   
  129.       </method>   
  130.   </class>   
  131.   <demotext align="center" y="${canvas.height/2-this.height}" id="theText" clip="false"
  132.         fontsize="70" fontstyle="bold" fgcolor="#2c657a" opacity="1.0">OpenLaszlo</demotext>   
  133.   <view id="wall" resource="openlaszloRes" y="${canvas.height-180}" />   
  134.   <view id="spotlight" x="$once{canvas.width/2-this.width/2}" y="$once{canvas.height/2-this.height/2}" resource="spotlightRes" />   
  135. </canvas> 
<?xml version="1.0" encoding="utf-8"?><!-- * GPL_COPYRIGHT_BEGIN *********************************************** * Copyright 2009 Raju Bitter * Use is subject to license terms. * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program.  If not, see <http://www.gnu.org/licenses/>. * GPL_COPYRIGHT__END ****************************************************** --><canvas width="600" height="400" bgcolor="#FFFFFF" proxied="true">  <!-- Resources -->  <resource name="spotlightRes" src="spotlight.png" />  <resource name="openlaszloRes" src="OpenLaszlo-Header.png" />  <!-- reposition boxes depending on mouse x-pos -->  <handler name="onmousemove" reference="lz.GlobalMouse"><![CDATA[    var posX = canvas.getMouse('x');    var posY = canvas.getMouse('y');    if (posX>0 &amp;amp;&amp;amp; posY>0 &amp;amp;&amp;amp; posX<canvas.width &amp;amp;&amp;amp; posY<canvas.height) {      spotlight.setAttribute("x", (posX-spotlight.width/2));      spotlight.setAttribute("y", (posY-spotlight.height/2));      // Calculate angel and distance      var xx = posX - canvas.width/2;      var yy = (posY - canvas.height/2);      var distance = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));      var angle = Math.atan(yy/xx)/(Math.PI/180);      if (xx<0){        angle+=180      }      if(xx>=0 &amp;amp;&amp;amp; yy<0) {        angle+=360      }      theText.setAttribute("distance", distance/2);      theText.setAttribute("angle", angle+180);    }  ]]>  </handler>  <class name="demotext" extends="text">      <!-- AS3 import statements -->      <switch>        <when property="$as3">          <passthrough>                        import flash.filters.DropShadowFilter;          </passthrough>        </when>      </switch>      <!-- Shadow distance -->      <attribute name="distance" value="12" />      <!-- Shadow angle -->      <attribute name="angle" value="0" />      <!-- blur X  -->      <attribute name="blurx" value="5" />      <!-- blur Y -->      <attribute name="blury" value="5" />      <!-- xoffset for CSS DropBox -->      <attribute name="__xoffset" value="0" />      <!-- yoffset for CSS DropBox -->      <attribute name="__yoffset" value="0" />      <!-- Reference to the Flash DropShadowFilter object -->      <attribute name="shadowfilter" value="null" />      <handler name="oninit">        this.addBoxShadow()      </handler>      <method name="addBoxShadow">        if ($dhtml) {          // lz.text clipping active, which would cut off the shadow in DHTML          // Workaround for http://jira.openlaszlo.org/jira/browse/LPP-8415          this.getMCRef().style.overflow = "visible";          this.getMCRef().firstChild.style.overflow = "visible";          this.getMCRef().firstChild.style.clip = "";          this.cssCalculateOffset();          var cssString = "#333 "+ __xoffset +"px "+ __yoffset+"px "+ blurx + "px";          Debug.write(cssString);          this.getMCRef().style.textShadow = cssString;        } else {          /* DropShadowFilter constructor values:           *  [distance:Number]           *  [angle:Number]           *  [color:Number]           *  [alpha:Number]           *  [blurX:Number]           *  [blurY:Number]           *  [strength:Number]           *  [quality:Number]           *  [inner:Boolean]           *  [knockout:Boolean]           *  [hideObject:Boolean])           */          this.shadowfilter = new flash.filters.DropShadowFilter(this.distance, this.angle,              0x333333, 0.95, this.blurx, this.blury, 1, 2, false, false, false);          // Have to remove mask on sprite for SWF8 runtime          // Workaround for http://jira.openlaszlo.org/jira/browse/LPP-8426          if ($as2) {            this.sprite.removeMask();          }          updateSWFFilter();        }      </method>      <handler name="onangle">        if ($as2 || $as3) {          this.shadowfilter.angle = this.angle;          this.shadowfilter.distance = this.distance;          this.shadowfilter.blurX = this.blurx;          this.shadowfilter.blurY = this.blurx;          updateSWFFilter();        } else if ($dhtml) {          this.cssCalculateOffset();          var cssString = "#333 "+ __xoffset +"px "+ __yoffset+"px "+ blurx + "px";          this.getMCRef().style.textShadow = cssString;        }      </handler>      <method name="updateSWFFilter">          this.sprite.getMCRef().filters = [this.shadowfilter];      </method>      <method name="cssCalculateOffset">        // CSS3 doesn't use angle, but x/y offset. So we need to        // translate from angle and distance to x and y offset for CSS3.        // Math.cos and Math.cos are based on radians, not degrees        var radians = this.angle * Math.PI/180;        this.__xoffset = Math.round(Math.cos(radians) * this.distance);        this.__yoffset = Math.round(Math.sin(radians) * this.distance);      </method>  </class>  <demotext align="center" y="${canvas.height/2-this.height}" id="theText" clip="false"        fontsize="70" fontstyle="bold" fgcolor="#2c657a" opacity="1.0">OpenLaszlo</demotext>  <view id="wall" resource="openlaszloRes" y="${canvas.height-180}" />  <view id="spotlight" x="$once{canvas.width/2-this.width/2}" y="$once{canvas.height/2-this.height/2}" resource="spotlightRes" /></canvas>

And if you built some other cool demos with CSS3 or HTML5 support, please ping me!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.