В ситуациях, когда элемент холста равен 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), чтобы вставить все эти шаги в один простой в использовании объект, который можно найти здесь здесь , а также позаботится о нескольких других мелочах игнорировать.
Вот то, что необходимо сделать для включения Firefox, сразу печатают, не показывая предпочтительное диалоговое окно печати.
Введите about:config в адресной панели Firefox и совершите нападки, Входят.
Щелкните правой кнопкой по где угодно на странице и выберите Новый> булевская переменная
Введите предпочтительное имя как печать always_print_silent и нажмите "OK".
Я нашел, что где-нибудь и это помогло мне
Вот два примера кода, которые можно попробовать:
1 :
<script>
function Print() {
alert ("THUD.. another tree bites the dust!")
if (document.layers)
{
window.print();
}
else if (document.all)
{
WebBrowser1.ExecWB(6, 1);
//use 6, 1 to prompt the print dialog or 6, 6 to omit it
//some websites also indicate that 6,2 should be used to omit the box
WebBrowser1.outerHTML = "";
}
}
</script>
<object ID="WebBrowser1" WIDTH="0" HEIGHT="0"
CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2">
</object>
2 :
if (navigator.appName == "Microsoft Internet Explorer")
{
var PrintCommand = '<object ID="PrintCommandObject" WIDTH=0 HEIGHT=0 CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object>';
document.body.insertAdjacentHTML('beforeEnd', PrintCommand);
PrintCommandObject.ExecWB(6, -1); PrintCommandObject.outerHTML = "";
}
else {
window.print();
}
Вы, возможно, должны добавить сайт/страница, Вы тестируете на Вас локальную зону интранет.
Я записал Python tsr, который опросил сервер время от времени (он вытянул свою частоту запросов с сервера), и распечатает для маркировки принтера. Было относительно хорошо.
Когда-то записанный в Python, я использовал py2exe на нем, тогда inno компилятор установки, затем поставивший интранет, и сделал, чтобы пользователь установил его.
Это не было большим, но это работало. Пользователи запустили бы его утром, и программа получит переключатель уничтожения от сервера ночью.
Я имею честно говоря, я - вид размышления вслух здесь.. Но разве это не могло быть сделано с апплетом или некоторым видом (быть им Java или безотносительно), которому дают полномочия, которым доверяют (такие как это в зоне Интранет) или что-то?
май стоить исследовать то, какие полномочия могут быть даны каждой зоне?
После Google, я думаю, что у Вас определенно есть проблема, до сих пор большинство статей, которые я видел, включает печать к принтеры, подключенные к серверу .
, Если бы его внутреннее, было бы возможно направить печать с сервера на принтеры отдела/пользователя или что-то?
Если это - просто внутреннее приложение, то можно постараться не печатать от браузера и отправить распечатку непосредственно с сервера на самый близкий принтер пользователю.