css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
14 Апр
К будущему надо готовиться, потому что оно наступает быстрее, чем мы его ждем. Поэтому сегодня расскажу о canvas — элементе спецификации Web Applications 1.0, которая со временем вероятно воплотится в язык HTML5. Сама спецификация подготовлена рабочей группой WHAT-WG (Web Hypertext Application Technology Working Group) и добавляет ряд нововведений в HTML и DOM.
Однако начнем с примера использования canvas…
Не знаю как кого, а меня пример впечатлил…
Итак, элемент Canvas предназначен для создания bitmap изображения при помощи JavaScript, т.е. мы получаем возможность создавать графические формы, рисовать линии, вращать изображения.
Такие возможности подстегнули производителей браузеров к включению API canvas в последние версии своих продуктов – FireFox, Opera, Chrome, Safari поддерживают тэг canvas. Как всегда неприятным исключением оказался горячо нелюбимый всеми Internet Explorer – не то что в 6 и 7 версиях, даже в 8 версии поддержка тэга canvas не планируется.
Однако не все так безнадежно как могло бы показаться – на помощь пришла компания Google, реализовав для IE полноценный API Canvas. По сути это небольшой js-файл, подключая который для браузеров IE можно заставить их «понимать» тэг canvas. Найти этот файл можно тут:
http://code.google.com/p/explorercanvas/
Но вернемся к нашему примеру. Для того, чтобы изобразить такие часики на своей страничке понадобится подключить в разделе HEAD файл excanvas.js – это для ого, чтобы заставить браузеры IE понимать canvas:
<!--[if IE]> <script type="text/javascript" src="excanvas.js"></script> < ![endif]-->
В body добавим следующую разметку:
<canvas id="canvas" height="150" width="150"></canvas>
И самое главное – JS-код, который и рисует сами часики:
// ожидаем загрузку
window.onload = function(){
// рисуем часы
clock();
// через каждую секунду
// часы перерисовываются
setInterval(clock, 1000);
}
//
function clock() {
// получаем текущие дату и время
var now = new Date();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
// получаем контекст canvas
var ctx = document
.getElementById("canvas")
.getContext("2d");
// сохраняем состояние
ctx.save();
// инициализируем холст
ctx.clearRect(0,0,150,150);
// рисуя в точке 0,0 фактически
// рисуем в точке 75,75
ctx.translate(75,75);
// при рисовании линии в 100px
// фактически рисуем линию в 40px
ctx.scale(0.4,0.4);
// начинаем вращать с 12:00
ctx.rotate(-Math.PI/2);
// инициализируем свойства рисунка
// контуры рисуем черным
ctx.strokeStyle = "black";
// заливка тоже черная
ctx.fillStyle = "black";
// ширина линии 8px
ctx.lineWidth = 8;
// будем рисовать по кругу
ctx.lineCap = "round";
// начинаем рисовать часовые метки
// сохраняем предыдущее состояние
ctx.save();
ctx.beginPath();
// для каждого часа
for(var i = 0; i < 12; i++) {
// поворачиваем на 1/12
ctx.rotate(Math.PI/6);
// перемещаем курсор
ctx.moveTo(100,0);
// рисуем черточку 20px
ctx.lineTo(120,0);
}
ctx.stroke();
ctx.restore();
// сохраняем состояние
ctx.save();
// ставим ширину линии 5px
ctx.lineWidth = 5;
ctx.beginPath();
// рисуем минутные метки
// для каждой минуты
for(var i = 0; i < 60; i++) {
// кроме тех, что совпадут
// с часами
if(i%5 != 0) {
// перемещаем курсор
ctx.moveTo(117,0);
// рисуем черточку 3px
ctx.lineTo(120,0);
}
// вращаем холст на 1/60
ctx.rotate(Math.PI/30);
}
ctx.stroke();
ctx.restore();
// сохраняем состояние
ctx.save();
// начинаем рисовать часовую стрелку
// вращаем холст на текущую позицию
ctx.rotate((Math.PI/6)*hr +
(Math.PI/360)*min +
(Math.PI/21600)*sec);
// устанавливаем ширину линии 14px
ctx.lineWidth = 14;
ctx.beginPath();
// сдвигаем курсор несколько назад
// стобы было похоже на стрелку
ctx.moveTo(-20,0);
// рисуем линию почти до часовых меток
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// сохраняем состояние
ctx.save();
// начинаем рисовать минутную стрелку
// вращаем холст на текущую позицию
ctx.rotate((Math.PI/30)*min +
(Math.PI/1800)*sec);
// ширина линии 10px
ctx.lineWidth = 10;
ctx.beginPath();
// двигаем курсор
ctx.moveTo(-28,0);
// рисуем линию
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore();
// сохраняем состояние
ctx.save();
// начинаем рисовать секундную стрелку
// вращаем холст на текущую позицию
ctx.rotate(sec * Math.PI/30);
// контур и заливка красного цвета
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
// ширина линии 6px
ctx.lineWidth = 6;
ctx.beginPath();
// двигаем курсор
ctx.moveTo(-30,0);
// рисуем линию
ctx.lineTo(83,0);
ctx.stroke();
ctx.restore();
// сохраняем состояние
ctx.save();
// рисуем внешнюю окружность
// шириной 14px
ctx.lineWidth = 14;
// синим цветом
ctx.strokeStyle = "#325FA2";
ctx.beginPath();
// рисуем окружность, отступающую
// от центра на 142px
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
ctx.restore();
}
Вы можете скачать файлы этого примера. Можно открыть пример в новом окне и посмотреть исходный код.
В заключение я приведу несколько очень полезных ссылок, для тех, кто заинтересовался.
Canvas Tutorial – туториал (на английском конечно), но там Вы найдете еще впечатляющие примеры.
The canvas element – подраздел спецификации HTML5, касающийся элемента canvas (и тоже ес-но на английском).
Отзывов (30) на «Что такое Canvas»
Правда у меня в Opera/9.64 (Windows NT 5.1; U; ru) Presto/2.1.1 часы идут, но вот минутных меток нет, а часовая только та, которая на 12 часах…. В остальных браузерах все нормально….
У меня в ФФ всё в норме (-:
Круто! Возьмём на вооружение
У меня в Opera/9.64 (Windows NT 5.1; U; ru) Presto/2.1.1 все отлично! Все стрелки присутствуют.
>У меня в Opera/9.64 (Windows NT 5.1; U; ru) >Presto/2.1.1 все отлично! Все стрелки присутствуют.
Не стрелки – а метки.
Opera/9.60 – аналогично с автором, нет меток.
> Не стрелки – а метки.
Opera/9.60 – аналогично с автором, нет меток.
Посмотрел в Firefox’е, действительно имеются метки. Простите за невнимательность )
Opera 10. Все ок.
linux/opera 9.64 – часовых меток (кроме самой верхней на 0/12 часов) – нет, в firefox 3.0.8 – метки есть. Эх… За статью – большое спасибо, как всегда очень интересно.
http://kilianvalkhof.com/2009/javascript/cufon-vs-typefacejs-which-one-is-better/
как то странно ссылка вставилась
To Negin:
Ссылка, которую Вы хотели вставить есть в самом конце статьи…
я к тому, что на Русском)
Есть способ корректно отобразить в Opera 9.**&?
По идее Opera, начиная с 9 версии должна полностью поддерживать тэг canvas. Да она-то вроде и поддерживает… Может быть в самом коде кроется проблема. Например, отрисовывать метки позже, чем отрисовываются стрелки… Можно это попробовать.
вот что у мя получилось)
window.onload = function(){
draw();
setInterval(draw, 15);
}
function draw() {
var canvas = document.getElementById(«canvas»);
if (canvas.getContext) {
var ctx = canvas.getContext(«2d»);
var now = new Date();
var hours = now.getHours();
var mins = now.getMinutes();
var sec = now.getSeconds();
var millisec = now.getMilliseconds();
ctx.save();
ctx.clearRect(0, 0, 200, 200);
ctx.translate(100, 100);
var grad = ctx.createRadialGradient(0, 0, 90, 0, 0, 85);
grad.addColorStop(0, ‘rgba(150, 240, 220, 0)’);
grad.addColorStop(0.8, ‘rgb(255, 250, 255)’ );
grad.addColorStop(1, ‘rgb(172, 220, 230)’ );
ctx.fillStyle = grad;
ctx.fillRect(-100, -100, 200, 200);
ctx.lineCap = ’round’;
ctx.save();
ctx.lineWidth = 3;
for(i = 0; i < 12; i++){
ctx.rotate(Math.PI/6);
ctx.beginPath();
ctx.moveTo(0, -83);
ctx.lineTo(0, -70);
ctx.stroke();
}
ctx.lineWidth = 2;
for(i = 0; i < 60; i++){
ctx.rotate(Math.PI/30);
ctx.beginPath();
ctx.moveTo(0, -80);
ctx.lineTo(0, -76);
ctx.stroke();
}
ctx.restore();
ctx.save();
ctx.strokeStyle = ‘darkblue’;
ctx.lineWidth = 6;
ctx.rotate((Math.PI/6)*hours);
ctx.beginPath();
ctx.moveTo(0, -60);
ctx.lineTo(0, 5);
ctx.stroke();
ctx.restore();
ctx.save();
ctx.strokeStyle = ‘darkblue’;
ctx.lineWidth = 4;
ctx.rotate((Math.PI/30)*mins);
ctx.beginPath();
ctx.moveTo(0, -66);
ctx.lineTo(0, 7);
ctx.stroke();
ctx.restore();
ctx.save();
ctx.strokeStyle = ‘red’;
ctx.lineWidth = 3;
ctx.rotate((Math.PI/30)*sec);
ctx.beginPath();
ctx.moveTo(0, -72);
ctx.lineTo(0, 8);
ctx.stroke();
ctx.restore();
ctx.strokeStyle = ‘red’;
ctx.lineWidth = 3;
ctx.rotate((Math.PI/500)*millisec);
ctx.beginPath();
ctx.moveTo(0, -95);
ctx.lineTo(0, 8);
ctx.stroke();
ctx.restore();
}
}
>на помощь пришла компания Google, реализовав для IE полноценный API Canvas
Посмотрев имена разработчиков, мне показалось, что к гуглу они никакого отношения не имеют, а лишь используют бесплатный гугловский сервис для размещения репозитория. Могу, конечно, ошибаться.
А Вы всех разработчиков Google знаете по именам?
Это действительно разработка от Google…
Замечательный пример.
и часы меня заинтересовали.
вот тока получается они берут системное время.
а как можно сделать чтобы они они показывали московское время независимо от времени на компе?
Используйте тот же php например. Возьмите время на сервере, обработайте как необходимо и передайте в JS.
использовал canvas в своем проекте и сталкнулся с такой проблемкой, что при множестве объектов канвас (у меня это кружки) браузер начинает жестко тормозить. Есть какие-нибудь мысли на этот счет?
Были времена, когда за такие часы на странице приходилось грузить огромные JAVA-апплеты… Всё меняется к лучшему
Хорошая статья
Спасибо за пример.
Можно сделать много полезных вещей.
Только один вопрос: возможно ли вывести текст в пределах рисунка?
В документации указаны такие методы, как strokeText и fillText, но excanvas.js их не поддерживает.
Последняя библиотека датируется 21 марта 2009 более поздних версий я не нашла.
Что ж, придется делать к схеме отдельное описание.
Для любителей картинок на js, предлагаю восхититься:
http://raphaeljs.com/tiger.html
Понравились часики. Сейчас занимаюсь как раз разработкой связанной с canvas, так что тема для меня очень интересная. пошел разбираться в коде. и спасибо за статью
А сейчас еще появились всяческие библиотеки для работы с canvas, такие как jCanvaScript – http://www.jcscript.com . Пользоваться просто, как jQuery… Да и примеров кода на сайте полно.
Alex, спасибо за ссылку… Интересно.
ссылка на статью, которую автор указал в конце есть на русском языке.
Нужна помощь. может кто знает в Ie 9 часы немного дергаются при этом дергают всю страницу и она на 1-2 px ходит вправо-влево с чем это может быть связано. Помогите. спасибо.
Оставьте отзыв