Classic text effect

Size
11,186 Kb
Views
24,288

How do I make an classic text effect?

Letters fly in and out using random parameters and easing functions. What is a classic text effect? How do you make a classic text effect? This script and codes were developed by Sakri Rosenstrom on 06 September 2022, Tuesday.

Classic text effect Previews

Classic text effect - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Classic text effect</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div id="canvasContainer"></div>
<span id="textInputSpan"> Enter your name (max 8 chars) : <input id="textInput" maxlength="8" type="text" width="150" /> <button onclick="changeText()">GO!</button>
</span> <script src="js/index.js"></script>
</body>
</html>

Classic text effect - Script Codes CSS Codes

html, body{ margin : 0px; width : 100%; height : 100%; overflow: hidden; background-color: #FFFFFF;
}
#canvasContainer{ margin : 0px; width : 100%; height : 100%;
}
#textInputSpan{ position: absolute;
}

Classic text effect - Script Codes JS Codes

/* * * @author Sakri Rosenstrom * * http://www.sakri.net * https://twitter.com/sakri * http://www.devstate.net * Sources for this can be found at: * https://github.com/sakri/sakriNetCommonJS */
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri;	Sakri.MathUtil = {};	//used for radiansToDegrees and degreesToRadians	Sakri.MathUtil.PI_180 = Math.PI/180;	Sakri.MathUtil.ONE80_PI = 180/Math.PI;	//precalculations for values of 90, 270 and 360 in radians	Sakri.MathUtil.PI2 = Math.PI*2;	Sakri.MathUtil.HALF_PI = Math.PI/2;	Sakri.MathUtil.PI_AND_HALF = Math.PI+ Math.PI/2;	Sakri.MathUtil.NEGATIVE_HALF_PI = -Math.PI/2; //keep degrees between 0 and 360 Sakri.MathUtil.constrainDegreeTo360 = function(degree){ return (360 + degree % 360) % 360;//hmmm... looks a bit weird?! }; Sakri.MathUtil.constrainRadianTo2PI = function(rad){ return (Sakri.MathUtil.PI2 + rad % Sakri.MathUtil.PI2) % Sakri.MathUtil.PI2;//equally so... }; Sakri.MathUtil.radiansToDegrees = function(rad){ return rad*Sakri.MathUtil.ONE80_PI; }; Sakri.MathUtil.degreesToRadians = function(degree){ return degree * Sakri.MathUtil.PI_180; };	//return number between 1 and 0	Sakri.MathUtil.normalize = function(value, minimum, maximum){	return (value - minimum) / (maximum - minimum);	};	//map normalized number to values	Sakri.MathUtil.interpolate = function(normValue, minimum, maximum){	return minimum + (maximum - minimum) * normValue;	};	//map a value from one set to another	Sakri.MathUtil.map = function(value, min1, max1, min2, max2){	return Sakri.MathUtil.interpolate( Sakri.MathUtil.normalize(value, min1, max1), min2, max2);	}; Sakri.MathUtil.clamp = function(min,max,value){ if(value < min){ return min; } if(value > max){ return max; } return value; }; Sakri.MathUtil.clampRGB = function(value){ return Sakri.MathUtil.clamp(0, 255, value); };	Sakri.MathUtil.getRandomNumberInRange = function(min, max){	return min + Math.random() * (max - min);	};	Sakri.MathUtil.getRandomIntegerInRange = function(min, max){	return Math.round(Sakri.MathUtil.getRandomNumberInRange(min, max));	};
}(window));
//has a dependency on Sakri.MathUtil
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri;	Sakri.Geom = {}; //================================================== //=====================::POINT::==================== //================================================== Sakri.Geom.Point = function (x,y){ this.x = isNaN(x) ? 0 : x; this.y = isNaN(y) ? 0 : y; }; Sakri.Geom.Point.prototype.clone = function(){ return new Sakri.Geom.Point(this.x,this.y); }; Sakri.Geom.Point.prototype.update = function(x, y){ this.x = isNaN(x) ? this.x : x; this.y = isNaN(y) ? this.y : y; }; Sakri.Geom.Point.prototype.add = function(x, y){ this.x += isNaN(x) ? 0 : x; this.y += isNaN(y) ? 0 : y; }; Sakri.Geom.Point.prototype.equals = function(point){ return this.x==point.x && this.y==point.y; }; Sakri.Geom.Point.prototype.toString = function(){ return "{x:"+this.x+" , y:"+this.y+"}"; }; Sakri.Geom.Point.interpolate = function(pointA, pointB, normal){ return new Sakri.Geom.Point(Sakri.MathUtil.interpolate(normal, pointA.x, pointB.x) , Sakri.MathUtil.interpolate(normal, pointA.y, pointB.y)); }; Sakri.Geom.Point.distanceBetweenTwoPoints = function( point1, point2 ){ //console.log("Math.pow(point2.x - point1.x,2) : ",Math.pow(point2.x - point1.x,2)); return Math.sqrt( Math.pow(point2.x - point1.x,2) + Math.pow(point2.y - point1.y,2) ); }; Sakri.Geom.Point.angleBetweenTwoPoints = function(p1,p2){ return Math.atan2(p1.y-p2.y, p1.x-p2.x); }; Sakri.Geom.mirrorPointInRectangle = function(point,rect){ return new Sakri.Geom.Point(rect.width-point.x,rect.height-point.y); }; Sakri.Geom.randomizePoint = function(point,randomValue){ return new Sakri.Geom.Point(-randomValue+Math.random()*randomValue+point.x,-randomValue+Math.random()*randomValue+point.y); };	//==================================================	//===================::RECTANGLE::==================	//==================================================	Sakri.Geom.Rectangle = function (x, y, width, height){	this.update(x, y, width, height);	};	Sakri.Geom.Rectangle.prototype.update = function(x, y, width, height){	this.x = isNaN(x) ? 0 : x;	this.y = isNaN(y) ? 0 : y;	this.width = isNaN(width) ? 0 : width;	this.height = isNaN(height) ? 0 : height;	}; //TODO : doesn't work Sakri.Geom.Rectangle.prototype.inflate = function(x, y){ this.x -= isNaN(x) ? 0 : x; this.y -= isNaN(y) ? 0 : y; this.width += isNaN(x) ? 0 : x * 2; this.height += isNaN(y) ? 0 : y * 2; };	Sakri.Geom.Rectangle.prototype.updateToRect = function(rect){	this.x = rect.x;	this.y = rect.y;	this.width = rect.width;	this.height = rect.height;	};	Sakri.Geom.Rectangle.prototype.scaleX = function(scaleBy){	this.width *= scaleBy;	};	Sakri.Geom.Rectangle.prototype.scaleY = function(scaleBy){	this.height *= scaleBy;	};	Sakri.Geom.Rectangle.prototype.scale = function(scaleBy){	this.scaleX(scaleBy);	this.scaleY(scaleBy);	};	Sakri.Geom.Rectangle.prototype.getRight = function(){	return this.x + this.width;	};	Sakri.Geom.Rectangle.prototype.getBottom = function(){	return this.y + this.height;	}; Sakri.Geom.Rectangle.prototype.getCenter = function(){ return new Sakri.Geom.Point(this.getCenterX(), this.getCenterY()); }; Sakri.Geom.Rectangle.prototype.getCenterX = function(){ return this.x + this.width/2; }; Sakri.Geom.Rectangle.prototype.getCenterY=function(){ return this.y + this.height/2; }; Sakri.Geom.Rectangle.prototype.containsPoint = function(x, y){ return x >= this.x && y >= this.y && x <= this.getRight() && y <= this.getBottom(); }; Sakri.Geom.Rectangle.prototype.containsRect = function(rect){ return this.containsPoint(rect.x, rect.y) && this.containsPoint(rect.getRight(), rect.getBottom()); };	Sakri.Geom.Rectangle.prototype.isSquare = function(){	return this.width == this.height;	};	Sakri.Geom.Rectangle.prototype.isLandscape = function(){	return this.width > this.height;	};	Sakri.Geom.Rectangle.prototype.isPortrait = function(){	return this.width < this.height;	};	Sakri.Geom.Rectangle.prototype.getSmallerSide = function(){	return Math.min(this.width, this.height);	};	Sakri.Geom.Rectangle.prototype.getBiggerSide = function(){	return Math.max(this.width,this.height);	};	Sakri.Geom.Rectangle.prototype.getArea = function(){	return this.width * this.height;	};	Sakri.Geom.Rectangle.prototype.floor = function(){	this.x = Math.floor(this.x);	this.y = Math.floor(this.y);	this.width = Math.floor(this.width);	this.height = Math.floor(this.height);	};	Sakri.Geom.Rectangle.prototype.ceil = function(){	this.x = Math.ceil(this.x);	this.y = Math.ceil(this.y);	this.width = Math.ceil(this.width);	this.height = Math.ceil(this.height);	};	Sakri.Geom.Rectangle.prototype.round = function(){	this.x=Math.round(this.x);	this.y=Math.round(this.y);	this.width=Math.round(this.width);	this.height=Math.round(this.height);	};	Sakri.Geom.Rectangle.prototype.roundIn = function(){	this.x = Math.ceil(this.x);	this.y = Math.ceil(this.y);	this.width = Math.floor(this.width);	this.height = Math.floor(this.height);	};	Sakri.Geom.Rectangle.prototype.roundOut = function(){	this.x = Math.floor(this.x);	this.y = Math.floor(this.y);	this.width = Math.ceil(this.width);	this.height = Math.ceil(this.height);	};	Sakri.Geom.Rectangle.prototype.clone = function(){	return new Sakri.Geom.Rectangle(this.x, this.y, this.width, this.height);	};	Sakri.Geom.Rectangle.prototype.toString = function(){	return "Rectangle{x:"+this.x+" , y:"+this.y+" , width:"+this.width+" , height:"+this.height+"}";	}; //================================================== //=====================::TRANSFORM::=================== //================================================== Sakri.Geom.setIdentityMatrixToContext = function(context){ context.setTransform(1,0,0,1,0,0); }; //(1,0,0,1,0,0); Sakri.Geom.Transform = function (scaleX, skewX, skewY, scaleY, tx, ty){ this.update(isNaN(scaleX) ? 1 : scaleX, isNaN(skewX) ? 0 : skewX, isNaN(skewY) ? 0 : skewY, isNaN(scaleY) ? 1 : scaleY, isNaN( tx) ? 0 : tx, isNaN(ty) ? 0 : ty); }; Sakri.Geom.Transform.prototype.update = function (scaleX, skewX, skewY, scaleY, tx, ty){ this.scaleX = scaleX; this.skewX = skewX; this.skewY = skewY; this.scaleY = scaleY; this.tx = tx; this.ty = ty; }; Sakri.Geom.Transform.prototype.toString = function() { return "SimpleGeometry.Transform{scaleX:"+this.scaleX+" ,skewX:"+this.skewX+" ,skewY:"+this.skewY+" ,scaleY:"+this.scaleY+" ,tx:"+this.tx+" ,ty:"+this.ty+"}"; };
}(window));
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri; Sakri.BitmapUtil = {}; //TODO : rename "canvas" to "source", if it's an img, create a canvas and draw the img into it Sakri.BitmapUtil.getFirstNonTransparentPixelTopDown = function(canvas){ var context = canvas.getContext("2d"); var y, i, rowData; for(y=0; y<canvas.height; y++){ rowData = context.getImageData(0, y, canvas.width, 1).data; for(i=0; i<rowData.length; i+=4){ if(rowData[i+0] + rowData[i+1] + rowData[i+2] + rowData[i+3] > 0){ return new Sakri.Geom.Point(i/4, y); } } } return null; }; Sakri.BitmapUtil.getFirstNonTransparentPixelBottomUp = function(canvas){ var context = canvas.getContext("2d"); var y, i, rowData; for(y = canvas.height - 1; y>-1; y--){ rowData = context.getImageData(0, y, canvas.width, 1).data; for(i=0; i<rowData.length; i+=4){ if(rowData[i+0] + rowData[i+1] + rowData[i+2] + rowData[i+3] > 0){ return new Sakri.Geom.Point(i/4, y); } } } return null; }; Sakri.BitmapUtil.getFirstNonTransparentPixelLeftToRight = function(canvas){ var context = canvas.getContext("2d"); var x, i, colData; for(x = 0; x < canvas.width; x++){ colData = context.getImageData(x, 0, 1, canvas.height).data; for(i=0; i<colData.length; i+=4){ if(colData[i+0] + colData[i+1] + colData[i+2] + colData[i+3] > 0){ return new Sakri.Geom.Point(x, i/4); } } } return null; }; Sakri.BitmapUtil.getFirstNonTransparentPixelRightToLeft = function(canvas){ var context = canvas.getContext("2d"); var x, i, colData; for(x = canvas.width-1; x >-1; x--){ colData = context.getImageData(x, 0, 1, canvas.height).data; for(i=0; i<colData.length; i+=4){ if(colData[i+0] + colData[i+1] + colData[i+2] + colData[i+3] > 0){ return new Sakri.Geom.Point(x, i/4); } } } return null; }; //cuts out rows and columns of pixels without color data from the top, bottom, left and right Sakri.BitmapUtil.trimImage = function(image){ var trimCanvas = Sakri.BitmapUtil.createTrimmedCanvas(image); image.src = trimCanvas.toDataURL(); }; Sakri.BitmapUtil.trimCanvas = function(canvas){ var trimCanvas = Sakri.BitmapUtil.createTrimmedCanvas(canvas); canvas.width = trimCanvas.width; canvas.height = trimCanvas.height; var context = canvas.getContext("2d"); context.drawImage(trimCanvas, 0, 0); }; Sakri.BitmapUtil.getCanvasTrimRectangle = function(canvas){ var rect = new Sakri.Geom.Rectangle(); rect.x = Sakri.BitmapUtil.getFirstNonTransparentPixelLeftToRight(canvas).x; rect.y = Sakri.BitmapUtil.getFirstNonTransparentPixelTopDown(canvas).y; rect.width = Sakri.BitmapUtil.getFirstNonTransparentPixelRightToLeft(canvas).x - rect.x + 1; rect.height = Sakri.BitmapUtil.getFirstNonTransparentPixelBottomUp(canvas).y - rect.y + 1; return rect; } Sakri.BitmapUtil.createTrimmedCanvas = function(imageOrCanvas){ var trimCanvas = document.createElement("canvas"); var trimContext = trimCanvas.getContext("2d"); trimCanvas.width = imageOrCanvas.width; trimCanvas.height = imageOrCanvas.height; trimContext.drawImage(imageOrCanvas, 0, 0); var rect = Sakri.BitmapUtil.getCanvasTrimRectangle(trimCanvas); //console.log("createTrimmedCanvas() ", rect.toString()); trimCanvas.width = rect.width; trimCanvas.height = rect.height; trimContext = trimCanvas.getContext("2d"); trimContext.drawImage(imageOrCanvas, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height); return trimCanvas; };
}(window));
/** * Created by sakri on 27-1-14. * has a dependecy on Sakri.Geom * has a dependecy on Sakri.BitmapUtil */
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri; Sakri.CanvasTextUtil = {}; Sakri.CanvasTextUtil.resizeCanvasToString = function(canvas, string, fontProps){ var context = canvas.getContext('2d'); context.font = fontProps.getFontString(); context.textBaseline = "top"; var textWidth = context.measureText(string).width; canvas.width = textWidth; canvas.height = fontProps.fontSize * 1.5;//normally descenders shouldn't go below this //after a resize of a canvas, we have to reset these properties context.font = fontProps.getFontString(); context.textBaseline = "top"; context.fillStyle = "#FF0000"; context.fillText(string, 0, 0); var textHeight = Sakri.BitmapUtil.getFirstNonTransparentPixelBottomUp(canvas).y + 4;//this returns a point canvas.width = textWidth; canvas.height = textHeight; } //this method renders text into a canvas, then resizes the image by shrinkPercent //loops through the non transparent pixels of the resized image and returns those as an array //fontProperties should be an object of type Sakri.CanvasTextProperties Sakri.CanvasTextUtil.createTextParticles = function(text, shrinkPercent, fontProps){ var canvas = document.createElement('canvas'); Sakri.CanvasTextUtil.resizeCanvasToString(canvas, text, fontProps); var context = canvas.getContext('2d'); //after a resize of a canvas, we have to reset these properties context.font = fontProps.getFontString();; context.textBaseline = "top"; context.fillStyle = "#FF0000"; context.fillText(text, 0, 0); var shrunkenCanvas = document.createElement('canvas'); shrunkenCanvas.width = Math.round(canvas.width * shrinkPercent); shrunkenCanvas.height = Math.round(canvas.height * shrinkPercent); var shrunkenContext = shrunkenCanvas.getContext('2d'); shrunkenContext.drawImage(canvas, 0, 0, shrunkenCanvas.width , shrunkenCanvas.height ); var pixels = shrunkenContext.getImageData(0, 0, shrunkenCanvas.width, shrunkenCanvas.height); var data = pixels.data; var particles = []; var i, x, y; for(i = 0; i < data.length; i += 4) { if(data[i]>200){ x = ((i/4)%shrunkenCanvas.width)/shrinkPercent; y = Math.floor((i/4)/shrunkenCanvas.width)/shrinkPercent; particles.push(new Sakri.Geom.Point(x, y)); } } delete canvas;//not sure if necessary?! delete shrunkenCanvas; return particles; }; Sakri.CanvasTextUtil.createImagesFromString = function(string, fillStyle, strokeStyle, strokeWidth, fontProps){ var fontString = fontProps.getFontString(); var characters = string.split(""); var images = []; var context, image, metrics, i, character; var canvas = document.createElement("canvas"); for(i=0; i<characters.length; i++){ character = characters[i]; Sakri.CanvasTextUtil.resizeCanvasToString(canvas, character, fontProps); context = canvas.getContext("2d"); //these properties have to be set twice as they vanish after setting a canvas width and height context = canvas.getContext("2d"); context.textBaseline = "top"; context.font = fontString; image = new Image(); image.width = canvas.width; image.height = canvas.height; if(fillStyle){ context.fillStyle = fillStyle; context.fillText (character,0, 0); } if(strokeStyle){ context.strokeStyle = strokeStyle; context.lineWidth = strokeWidth; context.strokeText(character, 0, 0); } image.src = canvas.toDataURL(); images[i] = image; } delete canvas; return images; }; //TODO: implement Sakri.CanvasTextUtil.fitTextIntoRect = function(string, fontProps, rect, canvas, fillStyle){ if(!canvas){ var canvas = document.createElement("canvas"); } if(!fillStyle){ fillStyle = "#000000"; } var context = canvas.getContext('2d'); context.font = fontProps.getFontString(); context.textBaseline = "top"; var fontSize = fontProps.fontSize; context.font = "bold "+fontSize+"px sans-serif"; var width = context.measureText(string).width; if(width < context.width){ while(context.measureText(string).width < rect.width && rect < bounds.height){ fontSize++; context.font = "bold "+fontSize+"px sans-serif"; } }else if(width > context.width){ while(context.measureText(string).width > rect.width && rect > bounds.height){ fontSize--; context.font = "bold "+fontSize+"px sans-serif"; } } canvas.width = context.measureText(string).width; canvas.height = fontSize * 1.5;//1.5 should be enough to cover all descenders context.font = "bold "+fontSize+"px sans-serif"; context.textBaseline = "top"; context.fillStyle = fillStyle; context.fillText(string, 0,0); return Sakri.BitmapUtil.createTrimmedCanvas(canvas); } //========================================================================================= //==============::CANVAS TEXT PROPERTIES::==================================== //======================================================== Sakri.CanvasTextProperties = function(fontWeight, fontStyle, fontSize, fontFace){ this.setFontWeight(fontWeight); this.setFontStyle(fontStyle); this.setFontSize(fontSize); this.fontFace = fontFace ? fontFace : "sans-serif"; }; Sakri.CanvasTextProperties.NORMAL = "normal"; Sakri.CanvasTextProperties.BOLD = "bold"; Sakri.CanvasTextProperties.BOLDER = "bolder"; Sakri.CanvasTextProperties.LIGHTER = "lighter"; Sakri.CanvasTextProperties.ITALIC = "italic"; Sakri.CanvasTextProperties.OBLIQUE = "oblique"; Sakri.CanvasTextProperties.prototype.setFontWeight = function(fontWeight){ switch (fontWeight){ case Sakri.CanvasTextProperties.NORMAL: case Sakri.CanvasTextProperties.BOLD: case Sakri.CanvasTextProperties.BOLDER: case Sakri.CanvasTextProperties.LIGHTER: this.fontWeight = fontWeight; break; default: this.fontWeight = Sakri.CanvasTextProperties.NORMAL; } }; Sakri.CanvasTextProperties.prototype.setFontStyle = function(fontStyle){ switch (fontStyle){ case Sakri.CanvasTextProperties.NORMAL: case Sakri.CanvasTextProperties.ITALIC: case Sakri.CanvasTextProperties.OBLIQUE: this.fontStyle = fontStyle; break; default: this.fontStyle = Sakri.CanvasTextProperties.NORMAL; } }; Sakri.CanvasTextProperties.prototype.setFontSize = function(fontSize){ if(fontSize && fontSize.indexOf && fontSize.indexOf("px")>-1){ var size = fontSize.split("px")[0]; fontProperites.fontSize = isNaN(size) ? 24 : size;//24 is just an arbitrary number return; } this.fontSize = isNaN(fontSize) ? 24 : fontSize;//24 is just an arbitrary number }; Sakri.CanvasTextProperties.prototype.getFontString = function(){ return this.fontWeight + " " + this.fontStyle + " " + this.fontSize + "px " + this.fontFace; };
}(window));
//=========================::UNIT ANIMATOR::===============================
//animates a number from 0-1 (with optional easing) for a given duration and a framerate
//this is used to animate or tweeen visuals which are set up using interpolation
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri;	//constructor, duration and framerate must be in milliseconds	Sakri.UnitAnimator = function(duration, framerate, updateCallBack, completeCallBack){ this.easingFunction = Sakri.UnitAnimator.easeLinear;//default	this.reset(duration, framerate, updateCallBack, completeCallBack);	};	//t is "time" this.millisecondsAnimated	//b is the "beginning" value	//c is "change" or the difference of end-start value	//d is this.duration	//classic Robert Penner easing functions	//http://www.robertpenner.com/easing/	Sakri.UnitAnimator.easeLinear = function(t, b, c, d){	return c * (t / d) + b;	};	//SINE	Sakri.UnitAnimator.easeInSine = function (t, b, c, d){	return -c * Math.cos(t/d * Sakri.MathUtil.HALF_PI) + c + b;	};	Sakri.UnitAnimator.easeOutSine = function (t, b, c, d){	return c * Math.sin(t/d * Sakri.MathUtil.HALF_PI) + b;	};	Sakri.UnitAnimator.easeInOutSine = function (t, b, c, d){	return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;	};	//BOUNCE	Sakri.UnitAnimator.easeInBounce = function(t, b, c, d){	return c - Sakri.UnitAnimator.easeOutBounce (d-t, 0, c, d) + b;	};	Sakri.UnitAnimator.easeOutBounce = function(t, b, c, d){	if ((t/=d) < (1/2.75)) {	return c*(7.5625*t*t) + b;	} else if (t < (2/2.75)) {	return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;	} else if (t < (2.5/2.75)) {	return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;	} else {	return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;	}	};	Sakri.UnitAnimator.easeInOutBounce = function (t, b, c, d){	if (t < d/2){	return Sakri.UnitAnimator.easeInBounce (t*2, 0, c, d) * .5 + b;	}	return Sakri.UnitAnimator.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b;	};	//ELASTIC	Sakri.UnitAnimator.easeInElastic = function(t, b, c, d, a, p){	var s;	if (t==0){	return b;	}	if ((t/=d)==1){	return b+c;	}	if (!p){	p=d*.3;	}	if (!a || a < Math.abs(c)) {	a=c; s=p/4;	}else{	s = p/Sakri.MathUtil.PI2 * Math.asin (c/a);	}	return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*Sakri.MathUtil.PI2/p )) + b;	};	Sakri.UnitAnimator.easeOutElastic = function(t, b, c, d, a, p){	var s;	if (t==0){	return b;	}	if ((t/=d)==1){	return b+c;	}	if (!p){	p=d*.3;	}	if (!a || a < Math.abs(c)) {	a=c; s=p/4;	}else{	s = p/Sakri.MathUtil.PI2 * Math.asin (c/a);	}	return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*Sakri.MathUtil.PI2/p ) + c + b);	};	Sakri.UnitAnimator.easeInOutElastic = function(t, b, c, d, a, p){	var s;	if (t==0){	return b;	}	if ((t/=d/2)==2){	return b+c;	}	if (!p){	p=d*(.3*1.5);	}	if (!a || a < Math.abs(c)) {	a=c; s=p/4;	}else{	s = p/Sakri.MathUtil.PI2 * Math.asin (c/a);	}	if (t < 1){	return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*Sakri.MathUtil.PI2/p )) + b;	}	return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*Sakri.MathUtil.PI2/p )*.5 + c + b;	};	Sakri.UnitAnimator.easingFunctions = [Sakri.UnitAnimator.easeLinear, Sakri.UnitAnimator.easeInSine, Sakri.UnitAnimator.easeOutSine, Sakri.UnitAnimator.easeInOutSine, Sakri.UnitAnimator.easeInBounce, Sakri.UnitAnimator.easeOutBounce, Sakri.UnitAnimator.easeInOutBounce, Sakri.UnitAnimator.easeInElastic, Sakri.UnitAnimator.easeOutElastic, Sakri.UnitAnimator.easeInOutElastic ];	Sakri.UnitAnimator.getRandomEasingFunction = function(){	return Sakri.UnitAnimator.easingFunctions[Math.floor( Math.random()*Sakri.UnitAnimator.easingFunctions.length )];	};	Sakri.UnitAnimator.prototype.setRandomEasingFunction = function(){	this.easingFunction = Sakri.UnitAnimator.getRandomEasingFunction();	};	Sakri.UnitAnimator.prototype.setEasingFunction = function(easingFunction){	if(Sakri.UnitAnimator.easingFunctions.indexOf(easingFunction) > -1){	this.easingFunction = easingFunction;	}	};	//easing (t, b, c, d)	//@t is the current time (or position) of the tween. This can be seconds or frames, steps, seconds, ms, whatever � as long as the unit is the same as is used for the total time [3].	//@b is the beginning value of the property.	//@c is the change between the beginning and destination value of the property.	//@d is the total time of the tween.	Sakri.UnitAnimator.prototype.getAnimationPercent = function(){	return this.easingFunction(Sakri.MathUtil.normalize(this.millisecondsAnimated,0,this.duration),0,1,1);	};	Sakri.UnitAnimator.prototype.isAnimating = function(){	return !isNaN(this.intervalId);	};	Sakri.UnitAnimator.prototype.reset = function(duration,framerate,updateCallBack,completeCallBack){	this.duration = duration;	this.framerate = framerate;	if(framerate > duration){	//throw error?!	}	this.updateCallBack = updateCallBack;	this.completeCallBack = completeCallBack;	this.millisecondsAnimated = 0;//keeps track of how long the animation has been running	};	Sakri.UnitAnimator.prototype.start = function(easingFunction){	//console.log("Sakri.UnitAnimator.start()");	if(easingFunction){	this.setEasingFunction(easingFunction);	}	var _this = this;	this.intervalId = setInterval(function(){_this.update();}, this.framerate);//TODO : find easier to explain solution	};	Sakri.UnitAnimator.prototype.pause = function(){	if(!isNaN(this.intervalId)){	clearInterval(this.intervalId);	} delete this.intervalId;	};	//refactor, make private	Sakri.UnitAnimator.prototype.update = function(){	//console.log("Sakri.UnitAnimator.update()",this.getAnimationPercent());	this.millisecondsAnimated += this.framerate;	if(this.millisecondsAnimated >= this.duration){	//console.log("Sakri.UnitAnimator.update() animation complete");	this.pause();	this.millisecondsAnimated = this.duration;	this.dispatchUpdate();	this.dispatchComplete();	return;	}	this.dispatchUpdate();	};	Sakri.UnitAnimator.prototype.dispatchUpdate = function(){	if(this.updateCallBack){	//console.log("Sakri.UnitAnimator.dispatchUpdate()",this.getAnimationPercent());	this.updateCallBack();	}	};	Sakri.UnitAnimator.prototype.dispatchComplete = function(){	if(this.completeCallBack){	this.completeCallBack();	}	};
}(window));
//has a dependency on Sakri.Geom, extends Sakri.Geom.Point
//=========================::BLOCK SET ANIMATOR::===============================
(function (window){ var Sakri = window.Sakri || {}; window.Sakri = window.Sakri || Sakri;	//width and height are used for sizing/scaling to fit.	Sakri.BlockSetAnimator = function(x, y){	Sakri.Geom.Point.call(this,x,y); //call super constructor.	this.frameRate = 20;	this.intervalId = -1;//make private	this.easingFunction = Sakri.UnitAnimator.easeOutSine;	this.animator = new Sakri.UnitAnimator(1000,20);	this.animator.easingFunction = Sakri.UnitAnimator.easeLinear;	};	//subclass extends superclass	Sakri.BlockSetAnimator.prototype = Object.create(Sakri.Geom.Point.prototype);	Sakri.BlockSetAnimator.prototype.constructor = Sakri.Geom.Point;	Sakri.BlockSetAnimator.prototype.setEasingFunction = function(easingFunction){	this.easingFunction = easingFunction;	};	//Image or Canvas items, or sprite sheet?!	Sakri.BlockSetAnimator.prototype.setImages = function(images){	this.blocks = [];	var blockX = this.x;	for(var i=0; i<images.length; i++){	this.blocks[i] = new Sakri.AnimationBlock(blockX, this.y, images[i]);	blockX += this.blocks[i].width;	}	};	Sakri.BlockSetAnimator.prototype.isAnimating = function(){	return this.animator && this.animator.isAnimating();	};	//Sakri.BlockSetAnimator.prototype.setAnimation = function(transformFrom, transformTo, alphaFrom, alphaTo){	Sakri.BlockSetAnimator.prototype.setAnimation = function(blockTransformFrom, blockTransformTo){	this.transformFrom = blockTransformFrom;	this.transformTo = blockTransformTo;	};	//duration is for the entire animation, delay is the amount of delay between the start of individual block animations	//both numbers are expressed in milliseconds	Sakri.BlockSetAnimator.prototype.start = function(duration, delay, completeCallBack, updateCallBack){	//console.log("Sakri.BlockSetAnimator.start()", duration, delay, this.blocks.length);	if(!this.blocks || this.blocks.length==0){	console.log("Sakri.BlockSetAnimator.start() ERROR : no blocks have been set");	return;	}	this.millisecondsAnimated = 0;	this.duration = duration;	this.blockAnimationDuration = this.duration - delay * (this.blocks.length-1);	//console.log(this.duration, blockAnimationDuration);	this.completeCallBack = completeCallBack ? completeCallBack : undefined;	this.updateCallBack = updateCallBack ? updateCallBack : undefined;	for(var i=0; i<this.blocks.length; i++){	this.blocks[i].animationBeginsAt = delay * i;	this.blocks[i].animationEndsAt = delay * i + this.blockAnimationDuration;	this.blocks[i].copyTransformValues(this.transformFrom);	//console.log("block : ",this.blocks[i].animationBeginsAt, this.blocks[i].animationEndsAt);	}	var _this = this;	this.animator.reset(duration, this.frameRate, function(){_this.update()}, function(){_this.complete()});	this.animator.start();	}; Sakri.BlockSetAnimator.prototype.stop = function(){ this.animator.pause(); }	//only one animator	//"main" animator has a linear ease	//the allocated time is chopped up into "segments" for each Sakri.AnimationBlock	//the segment is then normalized, and this normal is used for the easing function	Sakri.BlockSetAnimator.prototype.pause = function(){	//console.log("Sakri.BlockSetAnimator.prototype.pause()");	//clearInterval(this.intervalId);	};	Sakri.BlockSetAnimator.prototype.resume = function(){	//console.log("Sakri.BlockSetAnimator.prototype.resume()");	};	Sakri.BlockSetAnimator.prototype.reset= function(){	//console.log("Sakri.BlockSetAnimator.prototype.reset()");	};	Sakri.BlockSetAnimator.prototype.reverse = function(){	//console.log("Sakri.BlockSetAnimator.prototype.reverse()");	};	Sakri.BlockSetAnimator.prototype.update = function(){	//console.log("Sakri.BlockSetAnimator.update()",this.millisecondsAnimated);	this.millisecondsAnimated += this.frameRate;	this.dispatchUpdate();	};	//easing (t, b, c, d)	//@t is the current time (or position) of the tween.	//@b is the beginning value of the property.	//@c is the change between the beginning and destination value of the property.	//@d is the total time of the tween.	Sakri.BlockSetAnimator.prototype.setBlockTransform = function(block){	var normal = Sakri.MathUtil.normalize(this.millisecondsAnimated, block.animationBeginsAt, block.animationEndsAt);	block.transform.rotation =	this.easingFunction(normal, this.transformFrom.rotation, this.transformTo.rotation-this.transformFrom.rotation, 1);	block.transform.scale =	this.easingFunction(normal, this.transformFrom.scale, this.transformTo.scale-this.transformFrom.scale, 1);	block.transform.alpha =	this.easingFunction(normal, this.transformFrom.alpha, this.transformTo.alpha-this.transformFrom.alpha, 1);	block.transform.x =	this.easingFunction(normal, this.transformFrom.x, this.transformTo.x - this.transformFrom.x, 1);	block.transform.y =	this.easingFunction(normal, this.transformFrom.y, this.transformTo.y - this.transformFrom.y, 1);	};	Sakri.BlockSetAnimator.prototype.render = function(context){	//console.log("render()");	var block;	Sakri.Geom.setIdentityMatrixToContext(context);	for(var i=0; i<this.blocks.length; i++){	block = this.blocks[i];	if(this.millisecondsAnimated <= block.animationBeginsAt){	block.copyTransformValues(this.transformFrom);	}else if(this.millisecondsAnimated >= block.animationEndsAt){	block.copyTransformValues(this.transformTo);	}else{	this.setBlockTransform(block, i);	}	context.translate(block.x + block.transform.x -block.getTranslateX(), block.y + block.transform.y - block.getTranslateY());	context.rotate(block.transform.rotation);	context.scale(block.transform.scale, block.transform.scale);	context.globalAlpha = block.transform.alpha;	context.drawImage(block.image,block.getTranslateX(),block.getTranslateY());	Sakri.Geom.setIdentityMatrixToContext(context);	}	context.globalAlpha = 1;	};	Sakri.BlockSetAnimator.prototype.dispatchUpdate = function(){	if(this.updateCallBack){	this.updateCallBack();	}	};	Sakri.BlockSetAnimator.prototype.complete = function(){	this.dispatchComplete();	};	Sakri.BlockSetAnimator.prototype.dispatchComplete = function(){	if(this.completeCallBack){	this.completeCallBack();	}	};	//=========================::ANIMATION BLOCK::===============================	Sakri.AnimationBlock = function(x,y,image){	Sakri.Geom.Rectangle.call(this, x, y, image.width, image.height); //call super constructor.	this.image = image;	this.transform = new Sakri.Geom.Transform();	this.skipRender = true; this.animationBeginsAt = 0; this.animationEndsAt = 0;	};	//subclass extends superclass	Sakri.AnimationBlock.prototype = Object.create(Sakri.Geom.Rectangle.prototype);	Sakri.AnimationBlock.prototype.constructor = Sakri.Geom.Rectangle;	Sakri.AnimationBlock.prototype.copyTransformValues = function(transform){	this.transform.scale = transform.scale;	this.transform.rotation = transform.rotation;	this.transform.x = transform.x;	this.transform.y = transform.y;	this.transform.alpha = transform.alpha;	this.transform.horizontalAlign = transform.horizontalAlign;	this.transform.verticalAlign = transform.verticalAlign;	};	Sakri.AnimationBlock.prototype.getTranslateX = function(){	switch(this.transform.horizontalAlign){	case 1:	return -this.width / 2;	case 2:	return -this.width;	}	return 0;	};	Sakri.AnimationBlock.prototype.getTranslateY = function(){	switch(this.transform.verticalAlign){	case 1:	return -this.height / 2;	case 2:	return -this.height;	}	return 0;	};	//=========================::ANIMATION BLOCK TRANFORM::===============================	Sakri.AnimationBlockTransform = function(x, y, scale, rotation, alpha, horizontalAlign, verticalAlign){	this.x = isNaN(x) ? 0 : x;	this.y = isNaN(y) ? 0 : y;	this.scale = isNaN(scale) ? 1 : scale;	this.rotation = isNaN(rotation) ? 0 : rotation;	this.alpha = isNaN(alpha) ? 1 : alpha;	//0 = left, 1 = center, 2 = right	this.horizontalAlign = isNaN(horizontalAlign) && horizontalAlign<3 ? 0 : horizontalAlign;	//0 = top, 1 = center, 2 = bottom	this.verticalAlign = isNaN(verticalAlign) && verticalAlign<3 ? 0 : verticalAlign;	};
}(window));
//========================
//general properties for demo set up
//========================
var canvas;
var context;
var canvasContainer;
var htmlBounds;
var bounds;
var minimumStageWidth = 250;
var minimumStageHeight = 250;
var maxStageWidth = 1000;
var maxStageHeight = 400;
var resizeTimeoutId = -1;
var readyStateCheckInterval = setInterval( function() { if (document.readyState === "complete") { clearInterval(readyStateCheckInterval); init(); }
}, 10);
function init(){ canvasContainer = document.getElementById("canvasContainer"); window.onresize = resizeHandler; commitResize();
}
function getWidth( element ){return Math.max(element.scrollWidth,element.offsetWidth,element.clientWidth );}
function getHeight( element ){return Math.max(element.scrollHeight,element.offsetHeight,element.clientHeight );}
//avoid running resize scripts repeatedly if a browser window is being resized by dragging
function resizeHandler(){ context.clearRect(0,0,canvas.width, canvas.height); clearTimeout(resizeTimeoutId); clearTimeoutsAndIntervals(); resizeTimeoutId = setTimeout(commitResize, 300 );
}
function commitResize(){ if(canvas){ canvasContainer.removeChild(canvas); } canvas = document.createElement('canvas'); canvas.style.position = "absolute"; context = canvas.getContext("2d"); canvasContainer.appendChild(canvas); htmlBounds = new Sakri.Geom.Rectangle(0,0, getWidth(canvasContainer) , getHeight(canvasContainer)); if(htmlBounds.width >= maxStageWidth){ canvas.width = maxStageWidth; canvas.style.left = htmlBounds.getCenterX() - (maxStageWidth/2)+"px"; }else{ canvas.width = htmlBounds.width; canvas.style.left ="0px"; } if(htmlBounds.height > maxStageHeight){ canvas.height = maxStageHeight; canvas.style.top = htmlBounds.getCenterY() - (maxStageHeight/2)+"px"; }else{ canvas.height = htmlBounds.height; canvas.style.top ="0px"; } bounds = new Sakri.Geom.Rectangle(0,0, canvas.width, canvas.height); context.clearRect(0, 0, canvas.width, canvas.height); context.font = fontProperties.getFontString(); context.textBaseline = "top"; if(bounds.width<minimumStageWidth || bounds.height<minimumStageHeight){ stageTooSmallHandler(); return; } var textInputSpan = document.getElementById("textInputSpan");
textInputSpan.style.top = htmlBounds.getCenterY() + (bounds.height/2 + 10)+"px"; textInputSpan.style.left = (htmlBounds.getCenterX() - getWidth(textInputSpan)/2)+"px"; startDemo();
}
function stageTooSmallHandler(){ var warning = "Sorry, bigger screen required :("; context.font = "bold normal 24px sans-serif"; context.fillText(warning, bounds.getCenterX() - context.measureText(warning).width/2, bounds.getCenterY()-12);
}
//========================
//Demo specific properties
//========================
var blockSetAnimator = new Sakri.BlockSetAnimator();
var words = ["SAKRI", "DEVSTATE","CODEPEN"];
var bgColor;
var strokeColor = "#000000";
var strokeWidth = 2;
var wordIndex = 0;
var fontProperties = new Sakri.CanvasTextProperties(Sakri.CanvasTextProperties.BOLD, null, 160);
var isIntro;
var timeoutId;
var strokeWidth = 3;
var colors = ["#698384", "#841118", "#c26c2e", "#517c24", "#cca835", "#166586", "#9ba78c", "#b68679"];
function clearTimeoutsAndIntervals(){ clearTimeout(timeoutId); if(blockSetAnimator){ blockSetAnimator.stop(); }
}
function startDemo(){ isIntro = true; showNextAnimation();
}
function getTallestImageHeight(images){ var tallest = 0; for(var i = 0; i<images.length; i++){ if(images[i].height>tallest){ tallest = images[i].height; } } return tallest;
}
function getBGColor(textColor){ var color = colors[Math.floor(Math.random()*colors.length)]; while(color==textColor){ color = colors[Math.floor(Math.random()*colors.length)]; } return color;
}
function showNextAnimation(){ var textColor = colors[Math.floor(Math.random()*colors.length)]; var images = Sakri.CanvasTextUtil.createImagesFromString(words[wordIndex], textColor, strokeColor, strokeWidth, fontProperties); bgColor = getBGColor(textColor); context.fillStyle = bgColor; context.fillRect(0, 0, canvas.width, canvas.height); context.font = fontProperties.getFontString(); blockSetAnimator.x = bounds.getCenterX() - context.measureText(words[wordIndex]).width/2; blockSetAnimator.y = bounds.getCenterY() - getTallestImageHeight(images)/2; blockSetAnimator.setImages(images); runRandomAnimation(); wordIndex++; wordIndex %= words.length;
}
function getIntroEasingFunction(){ var anim = Sakri.UnitAnimator; var easing = [anim.easeLinear, anim.easeOutSine, anim.easeOutBounce, anim.easeOutElastic]; return easing[Math.floor( Math.random()*easing.length )];
}
function getEndtroEasingFunction(){ var anim = Sakri.UnitAnimator; var easing = [anim.easeLinear, anim.easeInSine, anim.easeInBounce, anim.easeInElastic]; return easing[Math.floor( Math.random()*easing.length )];
}
function runRandomAnimation(){ var anim = Sakri.UnitAnimator; var easingFunction = isIntro ? getIntroEasingFunction() : getEndtroEasingFunction(); var rotation, minTransform, maxTransform; if( easingFunction == anim.easeLinear || easingFunction == anim.easeOutSine || anim.easeInSine){ rotation = -Math.PI*3 + Math.random() * Math.PI*6; minTranform = -200; maxTranform = 400; }else{ rotation = -Math.PI*1.5 + Math.random() * Math.PI*3; minTranform = -100; maxTranform = 200; } var scale = Math.random() * 3; var hAlign = Math.floor(Math.random()*3); var vAlign = Math.floor(Math.random()*3); var transformA = new Sakri.AnimationBlockTransform(minTranform + Math.random()*maxTranform, minTranform + Math.random()*maxTranform, scale, rotation, 0, hAlign, vAlign ); var transformB = new Sakri.AnimationBlockTransform(0, 0, 1, 0, 1, hAlign, vAlign); if(isIntro){ blockSetAnimator.setAnimation(transformA, transformB); }else{ blockSetAnimator.setAnimation(transformB, transformA); } blockSetAnimator.setEasingFunction(easingFunction); blockSetAnimator.start (2000, 250, blockSetAnimationComplete , animationUpdate); isIntro = !isIntro;
}
function animationUpdate(){ //context.clearRect(bounds.x, bounds.y, bounds.width, bounds.height); context.fillStyle = bgColor; context.globalAlpha = .8; context.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); context.globalAlpha = 1; blockSetAnimator.render(context);
}
function blockSetAnimationComplete(){ context.fillStyle = bgColor; context.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); blockSetAnimator.render(context); timeoutId = setTimeout(isIntro ? showNextAnimation : runRandomAnimation, 1000);
}
var maxCharacters = 8;
function changeText(){ var textInput = document.getElementById("textInput"); if(textInput.value && textInput.text!=""){ if(textInput.value.length > maxCharacters){ alert("Sorry, there is only room for "+maxCharacters+" characters. Try a shorter name."); return; } if(textInput.value.indexOf(" ")>-1){ alert("Sorry, no support for spaces right now :("); return; } clearTimeoutsAndIntervals(); words = [textInput.value]; wordIndex = 0; isIntro = true; showNextAnimation(); }
}
Classic text effect - Script Codes
Classic text effect - Script Codes
Home Page Home
Developer Sakri Rosenstrom
Username sakri
Uploaded September 06, 2022
Rating 3.5
Size 11,186 Kb
Views 24,288
Do you need developer help for Classic text effect?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Sakri Rosenstrom (sakri) Script Codes
Create amazing art & images with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!