Zubashev Stepan's blog

Как найти ближайший видимый domElement в скролируемом viewPort-е

Возникла задача ― в скролируемом контейнере найти первый видимый domElement. Я подумал, что, наверняка, это довольно частая задача, и должно быть множество разных готовых решений. Порыскав по сети я нашёл лишь множество вариаций одного и того же: рекурсивный обход всего древа domElement-ов, с рассчётом их границ. В голову полезли варианты с бинарным поиском по тому же принципу, но уж больно не хотелось с этим всем связываться. Как то уж слишком сурово, для такой мелочной задачи. Должен быть “нативный” инструмент.

Увы, совсем уж нативного инструмента я не нашёл. Но нашёл, гхм, альтернативный путь. Возможно, кому-нибудь ещё пригодится. 

  • У контейнера, который содержит искомые domElement-ы вызываем getBoundingClientRect. Получаем его расположение на экране
  • Вычисляем координаты какого-либо участка из viewPort-а, где должен находится искомый domElement
  • Вызываем document.elementFromPoint, указав нужные координаты экрана
  • profit…

Решение сгодится не для любого случая. Но мне вполне подошло.

goPro 4 ― первое впечатление

Купил goPro 4 Black для записи видео с полётов. Первые впечатления по большей части негативные. Пока свежи, решил их перечислить в этой заметке:

  • Пульт из поставки убрали. Стоимость пульта довольно таки высокая. Стоимость батареи увеличенной ёмкости со спец. крышкой тоже выше всяких разумных пределов. На сайте goPro.com даже самые элементраные вещи стоят не ниже 19 $. Хороший бизнес, что сказать…
  • Пока не пробовал снимать нормальные видео в нормальных условиях. Но в условиях квартиры я почему-то наблюдаю жутчайшие артефакты на снятых видео. Попробовал разные режимы ― артефакты не пропадают. Неужели брак? Обновление прошивки ситуацию не спасло. Надеюсь в боевых условиях таких фокусов не будет.
  • Обновление прошивки не обрадовало. Вариант без сторонних приложений требует от вас кардридера (о_О). Вариант обновления через goPro APP с android-трубки был почему-то выпилен из приложения (хотя в описании на сайте присутствует). Обновление через goPro Studio прошло штатно. Однако неожиданно. Я так и не смог найти специальной кнопки для этого. Её попросту нет. Приложение само, при подключении goPro к windows (да-да, unix-фаги идут лесом), предложило обновиться и обновило прошивку. Минуты 4 ушло. В новой прошивке новые опции, типа timelapse и пр.
  • goPro Studio в своём windows-installer-е указывает куда она установится, но сменить путь не позволяет. оО. Впрочем плевать на форточки.

Из некоторых особенностей:

Read more

Кирилица и SmartGit

Извечная беда с горячими клавишами в нестандартной (т.е. английской) раскладке. Наиболее часто попадается в Java и QT приложениях. Наиболее остро я на это натыкаюсь при использовании Mate окружения в свежем LinuxMint-е. Обе баги (что QT, что Java) уже исправлены, что, почему то не сказывается даже на свежих билдах софта, к примеру SmartGit-а. В очередной раз вооружившись поисковиком я стал искать решения в обход. И нашёл! Хороший человек написал небольшую java-утилиту для решения проблем с горячими клавишами. Вся соль в том, что необходимо запустить jar-ки с флагом -javaagent к java. В описании к репозиторию указано, как правильно это сделать для Intelli Idea и ещё ряда приложений. А для SmartGit-а вот правильное решение:

  • Создать файл ~/.smartgit/smartgit.vmoptions
  • Вписать туда -javaagent:%jarpath%/LinuxJavaFixes-%version%.jar=swt. Вместо %jarpath% указать путь к скачанным с github-а файлам, а вместо %version% текущую версию jar-ки. Обратите внимание на =swt, без этого в SmartGit ничего не заработало. SWT это фреймворк для Java, который использует SmartGit
  • Готово!

Осталось найти рецепт для QT-приложений :( Похоже, что там надо насильно ставить себе QT5.5+ и собирать из исходников каждое проблемное приложение :(

Простой proxy-сервер на iojs

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

"use strict";

/**
 * run: iojs --harmony_arrow_functions proxy.js
 *
 * nginx:
 * location ~ ^/api.*$ {
 * 	proxy_pass http://127.0.0.1:3001;
 * 	proxy_set_header X-Real-IP $remote_addr;
 * 	proxy_set_header Host $host;
 * 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 * }
 */

let hostname = '%hostname%';
let port = 3001;
let auth = '%user%:%pass%';
let http = require('http');

http.createServer((clientReq, clientRes) =>
{
	let opts =
	{
		hostname: hostname,
		port: 80,
		path: clientReq.url,
		auth: auth,
		headers: clientReq.headers,
		method: clientReq.method
	};
	opts.headers.host = hostname;

	console.info('serve: %s %s', clientReq.method, clientReq.url);

	let proxy = http.request(opts, (proxyRes) =>
	{
		proxyRes.addListener('data', (chunk) => clientRes.write(chunk, 'binary'));
		proxyRes.addListener('end', () => clientRes.end());
		clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
	});

	clientReq.addListener('data', (chunk) => proxy.write(chunk, 'binary'));
	clientReq.addListener('end', () => proxy.end());
}).listen(port);

Запускается путём выполнения iojs --harmony_arrow_functions proxy.js, логирует все запросы в консоль. Точно умеет POST, GET, отдавать статику… Для простых нужд вполне сгодится. Жаль браузеры пока толком не умеют arrow functions :(

Облёт Litespeed-а

Купил почти новый Moyes Litespeed RX 3.5. Сегодня облетал. Третий полёт на лысом аппарате. Посадка “пузом” на контрсклон.