среда, 10 июля 2013 г.

SVG: как нарисовать сектор круга

Сегодня мы будем рисовать круг, разбитый на шесть равных секторов, используя замечательную библиотеку jQuery SVG. Плюс сделаем подсветку сектора при наведении.

Итак, качаем библиотеку отсюда: http://keith-wood.name/svg.html и подключаем её. Если нам нужна реакция на клик или наведение, дополнительно подключаем расширение SVG DOM (обратите внимание - для нормальной работы с нашим любимым ИЕ понадобится изменённая библиотека jQuery, она есть на этом же сайте). Собственно, мануал с большими картинками там присутствует, примеров сколько душе угодно - играйтесь на здоровье.  А я перейду сразу к секторам, поскольку гугл выдаёт очень мало информации на этот счёт, а хочется быстро и красиво.

Итак, после подключения библиотеки создаём блок, в котором всё будет происходить:

<div id='circle' width='200' height='200'></div>

Ну и поехали. См. комментарии.


<script type="text/javascript">
$(function() {
$('#circle').svg({onLoad: drawCircle}); // #circle - идентификатор вашего блока, drawCirce - функция, которая будет отрисовывать всю красоту
});

/* Эта функция вычисляет координату точки на окружности, из которой будет начинаться следующий сектор. Чуть ниже мы загоним её в цикл. В неё передаются координаты точки начала отсчёта. */

function nextCoord(x0, y0){

// это координаты центра круга
x = 100;
y = 100;

alpha = 60*Math.PI/180; // считаем угол в радианах. 60 - это размер угла в градусах. Соответственно, у нас будет 6 секторов по 60 градусов.

rx = x0 - x;
ry = y0 - y;
c = Math.cos(alpha);
s = Math.sin(alpha);
x1 = x + rx * c - ry * s;
y1 = y + rx * s + ry * c;

return [x1,y1]; // и возвращаем массив с новыми координатами
}

// Наша основная функция

function drawCircle(svg) {

svg.circle(100, 100, 100,  {fill: '#ffffff'});  /* Рисуем круг. Параметры: координата x, координата y, радиус, объект со всяческими опциями (см. мануал). Этот шаг можно пропустить, поскольку наши сектора и так составят тот же самый круг. */

var coord = [0,100]; // точка, с которой мы начинаем отсчитывать сектора. В данном случае - крайняя левая точка окружности.

for(var i=0;i<6;i++){ // секторов у нас будет 6, поэтому прогоняем цикл 6 раз

                var sector = svg.createPath(); // создаём новую кривую

sector.move(100,100,false); // "ставим карандаш" в центр будущего круга. false здесь означает, что координаты абсолютные, опять же, курите мануал

sector.line(coord[0],coord[1],false); // ведём линию из центра к нашей отправной точке на окружности

var newcoord = nextCoord(coord[0],coord[1]); // с помощью предыдущей функции считаем координаты конечной точки дуги сектора

sector.arc(100, 100, 60, false, true, newcoord[0], newcoord[1], false)
/* рисуем дугу. Параметры: 
1,2) 100 и 100 - 2 радиуса эллипса, частью которого будет наша дуга  (в данном случае это и есть круг с радиусом 100), 
 3) угол - у нас он 60 градусов
4) Выбрать бОльшую дугу (если эллипс вытянутый) - true или false
5) Отмеряем дугу по часовой стрелке - true, против часовой - false
6,7) Наши новые координаты, точка, в которую дуга должна прийти
8) false - координаты итоговой точки абсолютные
*/

sector.close(); // "закрываем" наш сектор, конец дуги автоматически соединяется с начальной точкой в центре круга

svg.path(sector, {fill:'#ffffff',stroke: 'black', strokeWidth: 1, class: 'sector'}); //отрисовываем наш сектор. не забываем присвоить ему класс или id, если хотим повесить на него событие

coord = newcoord; // принимаем точку на круге, в которую мы пришли, за исходную, и идём на следующий цикл
}

       // Добавляем изменение заливки при наведении

$('.sector').mouseover(function(){
$(this).attr('fill','#d5ff9d');
});

$('.sector').mouseout(function(){
$(this).attr('fill','#fff');
});

}

</script>

Как-то так.

ЗЫ: Я окончательно убедилась, что мне нужна подсветка кода. Надо бы что-нибудь такое подключить к блогу.

четверг, 27 июня 2013 г.

PHP: Zip архив с кириллическими именами

Допустим, нам нужно извлечь из zip архива файлы с именами на русском. А он извлекает крокозябры. Вот что сработало в итоге для меня:


$zip = new ZipArchive;
$res = $zip->open(*путь к папке, в которую загружен архив*);
if ($res === TRUE) {

     $docs_path = *путь к папке, в которую надо распаковать архив*;
     if(!is_file($docs_path)) mkdir($docs_path); // создаём, если не существует
     $count = $zip->numFiles;
                   
for($i = 0; $i < $count; $i++) {        
$stat = $zip->statIndex($i);
$newname =  mb_convert_encoding ($stat['name'], 'UTF-8','CP866' );
$newname = $this->makeAlias($newname, 1); // makeAlias - функция для перевода в транслит. Highly recommended, не используйте кириллические имена
$zip->renameIndex($i,$newname);
$res = $zip->extractTo($docs_path, array($zip->getNameIndex($i)));
}

$zip->close();
}

Итак, мы прошлись циклом по архиву, переименовали каждый файлик и распаковали его в нужное место. Хочу отметить, что функция iconv для меня по каким-то таинственным причинам не сработала, поэтому, как вы видите, используется mb_convert_encoding.

четверг, 14 марта 2013 г.

Добавить кнопку (плагин) в JCE

Поговорим о том, как можно сделать свою кнопку в панели инструментов JCE Editor. А лучше сделаем плагин сразу с двумя кнопками, поскольку именно с этим моментом у меня возникал затык. Допустим, нам нужны две кнопки: одна добавляет в текст смайлик ^_^, вторая - смайлик >_<. Пусть наш плагин называется "smiles". Поехали.

1) Создаём папку для плагина. В ней размещаем следующую структуру:

/img
--icon.gif
/langs
--en.js
smiles.xml
editor_plugin.js

2) Файл smiles.xml описывает наш плагин (цветом выделены значения, которые нужно заменить на собственные):


<?xml version="1.0" ?>
<install version="2.2.0" type="plugin" plugin="smiles"> // 2.2.0 - это версия JCE. 
   <name>Example</name>
   <version>2.2.0</version>
   <creationDate>2013</creationDate>
   <author>Anonym</author>
   <icon>good,bad</icon> // здесь нужно перечислить идентификаторы всех кнопок
   <layout>smiles</layout>
   <files>
        <file>editor_plugin.js</file>
<file>langs/en.js</file>
<file>img/icon_good.gif</file>
                 <file>img/icon_bad.gif</file>
    </files>
</install>

3) en.js - это наш файл локализации. Если язык редактора другой, файл будет называться, к примеру, ru.js. Содержание:

tinyMCE.addI18n('en.smiles',{

good_smile: 'Add good smile',
bad_smile: 'Add bas smile'
});

Надеюсь, здесь всё понятно. Задаём константы имён кнопочек. Конечно, можно и не использовать локализацию, но будем следовать правилам хорошего тона.

4) И, наконец, editor_plugin.js - собственно, код плагина.


(function() {
tinymce.PluginManager.requireLangPack('smiles'); // подключили нашу локализацию
 
tinymce.create('tinymce.plugins.Smiles', {
init : function(ed, url) {
var t = this;
t.editor = ed;

// добавляем кнопки
ed.addButton('good', {
title : 'smiles.good_smile', // локализованный заголовок кнопки
cmd : 'mceSmileGood',  // команда, которая будет выполняться по щелчку на кнопку
image : url + '/img/icon_good.gif' // иконка кнопки
});

// и вторая кнопка
ed.addButton('bad', {
title : 'smiles.bad_smile',
cmd : 'mceSmileBad',
image : url + '/img/icon_bad.gif'
});

// теперь добавляем команды, привязанные к кнопкам

ed.addCommand('mceSmileGood', function() {
var html = '^_^'; // вот и наш смайл (или любой другой текст, который вы хотите вставить)
ed.execCommand("mceInsertContent", false, html);
return true;
});

ed.addCommand('mceSmileBad', function() {
var html = '>_<';
ed.execCommand("mceInsertContent", false, html);
return true;
});
}
});
// Register plugin
tinymce.PluginManager.add('smiles', tinymce.plugins.Smiles);

})();


Вот, собственно, и всё. Пакуем папку в zip-архив и устанавливаем аддон в JCE. Не забываем зайти в настройки профиля (Editor Profiles) и перетащить наши кнопки на панель инструментов. Возможно, в настройках не будут отображаться иконки - у меня получилось именно так - но в редакторе они должны показываться нормально и работать. Удачи!


Joomla 2.5 режет javascript в параметрах плагина

Допустим, вам позарез нужно вставить код javascript (например, какой-нибудь Adsense) в параметры вашего модуля или плагина Joomla. Решение простое до идиотизма. В xml описании плагина поле должно выглядеть так:


<field name="js" filter="RAW" type="textarea" description="" label="Код js" />

четверг, 24 января 2013 г.

Глюк выпадающего списка в TinyMce и JCE Editor при использовании Twitter Bootstrap

Наткнулась на очень странный баг при одновременном применении Bootstrap и Tinymce. Заключается он в следующем: при многократных вызовах выпадающего списка в панели инструментов (стили, шрифты и т.п.) список с каждым щелчком сужается, пока не исчезает.

Решение:

Идём в bootstrap.css, находим стиль для элемента table, убираем max-width:100%. Я переопределила это свойство для таблиц внутри основного контентного блока, примерно так: #content table{max-width:100%}. Всё работает.

пятница, 4 января 2013 г.

Яндекс карта и Jquery Ui Tabs

Если яндекс карта располагается у нас во вкладке, которая по умолчанию закрыта, необходимо будет несколько изменить вызов карты. Делается это следующим образом:

1) Если в подключаемом скрипте присутствует фрагмент, похожий на выделенный, удаляем этот фрагмент.

<script type="text/javascript"
src="http://api-maps.yandex.ru/2.0-stable/?lang=ru-RU&coordorder=longlat&load=package.full&wizard=constructor&onload=fid_1357309839884552313"></script>


2) Далее вызов карты и включение табов производятся по следующему образцу:



<script type="text/javascript">

$(document).ready(function(){

ymaps.ready(init);
var map;

function init(){
map = new ymaps.Map("ymaps-map-id_1355060157801926", {
center: 100,
zoom: 10,
type: "yandex#map"
});
map.controls.add("zoomControl").add("mapTools");
}

// Внутри функции init() - ваш вызов карты со всеми инструментами, метками и пр.. Если вы создавали карту при помощи конструктора, сюда переносится весь код функции с именем типа  function fid_135730983988455231359.


$("#tabs").tabs(); //далее включаем табы


$('#tabs').bind('tabsshow', function (event, ui) {
       map.container.fitToViewport();
    });

//и при переключении между табами яндекс карта подстраивается под размер контейнера

});
</script>





Массив с месяцами на русском - сколько можно набивать руками)



$months = array(
'01'=>'январь',
'02'=>'февраль',
'03'=>'март',
'04'=>'апрель',
'05'=>'май',
'06'=>'июнь',
'07'=>'июль',
'08'=>'август',
'09'=>'сентябрь',
'10'=>'октябрь',
'11'=>'ноябрь',
'12'=>'декабрь',
);

$months2 = array(
'01'=>'января',
'02'=>'февраля',
'03'=>'марта',
'04'=>'апреля',
'05'=>'мая',
'06'=>'июня',
'07'=>'июля',
'08'=>'августа',
'09'=>'сентября',
'10'=>'октября',
'11'=>'ноября',
'12'=>'декабря',
);