В ситуациях, когда элемент холста равен 1: 1 по сравнению с размером растрового изображения, вы можете получить позиции мыши с помощью этого фрагмента:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
Просто вызовите его из вашего события с событием и холстом в качестве аргументов. Он возвращает объект с x и y для позиций мыши.
Поскольку позиция мыши, которую вы получаете, относится к окну клиента, вам нужно будет вычесть позицию элемента холста, чтобы преобразовать его относительно самого элемента.
Пример интеграции в ваш код:
//put this outside the event loop..
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
function draw(evt) {
var pos = getMousePos(canvas, evt);
context.fillStyle = "#000000";
context.fillRect (pos.x, pos.y, 4, 4);
}
Примечание: границы и отступы будет влиять на позицию, если она применяется непосредственно к элементу canvas, поэтому их необходимо рассмотреть с помощью getComputedStyle()
- или применить эти стили к родительскому div.
Когда возникает ситуация, когда элемент имеет размер, отличный от самого растрового изображения, например, элемент масштабируется с использованием CSS или имеет соотношение сторон пикселей и т. д., вам придется обратиться к этому вопросу.
Пример:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(), // abs. size of element
scaleX = canvas.width / rect.width, // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
return {
x: (evt.clientX - rect.left) * scaleX, // scale mouse coordinates after they have
y: (evt.clientY - rect.top) * scaleY // been adjusted to be relative to element
}
}
Тогда существует более сложный случай, когда вы применили преобразование к контексту, такое как вращение, перекос / сдвиг, масштабирование, перевод и т. д. Чтобы справиться с этим, вы можете вычислить обратную матрицу текущей матрицы.
Новые браузеры позволяют читать текущую матрицу через свойство currentTransform
и Firefox (текущая альфа) даже обеспечивают инвертированную матрицу через mozCurrentTransformInverted
. Однако Firefox через mozCurrentTransform
вернет массив, а не DOMMatrix
, как следует. Ни Chrome, если он включен с помощью экспериментальных флагов, возвратит DOMMatrix
, а SVGMatrix
.
. В большинстве случаев вам придется реализовать собственное собственное собственное матричное решение (например, мое собственное решение здесь - бесплатный / проект MIT), пока это не получит полную поддержку.
Когда вы в конечном итоге получили матрицу независимо от пути, который вы берете, чтобы получить ее, вам нужно ее инвертировать и примените его к вашим координатам мыши. Затем координаты передаются на холст, который будет использовать свою матрицу, чтобы преобразовать ее назад, где бы она ни находилась.
Таким образом, точка будет в правильном положении относительно мыши. Также здесь вам нужно отрегулировать координаты (перед применением обратной матрицы к ним) относительно элемента.
Пример, показывающий шаги матрицы
function draw(evt) {
var pos = getMousePos(canvas, evt); // get adjusted coordinates as above
var imatrix = matrix.inverse(); // get inverted matrix somehow
pos = imatrix.applyToPoint(pos.x, pos.y); // apply to adjusted coordinate
context.fillStyle = "#000000";
context.fillRect(pos.x-1, pos.y-1, 2, 2);
}
Пример с использованием решения, связанного выше (замените его с помощью встроенного браузера при более широком использовании).
Пример использования currentTransform
при реализации:
var pos = getMousePos(canvas, e); // get adjusted coordinates as above
var matrix = ctx.currentTransform; // W3C (future)
var imatrix = matrix.invertSelf(); // invert
// apply to point:
var x = pos.x * imatrix.a + pos.y * imatrix.c + imatrix.e;
var y = pos.x * imatrix.b + pos.y * imatrix.d + imatrix.f;
Обновление. Я сделал бесплатное решение (MIT), чтобы вставить все эти шаги в один простой в использовании объект, который можно найти здесь здесь , а также позаботится о нескольких других мелочах игнорировать.
Мог попытаться использовать awk
:
<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }'
Вы, возможно, должны удостовериться это <command>
продолжает буферизованный вывод линии, т.е. он сбрасывает свой поток вывода после каждой строки; метка времени awk
добавляет будет время, когда конец строки появился на ее входном канале.
Если awk показывает ошибки, то попробуйте gawk
вместо этого.
Если значение, Вы предварительно ожидаете, является тем же на каждой строке, разожгите emacs с файлом, то:
Ctrl + < space>
в начале файла (для маркировки того пятна) затем прокрутите вниз к началу последней строки (Высокий звук + > пойдет до конца файла..., который, вероятно, включит клавишу Shift также, затем Ctrl + для движения в начало той строки), и:
Ctrl + x r t
, Который является командой для вставки в прямоугольнике, который Вы просто определили (прямоугольник 0 ширин).
21.08.2008 18:45 < enter>
Или независимо от того, что Вы хотите предварительно ожидать... тогда, Вы будете видеть, что текст предварительно ожидал к каждой строке в 0 прямоугольниках ширины.
ОБНОВЛЕНИЕ: Я просто понял, что Вы не хотите ТУ ЖЕ дату, таким образом, это не будет работать..., хотя можно быть в состоянии сделать это в emacs с немного более сложным пользовательским макросом, но тем не менее, этот вид прямоугольного редактирования довольно хорош знать о...
Используйте чтение (1) команда для чтения одной строки за один раз из стандартного входа, затем произведите строку, предварительно ожидаемую с датой в формате выбора с помощью даты (1).
$ cat timestamp
#!/bin/sh
while read line
do
echo `date` $line
done
$ cat somefile.txt | ./timestamp
Ответ Kieron является лучшим до сих пор. Если у Вас есть проблемы, потому что первая программа буферизует, можно использовать освобождать буфер программу:
unbuffer <command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'
Это установлено по умолчанию в большинстве систем Linux. Если необходимо создать его сами, это - часть ожидать пакета
Как насчет этого?
cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'
Оценка от Вашего требования получить живые метки времени, возможно, Вы хотите сделать живое обновление на файле журнала или чем-то? Возможно
tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps
аннотируют , доступный по той ссылке или как annotate-output
в пакете Debian devscripts
.
$ echo -e "a\nb\nc" > lines
$ annotate-output cat lines
17:00:47 I: Started cat lines
17:00:47 O: a
17:00:47 O: b
17:00:47 O: c
17:00:47 I: Finished with exitcode 0
Я не парень Unix, но я думаю, что можно использовать
gawk '{print strftime("%d/%m/%y",systime()) $0 }' < somefile.txt
#! /bin/sh
unbuffer "$@" | perl -e '
use Time::HiRes (gettimeofday);
while(<>) {
($s,$ms) = gettimeofday();
print $s . "." . $ms . " " . $_;
}'