Блик
Автор: Евгений Рыжков Дата публикации:
Задача
Сделать пробегающий блик по надписи.
Решение
Делаем с помощью HTML5 Canvas. К примеру сделаем блик для заголовка:
<h1>Подопытный заголовок</h1>
h1 { position: relative; display: inline-block; // это нужно чтобы проще подобрать скорость блика } #canvasBlik { position: absolute; top: 0; left: 0; z-index: 1; }
/* иницализация блика: el - элемент, к которому применяется эффект params - параметы: blikWidth - ширина блика blikAngle - угог наклона duration - продолжительность */ function blikInit(el, params) { var el = el, elH = el.height(), elW = el.innerWidth(), canvasForBlik; /* если блик к элементу еще не применялся добаялем canvas и скрываем текст */ if(el.find('canvas').length == 0) { canvasForBlik = document.createElement('canvas'); canvasForBlik.id = 'canvasBlik'; el.wrapInner('<span style="opacity: 0; position: relative; z-index: 2"></span>'); el.append(canvasForBlik); /* задаем размеры и позиционируем canvas */ canvasForBlik.width=elW; canvasForBlik.height=elH; } else { // делать этого нет смысле canvasForBlik = document.getElementById('canvasBlik'); } /* определяем параметры текста */ var optFontName = el.css('fontFamily'), optFontSize = el.css('fontSize'), optFontColor = el.css('color'), optFontWeight = el.css('fontWeight'), optFontStyle = el.css('fontStyle'), optLineHeight = el.css('lineHeight'), optText = el.text(); var ctx = canvasForBlik.getContext('2d'); var blikWidth = params.blikWidth; // ширина блика /* создаем блик. тут же определяем его вид */ var lineargradient = ctx.createLinearGradient(0,0,blikWidth,0); /* цвета блика */ lineargradient.addColorStop(0, 'rgba(255, 255, 255, 0.5)'); lineargradient.addColorStop(0.4, 'rgba(255, 255, 255, 1)'); lineargradient.addColorStop(0.6, 'rgba(255, 255, 255, 1)'); lineargradient.addColorStop(1, 'rgba(255, 255, 255, 0.5)'); var blikAngle = params.blikAngle; // угол блика // параметры анимации var anim, // таймаут start, // время старта now, // текущее время duration = params.duration, // продолжительность from = -20-blikWidth, // стартовая позиция to = elW+blikWidth+20, // финишная позиция progress = 0, // прогресс анимации x; // позиция в текущий момент времени // закон приращения аргумента (easing) function delta(param){ return param; }; // рендер function render(){ now = new Date().getTime(); progress = (now-start)/duration; x = (to - from)*delta(progress) + from; ctx.save(); ctx.clearRect(0, 0, elW, elH); ctx.textBaseline = 'top'; ctx.font = optFontStyle+' '+optFontWeight+' '+optFontSize+' '+optFontName; ctx.fillStyle = optFontColor; ctx.fillText(optText,0, 7); ctx.save(); ctx.globalCompositeOperation = 'source-atop'; ctx.translate(x, 0); ctx.fillStyle = lineargradient; ctx.rotate( blikAngle ); ctx.fillRect(0,-50, blikWidth, elH+50); ctx.restore(); // если не конец выполняем анимацию еще if (progress > 1) anim = setTimeout(arguments.callee, 0) // иначе заканчиваем анимацию else { clearTimeout(anim); progress = 0; el.find('canvas') }; }; start = new Date().getTime(); render(); } $(document).ready(function(){ blikInit($('h1'), {blikWidth: 100, blikAngle: Math.PI / 6, duration: 1500}); $('input').click(function() { blikInit($('h1'), {blikWidth: 50, blikAngle: Math.PI / 6, duration: 800}); }); }); //requestAnimFrame window.setAnimation = (function() { return window.requestAnimationFrame|| window.webkitRequestAnimationFrame|| window.mozRequestAnimationFrame|| window.oRequestAnimationFrame|| window.msRequestAnimationFrame|| function(/* function */callback, /* DOMElement */element) { return window.setTimeout(callback, 1000 / 60); }; })(); //canсelRequestAnimFrame window.clearAnimation = (function() { return window.cancelRequestAnimationFrame|| window.webkitCancelRequestAnimationFrame|| window.mozCancelRequestAnimationFrame|| window.oCancelRequestAnimationFrame|| window.msCancelRequestAnimationFrame|| function(id){clearTimeout(id)} })();
Демо пример. Поддерживается:
- IE 9
- Firefox 4+
- Safari 5+
- Chrome
- iOs 4+
- Android 3+