У меня есть программа HTML/JavaScript, которая использует холст HTML5 для создания красивого графика:
Я хочу включить этот график в книгу, которую я создаю с помощью LaTeX. К сожалению, когда я печатаю эту страницу в формате PDF, я получаю растровое изображение — вероятно, потому, что холст — это растровое изображение.
Я только что проверил, и, очевидно, если бы я разработал это с помощью SVG вместо холста HTML5, мне было бы хорошо идти. Но я этого не сделал. Итак, есть ли способ создать штриховой рисунок из HTML5 Canvas, или я должен просто стиснуть зубы и повторно реализовать это как SVG?
(Я использовал Canvas вместо svg, потому что думал, что Canvas предпочтительнее, современнее и эффективнее. Я ошибался?)
Обновлено: вот мой JavaScript для рисования каждой стрелки. Я считаю, что могу легко перенести это в SVG, используя svg.js
/* Draw a Piece at its rotation at the position row,col */
drawRotatedPiece(p) {
let x = this.x(p.col);
let y = this.y(p.row);
this.ctx.beginPath();
this.ctx.save();
this.ctx.translate( x, y);
this.ctx.fillStyle='white';
this.ctx.fillRect( -this.radius, -this.radius, this.radius*2, this.radius*2 );
this.ctx.rotate( p.angle * Math.PI / 180);
this.ctx.moveTo( 0, -this.radius );
this.ctx.lineTo( -this.radius, 0 );
this.ctx.lineTo( +this.radius, 0 );
this.ctx.closePath( );
this.ctx.fillStyle='black';
this.ctx.fill();
this.ctx.fillRect( -this.radius/2.0, 0, this.radius, this.radius*2/3.0 );
this.ctx.restore();
}
Вам каким-то образом придется воспроизвести вызовы отрисовки API холста HTML5, например, написав класс-оболочку, который обертывает холст HTML5 и преобразует эти вызовы в вызовы, которые записывают команды SVG или PDF. Однако это не совсем просто сделать, в зависимости от того, как вы используете API холста HTML5. Вы должны отредактировать свой вопрос, включив в него код, показывающий, как вы создали графику с помощью API холста HTML5.
В любом случае, ваша графика выглядит достаточно просто — всего лишь набор заштрихованных и заполненных контуров — поэтому моя заметка о Основах SVG может помочь вам перевести графику в SVG.
Нет, вам не нужен svg.js. Ваш код холста довольно прост. Было бы не слишком сложно вручную портировать его в svg. Просто укуси эту пулю. А если вы не знакомы с svg, то это отличный шанс узнать что-то новое. По сути, вам просто нужно выучить атрибут "d" элемента пути.
Последнее, что я проверял, pdf также не поддерживает svg из коробки. Их векторная графика не была совместима с svg, поэтому вместо преобразования в svg лучше изучите их векторный формат (хотя я считаю, что использовать их графический интерфейс может быть проще).
@Kaiido - узнай, чей векторный формат? Я просто попрошу свою веб-силу распечатать в PDF....
@hackape - это для поощрения!
Векторный формат PDF.
Ниже приведен код, который генерирует SVG, который воспроизводит повернутую часть, которую вы указали в своем вопросе. Метод drawRotatedPiece(x, y, radius, angle)
.
// Generate a SVG path command
function xycmd(cmd,x,y){
return cmd+ x + " " + y;
}
function rectpathxy(x,y,w,h){
return xycmd("M", x, y) +
xycmd("L", x+w, y) +
xycmd("L", x+w, y+h) +
xycmd("L", x, y+h) +
"Z";
}
function drawRotatedPiece(x, y, radius, angle){
trans=[];
svg = "";
svg+ = "<path style='stroke:red;fill:white'";
svg+ = " transform='translate("+x+","+y+")'";
svg+ = " d='";
svg+=rectpathxy(-radius, -radius, radius*2, radius*2);
svg+ = "'/>";
svg+ = "<path style='stroke:none;fill:black'";
svg+ = " transform='translate("+x+","+y+") rotate("+angle+")'";
svg+ = " d='";
var w=radius;
var h=radius*2/3.0;
svg+= xycmd("M", 0, -radius) +
xycmd("L", -radius, 0) +
xycmd("L", +radius, 0) +
"Z" +
xycmd("M", x, y) +
xycmd("L", x+w, y) +
xycmd("L", x+w, y+h) +
xycmd("L", x, y+h) +
"Z";
svg+ = "'/>";
return svg;
}
Если вам нужно сгенерировать любую другую графику в формате SVG (особенно простую графику, подобную вашей, которая представляет собой просто набор обведенных и заполненных контуров), моя заметка о Essentials of SVG может помочь вам перевести эту графику в SVG.
(знали ли вы, что у svg есть атрибут преобразования?)
@Kaiido: Да, но я не был знаком с этим в деталях. Я посмотрю, смогу ли я включить этот атрибут.
Вау! Отлично. Но мы хотим использовать transform
....
Этот ответ (отредактированная версия) уже генерирует этот атрибут.
Так и есть! Я попробую это завтра.
@ПитерО. — Большое спасибо за вашу помощь в этом. Я взял то, что вы написали, очистил его и опубликую, но я приму ваше решение, чтобы вы получили признание. Я считаю, что ваш стиль не ставить ;
в конце каждой строки проблематичен, но в остальном ваш код чистый и простой для понимания. Однако я упростил стрелку до одного пути. Я также сделал translate
и rotate
разные преобразования для разных элементов, чтобы знания о рисовании были отделены от того, где происходит рисование. Вскоре я опубликую полный рабочий пример на GitHub.
Продолжение здесь: stackoverflow.com/questions/65485761/…
Пиксели хороши, когда размер вывода фиксирован. Начните говорить о DPI и размере вывода, как это делается при печати, и вам понадобятся изображения разных размеров для заполнения заданной области. Подумайте о своем выборе LaTeX — вы не пытаетесь сохранить изображения страниц книги, вы пытаетесь сохранить данные, используемые для визуализации изображений текста. Вы должны сделать то же самое с изображениями - сохранить их определение, а не их реализацию. Да, просто перерисовать с помощью SVG.