CSS3教程

当前位置: HTML5技术网 > CSS3教程 > CSS3火焰文字特效制作教程

CSS3火焰文字特效制作教程

        用一句很俗气的话概括这两天的情况就是:“最近很忙”,虽然手头上有不少很酷的HTML5和CSS3资源,但确实没时间将它们的实现过程写成教程分享给大家。今天刚完成了一个神秘的项目,空下来来博客园写点东西。今天给大家分享2个CSS3火焰文字特效,并且将实现的思路和核心代码写成教程分享给大家。
第一个是静态的火焰文字效果,先看看效果图:



看着图的效果很酷吧。
同时你也可以在这里查看火焰文字的DEMO演示。
下面是实现的源码,由于是静态的文字效果,所以代码相当比较简单。
HTML代码,就一个h1标签:


  1. <h1 id="fire">HTML5 Tricks</h1>
复制代码

然后是CSS3代码:


  1. #fire{
  2. text-align: center;
  3. margin: 100px auto;
  4. font-family: "Comic Sans MS";
  5. font-size: 80px;
  6. color: white;
  7. text-shadow: 0 0 20px #fefcc9, 10px -10px 30px #feec85, -20px -20px 40px #ffae34, 20px -40px 50px #ec760c, -20px -60px 60px #cd4606, 0 -80px 70px #973716, 10px -90px 80px #451b0e;

  8. }

  9. body {background:black; }
复制代码

       这里简单说一下,主要是用了CSS3的text-shadow属性实现文字阴影,这里定义了7层的层叠阴影,用阶梯变化的颜色和一定的阴影半径模拟出火焰从里到外的颜色渐变。


         第二个是带动画的火焰文字特效,说实话,和上一个相比,这个不怎么像火焰,但我还是称它火焰吧。先来看看效果图:



看看,是不是很大气。
要看动起来的效果,可以查看DEMO演示。
然后再分析一下源代码,由于涉及到CSS3动画,所以利用了JS代码动态改变CSS样式。
先是HTML代码,构造了一个div容器:


  1. <div id="canvasContainer"></div>
复制代码

下面是JS代码:


  1. function Stats()
  2. {
  3.   this.init();
  4. }

  5. Stats.prototype =
  6.   {
  7.   init: function()
  8.   {
  9.     this.frames = 0;
  10.     this.framesMin = 100;
  11.     this.framesMax = 0;

  12.     this.time = new Date().getTime();
  13.     this.timePrev = new Date().getTime();

  14.     this.container = document.createElement("div");
  15.     this.container.style.position = 'absolute';
  16.     this.container.style.fontFamily = 'Arial';
  17.     this.container.style.fontSize = '10px';
  18.     this.container.style.backgroundColor = '#000020';
  19.     this.container.style.opacity = '0.9';
  20.     this.container.style.width = '80px';
  21.     this.container.style.paddingTop = '2px';

  22.     this.framesText = document.createElement("div");
  23.     this.framesText.style.color = '#00ffff';
  24.     this.framesText.style.marginLeft = '3px';
  25.     this.framesText.style.marginBottom = '3px';
  26.     this.framesText.innerHTML = '<strong>FPS</strong>';
  27.     this.container.appendChild(this.framesText);

  28.     this.canvas = document.createElement("canvas");
  29.     this.canvas.width = 74;
  30.     this.canvas.height = 30;
  31.     this.canvas.style.display = 'block';
  32.     this.canvas.style.marginLeft = '3px';
  33.     this.canvas.style.marginBottom = '3px';
  34.     this.container.appendChild(this.canvas);

  35.     this.context = this.canvas.getContext("2d");
  36.     this.context.fillStyle = '#101030';
  37.     this.context.fillRect(0, 0, this.canvas.width, this.canvas.height );

  38.     this.contextImageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height);

  39.     setInterval( bargs( function( _this ) { _this.update(); return false; }, this ), 1000 );
  40.   },

  41.   getDisplayElement: function()
  42.   {
  43.     return this.container;
  44.   },

  45.   tick: function()
  46.   {
  47.     this.frames++;
  48.   },

  49.   update: function()
  50.   {
  51.     this.time = new Date().getTime();

  52.     this.fps = Math.round((this.frames * 1000 ) / (this.time - this.timePrev)); //.toPrecision(2);

  53.     this.framesMin = Math.min(this.framesMin, this.fps);
  54.     this.framesMax = Math.max(this.framesMax, this.fps);

  55.     this.framesText.innerHTML = '<strong>' + this.fps + ' FPS</strong> (' + this.framesMin + '-' + this.framesMax + ')';

  56.     this.contextImageData = this.context.getImageData(1, 0, this.canvas.width - 1, 30);
  57.     this.context.putImageData(this.contextImageData, 0, 0);

  58.     this.context.fillStyle = '#101030';
  59.     this.context.fillRect(this.canvas.width - 1, 0, 1, 30);

  60.     this.index = ( Math.floor(30 - Math.min(30, (this.fps / 60) * 30)) );

  61.     this.context.fillStyle = '#80ffff';
  62.     this.context.fillRect(this.canvas.width - 1, this.index, 1, 1);

  63.     this.context.fillStyle = '#00ffff';
  64.     this.context.fillRect(this.canvas.width - 1, this.index + 1, 1, 30 - this.index);

  65.     this.timePrev = this.time;
  66.     this.frames = 0;
  67.   }
  68. }

  69. // Hack by Spite

  70. function bargs( _fn )
  71. {
  72.   var args = [];
  73.   for( var n = 1; n < arguments.length; n++ )
  74.     args.push( arguments[ n ] );
  75.   return function () { return _fn.apply( this, args ); };
  76. }


  77. (function (window){

  78.   var Sakri = window.Sakri || {};
  79.   window.Sakri = window.Sakri || Sakri;

  80.   Sakri.MathUtil = {};

  81.   //return number between 1 and 0
  82.   Sakri.MathUtil.normalize = function(value, minimum, maximum){
  83.     return (value - minimum) / (maximum - minimum);
  84.   };

  85.   //map normalized number to values
  86.   Sakri.MathUtil.interpolate = function(normValue, minimum, maximum){
  87.     return minimum + (maximum - minimum) * normValue;
  88.   };

  89.   //map a value from one set to another
  90.   Sakri.MathUtil.map = function(value, min1, max1, min2, max2){
  91.     return Sakri.MathUtil.interpolate( Sakri.MathUtil.normalize(value, min1, max1), min2, max2);
  92.   };


  93.   Sakri.MathUtil.hexToRgb = function(hex) {
  94.     // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  95.     var shorthandRegex = /^#?([a-fd])([a-fd])([a-fd])$/i;
  96.     hex = hex.replace(shorthandRegex, function(m, r, g, b) {
  97.       return r + r + g + g + b + b;
  98.     });

  99.     var result = /^#?([a-fd]{2})([a-fd]{2})([a-fd]{2})$/i.exec(hex);
  100.     return result ? {
  101.       r: parseInt(result[1], 16),
  102.       g: parseInt(result[2], 16),
  103.       b: parseInt(result[3], 16)
  104.     } : null;
  105.   }

  106.   Sakri.MathUtil.getRandomNumberInRange = function(min, max){
  107.     return min + Math.random() * (max - min);
  108.   };

  109.   Sakri.MathUtil.getRandomIntegerInRange = function(min, max){
  110.     return Math.round(Sakri.MathUtil.getRandomNumberInRange(min, max));
  111.   };


  112. }(window));


  113. //has a dependency on Sakri.MathUtil

  114. (function (window){

  115.   var Sakri = window.Sakri || {};
  116.   window.Sakri = window.Sakri || Sakri;

  117.   Sakri.Geom = {};

  118.   //==================================================
  119.   //=====================::POINT::====================
  120.   //==================================================

  121.   Sakri.Geom.Point = function (x,y){
  122.     this.x = isNaN(x) ? 0 : x;
  123.     this.y = isNaN(y) ? 0 : y;
  124.   };

  125.   Sakri.Geom.Point.prototype.clone = function(){
  126.     return new Sakri.Geom.Point(this.x,this.y);
  127.   };

  128.   Sakri.Geom.Point.prototype.update = function(x, y){
  129.     this.x = isNaN(x) ? this.x : x;
  130.     this.y = isNaN(y) ? this.y : y;
  131.   };


  132.   //==================================================
  133.   //===================::RECTANGLE::==================
  134.   //==================================================

  135.   Sakri.Geom.Rectangle = function (x, y, width, height){
  136.     this.update(x, y, width, height);
  137.   };

  138.   Sakri.Geom.Rectangle.prototype.update = function(x, y, width, height){
  139.     this.x = isNaN(x) ? 0 : x;
  140.     this.y = isNaN(y) ? 0 : y;
  141.     this.width = isNaN(width) ? 0 : width;
  142.     this.height = isNaN(height) ? 0 : height;
  143.   };

  144.   Sakri.Geom.Rectangle.prototype.getRight = function(){
  145.     return this.x + this.width;
  146.   };

  147.   Sakri.Geom.Rectangle.prototype.getBottom = function(){
  148.     return this.y + this.height;
  149.   };

  150.   Sakri.Geom.Rectangle.prototype.getCenter = function(){
  151.     return new Sakri.Geom.Point(this.getCenterX(), this.getCenterY());
  152.   };

  153.   Sakri.Geom.Rectangle.prototype.getCenterX = function(){
  154.     return this.x + this.width/2;
  155.   };

  156.   Sakri.Geom.Rectangle.prototype.getCenterY=function(){
  157.     return this.y + this.height/2;
  158.   };

  159.   Sakri.Geom.Rectangle.prototype.containsPoint = function(x, y){
  160.     return x >= this.x && y >= this.y && x <= this.getRight() && y <= this.getBottom();
  161.   };


  162.   Sakri.Geom.Rectangle.prototype.clone = function(){
  163.     return new Sakri.Geom.Rectangle(this.x, this.y, this.width, this.height);
  164.   };

  165.   Sakri.Geom.Rectangle.prototype.toString = function(){
  166.     return "Rectangle{x:"+this.x+" , y:"+this.y+" , width:"+this.width+" , height:"+this.height+"}";
  167.   };


  168. }(window));



  169. /**
  170.      * Created by sakri on 27-1-14.
  171.      * has a dependecy on Sakri.Geom
  172.      * has a dependecy on Sakri.BitmapUtil
  173.      */

  174. (function (window){

  175.   var Sakri = window.Sakri || {};
  176.   window.Sakri = window.Sakri || Sakri;

  177.   Sakri.CanvasTextUtil = {};

  178.   //returns the biggest font size that best fits into given width
  179.   Sakri.CanvasTextUtil.getFontSizeForWidth = function(string, fontProps, width, canvas, fillStyle, maxFontSize){
  180.     if(!canvas){
  181.       var canvas = document.createElement("canvas");
  182.     }
  183.     if(!fillStyle){
  184.       fillStyle = "#000000";
  185.     }
  186.     if(isNaN(maxFontSize)){
  187.       maxFontSize = 500;
  188.     }
  189.     var context = canvas.getContext('2d');
  190.     context.font = fontProps.getFontString();
  191.     context.textBaseline = "top";

  192.     var copy = fontProps.clone();
  193.     //console.log("getFontSizeForWidth() 1  : ", copy.fontSize);
  194.     context.font = copy.getFontString();
  195.     var textWidth = context.measureText(string).width;

  196.     //SOME DISAGREEMENT WHETHER THIS SHOOULD BE WITH && or ||
  197.     if(textWidth < width){
  198.       while(context.measureText(string).width < width){
  199.         copy.fontSize++;
  200.         context.font = copy.getFontString();
  201.         if(copy.fontSize > maxFontSize){
  202.           console.log("getFontSizeForWidth() max fontsize reached");
  203.           return null;
  204.         }
  205.       }
  206.     }else if(textWidth > width){
  207.       while(context.measureText(string).width > width){
  208.         copy.fontSize--;
  209.         context.font = copy.getFontString();
  210.         if(copy.fontSize < 0){
  211.           console.log("getFontSizeForWidth() min fontsize reached");
  212.           return null;
  213.         }
  214.       }
  215.     }
  216.     //console.log("getFontSizeForWidth() 2  : ", copy.fontSize);
  217.     return copy.fontSize;
  218.   };


  219.   //=========================================================================================
  220.   //==============::CANVAS TEXT PROPERTIES::====================================
  221.   //========================================================

  222.   Sakri.CanvasTextProperties = function(fontWeight, fontStyle, fontSize, fontFace){
  223.     this.setFontWeight(fontWeight);
  224.     this.setFontStyle(fontStyle);
  225.     this.setFontSize(fontSize);
  226.     this.fontFace = fontFace ? fontFace : "sans-serif";
  227.   };

  228.   Sakri.CanvasTextProperties.NORMAL = "normal";
  229.   Sakri.CanvasTextProperties.BOLD = "bold";
  230.   Sakri.CanvasTextProperties.BOLDER = "bolder";
  231.   Sakri.CanvasTextProperties.LIGHTER = "lighter";

  232.   Sakri.CanvasTextProperties.ITALIC = "italic";
  233.   Sakri.CanvasTextProperties.OBLIQUE = "oblique";


  234.   Sakri.CanvasTextProperties.prototype.setFontWeight = function(fontWeight){
  235.     switch (fontWeight){
  236.       case Sakri.CanvasTextProperties.NORMAL:
  237.       case Sakri.CanvasTextProperties.BOLD:
  238.       case Sakri.CanvasTextProperties.BOLDER:
  239.       case Sakri.CanvasTextProperties.LIGHTER:
  240.         this.fontWeight = fontWeight;
  241.         break;
  242.       default:
  243.         this.fontWeight = Sakri.CanvasTextProperties.NORMAL;
  244.     }
  245.   };

  246.   Sakri.CanvasTextProperties.prototype.setFontStyle = function(fontStyle){
  247.     switch (fontStyle){
  248.       case Sakri.CanvasTextProperties.NORMAL:
  249.       case Sakri.CanvasTextProperties.ITALIC:
  250.       case Sakri.CanvasTextProperties.OBLIQUE:
  251.         this.fontStyle = fontStyle;
  252.         break;
  253.       default:
  254.         this.fontStyle = Sakri.CanvasTextProperties.NORMAL;
  255.     }
  256.   };

  257.   Sakri.CanvasTextProperties.prototype.setFontSize = function(fontSize){
  258.     if(fontSize && fontSize.indexOf && fontSize.indexOf("px")>-1){
  259.       var size = fontSize.split("px")[0];
  260.       fontProperites.fontSize = isNaN(size) ? 24 : size;//24 is just an arbitrary number
  261.       return;
  262.     }
  263.     this.fontSize = isNaN(fontSize) ? 24 : fontSize;//24 is just an arbitrary number
  264.   };

  265.   Sakri.CanvasTextProperties.prototype.clone = function(){
  266.     return new Sakri.CanvasTextProperties(this.fontWeight, this.fontStyle, this.fontSize, this.fontFace);
  267.   };

  268.   Sakri.CanvasTextProperties.prototype.getFontString = function(){
  269.     return this.fontWeight + " " + this.fontStyle + " " + this.fontSize + "px " + this.fontFace;
  270.   };

  271. }(window));


  272. window.requestAnimationFrame =
  273.         window.__requestAnimationFrame ||
  274.                 window.requestAnimationFrame ||
  275.                 window.webkitRequestAnimationFrame ||
  276.                 window.mozRequestAnimationFrame ||
  277.                 window.oRequestAnimationFrame ||
  278.                 window.msRequestAnimationFrame ||
  279.                 (function () {
  280.                     return function (callback, element) {
  281.                         var lastTime = element.__lastTime;
  282.                         if (lastTime === undefined) {
  283.                             lastTime = 0;
  284.                         }
  285.                         var currTime = Date.now();
  286.                         var timeToCall = Math.max(1, 33 - (currTime - lastTime));
  287.                         window.setTimeout(callback, timeToCall);
  288.                         element.__lastTime = currTime + timeToCall;
  289.                     };
  290.                 })();

  291. var readyStateCheckInterval = setInterval( function() {
  292.     if (document.readyState === "complete") {
  293.         clearInterval(readyStateCheckInterval);
  294.         init();
  295.     }
  296. }, 10);

  297. //========================
  298. //general properties for demo set up
  299. //========================

  300. var canvas;
  301. var context;
  302. var canvasContainer;
  303. var htmlBounds;
  304. var bounds;
  305. var minimumStageWidth = 250;
  306. var minimumStageHeight = 250;
  307. var maxStageWidth = 1000;
  308. var maxStageHeight = 600;
  309. var resizeTimeoutId = -1;
  310. var stats;

  311. function init(){
  312.     canvasContainer = document.getElementById("canvasContainer");
  313.     window.onresize = resizeHandler;
  314.     stats = new Stats();
  315.     canvasContainer.appendChild( stats.getDisplayElement() );
  316.     commitResize();
  317. }

  318. function getWidth( element ){return Math.max(element.scrollWidth,element.offsetWidth,element.clientWidth );}
  319. function getHeight( element ){return Math.max(element.scrollHeight,element.offsetHeight,element.clientHeight );}

  320. //avoid running resize scripts repeatedly if a browser window is being resized by dragging
  321. function resizeHandler(){
  322.     context.clearRect(0,0,canvas.width, canvas.height);
  323.     clearTimeout(resizeTimeoutId);
  324.     clearTimeoutsAndIntervals();
  325.     resizeTimeoutId = setTimeout(commitResize, 300 );
  326. }

  327. function commitResize(){
  328.     if(canvas){
  329.         canvasContainer.removeChild(canvas);
  330.     }
  331.     canvas = document.createElement('canvas');
  332.     canvas.style.position = "absolute";
  333.     context = canvas.getContext("2d");
  334.     canvasContainer.appendChild(canvas);

  335.     htmlBounds = new Sakri.Geom.Rectangle(0,0, getWidth(canvasContainer) , getHeight(canvasContainer));
  336.     if(htmlBounds.width >= maxStageWidth){
  337.         canvas.width = maxStageWidth;
  338.         canvas.style.left = htmlBounds.getCenterX() - (maxStageWidth/2)+"px";
  339.     }else{
  340.         canvas.width = htmlBounds.width;
  341.         canvas.style.left ="0px";
  342.     }
  343.     if(htmlBounds.height > maxStageHeight){
  344.         canvas.height = maxStageHeight;
  345.         canvas.style.top = htmlBounds.getCenterY() - (maxStageHeight/2)+"px";
  346.     }else{
  347.         canvas.height = htmlBounds.height;
  348.         canvas.style.top ="0px";
  349.     }
  350.     bounds = new Sakri.Geom.Rectangle(0,0, canvas.width, canvas.height);
  351.     context.clearRect(0,0,canvas.width, canvas.height);

  352.     if(bounds.width<minimumStageWidth || bounds.height<minimumStageHeight){
  353.         stageTooSmallHandler();
  354.         return;
  355.     }

  356.     var textInputSpan = document.getElementById("textInputSpan");
  357.     textInputSpan.style.top = htmlBounds.getCenterY() + (bounds.height/2) + 20 +"px";
  358.     textInputSpan.style.left = (htmlBounds.getCenterX() - getWidth(textInputSpan)/2)+"px";

  359.     startDemo();
  360. }

  361. function stageTooSmallHandler(){
  362.     var warning = "Sorry, bigger screen required :(";
  363.     context.font = "bold normal 24px sans-serif";
  364.     context.fillText(warning, bounds.getCenterX() - context.measureText(warning).width/2, bounds.getCenterY()-12);
  365. }




  366. //========================
  367. //Demo specific properties
  368. //========================

  369. var animating = false;
  370. var particles = [];
  371. var numParticles = 4000;
  372. var currentText = "SAKRI";
  373. var fontRect;
  374. var fontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 100);
  375. var animator;
  376. var particleSource = new Sakri.Geom.Point();;
  377. var particleSourceStart = new Sakri.Geom.Point();
  378. var particleSourceTarget = new Sakri.Geom.Point();

  379. var redParticles = ["#fe7a51" , "#fdd039" , "#fd3141"];
  380. var greenParticles = ["#dbffa6" , "#fcf8fd" , "#99de5e"];
  381. var pinkParticles = ["#fef4f7" , "#f2a0c0" , "#fb3c78"];
  382. var yellowParticles = ["#fdfbd5" , "#fff124" , "#f4990e"];
  383. var blueParticles = ["#9ca2df" , "#222a6d" , "#333b8d"];

  384. var particleColorSets = [redParticles, greenParticles, pinkParticles, yellowParticles, blueParticles];
  385. var particleColorIndex = 0;

  386. var renderParticleFunction;
  387. var renderBounds;
  388. var particleCountOptions = [2000, 4000, 6000, 8000, 10000, 15000, 20000 ];
  389. var pixelParticleCountOptions = [10000, 40000, 60000, 80000, 100000, 150000 ];

  390. function clearTimeoutsAndIntervals(){
  391.     animating = false;
  392. }

  393. function startDemo(){

  394.     fontRect = new Sakri.Geom.Rectangle(Math.floor(bounds.x + bounds.width*.2), 0, Math.floor(bounds.width - bounds.width*.4), bounds.height);
  395.     fontProperties.fontSize = 100;
  396.     fontProperties.fontSize = Sakri.CanvasTextUtil.getFontSizeForWidth(currentText, fontProperties, fontRect.width, canvas);
  397.     fontRect.y = Math.floor(bounds.getCenterY() - fontProperties.fontSize/2);
  398.     fontRect.height = fontProperties.fontSize;
  399.     renderBounds = fontRect.clone();
  400.     renderBounds.x -= Math.floor(canvas.width *.1);
  401.     renderBounds.width += Math.floor(canvas.width *.2);
  402.     renderBounds.y -= Math.floor(fontProperties.fontSize *.5);
  403.     renderBounds.height += Math.floor(fontProperties.fontSize *.6);
  404.     context.font = fontProperties.getFontString();

  405.     createParticles();
  406.     context.globalAlpha = globalAlpha;
  407.     animating = true;
  408.     loop();
  409. }


  410. function loop(){
  411.     if(!animating){
  412.         return;
  413.     }
  414.     stats.tick();
  415.     renderParticles();
  416.     window.requestAnimationFrame(loop, canvas);
  417. }


  418. function createParticles(){
  419.     context.clearRect(0,0,canvas.width, canvas.height);
  420.     context.fillText(currentText, fontRect.x, fontRect.y);
  421.     var imageData = context.getImageData(fontRect.x, fontRect.y, fontRect.width, fontRect.height);
  422.     var data = imageData.data;
  423.     var length = data.length;
  424.     var rowWidth = fontRect.width*4;
  425.     var i, y, x;

  426.     particles = [];
  427.     for(i=0; i<length; i+=4){
  428.         if(data[i+3]>0){
  429.             y = Math.floor(i / rowWidth);
  430.             x = fontRect.x + (i - y * rowWidth) / 4;
  431.             particles.push(x);//x
  432.             particles.push(fontRect.y + y);//y
  433.             particles.push(x);//xOrigin
  434.             particles.push(fontRect.y + y);//yOrigin
  435.         }
  436.     }

  437.     //console.log(particles.length);
  438.     context.clearRect(0,0,canvas.width, canvas.height);

  439.     //pre calculate random numbers used for particle movement
  440.     xDirections = [];
  441.     yDirections = [];
  442.     for(i=0; i<directionCount; i++){
  443.         xDirections[i] = -7 + Math.random() * 14;
  444.         yDirections[i] = Math.random()* - 5;
  445.     }
  446. }


  447. var xDirections, yDirections;
  448. //fidget with these to manipulate effect
  449. var globalAlpha = .11; //amount of trails or tracers
  450. var xWind = 0; //all particles x is effected by this
  451. var threshold = 60; //if a pixels red component is less than this, return particle to it's original position
  452. var amountRed = 25; //amount of red added to a pixel occupied by a particle
  453. var amountGreen = 12; //amount of green added to a pixel occupied by a particle
  454. var amountBlue = 1; //amount of blue added to a pixel occupied by a particle
  455. var directionCount = 100; //number of random pre-calculated x and y directions

  456. function renderParticles(){
  457.     //fill renderBounds area with a transparent black, and render a nearly black text
  458.     context.fillStyle = "#000000";
  459.     context.fillRect(renderBounds.x, renderBounds.y, renderBounds.width, renderBounds.height);
  460.     context.fillStyle = "#010000";
  461.     context.fillText(currentText, fontRect.x, fontRect.y);

  462.     var randomRed = amountRed -5 + Math.random()*10;
  463.     var randomGreen = amountGreen -2 + Math.random()*4;

  464.     var imageData = context.getImageData(renderBounds.x, renderBounds.y, renderBounds.width, renderBounds.height);
  465.     var data = imageData.data;
  466.     var rowWidth = imageData.width * 4;
  467.     var index, i, length = particles.length;
  468.     var d = Math.floor(Math.random()*30);
  469.     xWind += (-.5 + Math.random());//move randomly left or right
  470.     xWind = Math.min(xWind, 1.5);//clamp to a maximum wind
  471.     xWind = Math.max(xWind, -1.5);//clamp to a minimum wind
  472.     for(i=0; i<length; i+=4, d++ ){

  473.         particles[i] += (xDirections[d % directionCount] + xWind);
  474.         particles[i+1] += yDirections[d % directionCount];

  475.         index = Math.round(particles[i] - renderBounds.x) * 4 + Math.round(particles[i+1] - renderBounds.y) * rowWidth;

  476.         data[index] += randomRed;
  477.         data[index + 1] += randomGreen;
  478.         data[index + 2] += amountBlue;

  479.         //if pixels red component is below set threshold, return particle to orgin
  480.         if( data[index] < threshold){
  481.             particles[i] = particles[i+2];
  482.             particles[i+1] = particles[i+3];
  483.         }
  484.     }
  485.     context.putImageData(imageData, renderBounds.x, renderBounds.y);
  486. }



  487. var maxCharacters = 10;

  488. function changeText(){
  489.     var textInput = document.getElementById("textInput");
  490.     if(textInput.value && textInput.text!=""){
  491.         if(textInput.value.length > maxCharacters){
  492.             alert("Sorry, there is only room for "+maxCharacters+" characters. Try a shorter name.");
  493.             return;
  494.         }
  495.         if(textInput.value.indexOf(" ")>-1){
  496.             alert("Sorry, no support for spaces right now :(");
  497.             return;
  498.         }
  499.         currentText = textInput.value;
  500.         clearTimeoutsAndIntervals();
  501.         animating = false;
  502.         setTimeout(commitResize, 100);
  503.     }
  504. }

  505. function changeSettings(){
  506.     clearTimeoutsAndIntervals();
  507.     animating = false;
  508.     setTimeout(commitResize, 100);
  509. }

  510. function setParticleNumberOptions(values){
  511.     var selector = document.getElementById("particlesSelect");
  512.     if(selector.options.length>0 && parseInt(selector.options[0].value) == values[0] ){
  513.         return;
  514.     }
  515.     while(selector.options.length){
  516.         selector.remove(selector.options.length-1);
  517.     }
  518.     for(var i=0;i <values.length; i++){
  519.         selector.options[i] = new Option(values[i], values[i], i==0, i==0);
  520.     }
  521. }
复制代码

        这两款CSS3火焰文字效果都还不错吧,如果你真的对HTML5感兴趣,可以点这里邮件订阅一下,注意需要登录邮箱确认订阅,这样有好的HTML5资源我会用邮件发送给你。


        另外,如果你有微博,也可以用微博关注获取最新的HTML5资源和教程,

【CSS3火焰文字特效制作教程】相关文章

1. CSS3火焰文字特效制作教程

2. CSS3 3D镂空文字特效

3. 一款非常棒的纯CSS3 3D菜单演示及制作教程

4. 简单做出HTML5翻页效果文字特效

5. 10个很棒的 jQuery 插件和制作教程

6. 基于css3的文字3D翻转特效

7. 视频教程:CSS3动画属性实用技巧教程

8. CSS3的文字阴影—Text-Shadow

9. CSS3 HTML5实例三(块阴影与文字阴影)

10. CSS3每日一练之选择器-插入文字

本文来源:https://www.51html5.com/a1059.html

点击展开全部

﹝CSS3火焰文字特效制作教程﹞相关内容

「CSS3火焰文字特效制作教程」相关专题

其它栏目

也许您还喜欢