При чтении из текстового файла, пока EOF не повторяет последнюю строку [дубликат]

Простой сценарий 1: 1

В ситуациях, когда элемент холста равен 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), чтобы вставить все эти шаги в один простой в использовании объект, который можно найти здесь здесь , а также позаботится о нескольких других мелочах игнорировать.

117
задан Lightness Races with Monica 9 July 2011 в 22:22
поделиться

3 ответа

Просто следуйте тесно за цепочкой событий.

  • Захват 10
  • Захват 20
  • Захват 30
  • Взгляд EOF

Захвата на предпоследнее повторение. Вы захватили 30, затем продолжили проверять на EOF. Вы не достигли EOF, потому что метка EOF еще не была считана ("binarically" разговор, его концептуальное местоположение сразу после 30 строк). Поэтому Вы продолжаете к следующему повторению. x все еще 30 от предыдущего повторения. Теперь Вы читаете из потока, и Вы добираетесь, EOF. x остается 30 и iOS:: eofbit повышен. Вы производите к stderr x (который равняется 30, точно так же, как в предыдущем повторении). Затем Вы проверяете на EOF в условии цикла, и на этот раз Вы вне цикла.

Попытка это:

while (true) {
    int x;
    iFile >> x;
    if( iFile.eof() ) break;
    cerr << x << endl;
}

Между прочим, в Вашем коде существует другая ошибка. Вы когда-либо пытались выполнить его на пустом файле? Поведение, которое Вы получаете, по той же самой причине.

120
ответ дан wilhelmtell 24 November 2019 в 02:08
поделиться

Мне нравится этот пример, который на данный момент, не учитывает проверку, которую Вы могли добавить в в то время как блок:

ifstream iFile("input.txt");        // input.txt has integers, one per line
int x;

while (iFile >> x) 
{
    cerr << x << endl;
}

Не уверенный, насколько безопасный это...

34
ответ дан Patrick Loz 24 November 2019 в 02:08
поделиться

Существует альтернативный подход к этому:

#include <iterator>
#include <algorithm>

// ...

    copy(istream_iterator<int>(iFile), istream_iterator<int>(),
         ostream_iterator<int>(cerr, "\n"));
15
ответ дан wilhelmtell 24 November 2019 в 02:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: