Артём Мáлков

Как сделать скриншот элемента на JavaScript?

7 фев28 комм

Для тех, кто еще не знает, что такое скриншот (screenshot) поясню: это снимок экрана вашего компьютера.

Существует множество различных дополнений (включая стандартные функции Windows), которые позволяют сделать этот снимок.

Но мы же с вами вебмастера, а значит, пойдем куда глубже – научимся делать скриншот не всего экрана, а только сайта или отдельного его элемента.

Где это может вам пригодиться – вы решаете сами, а мне это пригодилось для написания простого модуля оформления заказа, где я смог прикреплять итоговое изображение из конструктора мебели к e-mail-письму.

Для реализации поставленных целей мы будем использовать очень классную библиотеку под названием «html2canvas».

1. Скачайте архив в конце статьи, содержимое разархивируйте и файл библиотеки загрузите к себе на сайт, после чего перед закрывающим тегом </head> подключите его:

<script type="text/javascript" src="/js/html2canvas.js"></script>

Не забывайте проставить корректную ссылку до файла.

2. Далее на нужную страницу, перед закрывающим тегом </body>, вставляем скрипт, который и будет делать скриншот элемента:

<script>

	window.onload = function() {
		
		html2canvas(document.getElementById("content")).then(function(canvas) {

			var my_screen = canvas;

		});	
	
	}

</script>

Здесь «content» – это идентификатор элемента, который и нужно заскринить, а «my_screen» – это переменная, содержащая наш снимок в формате base64.

Что мы можем сделать с полученными данными? Сохранить и вывести изображение с помощью PHP-скрипта (об этом вы можете почитать в отдельной нашей статье), а можете вставить на страницу в нужное место.

Тогда итоговый вариант скрипта будет таким:

<script>

	window.onload = function() {
		
		html2canvas(document.getElementById("content")).then(function(canvas) {

			var my_screen = canvas;

			document.getElementById("result").appendChild(my_screen);

		});	
	
	}

</script>

Где «result» – это ID элемента, куда нужно вывести ваше изображение.

Можно ли отключить автоматическое создание скриншота?

Да. Создание скриншота можно привязать к ссылке или кнопке, а как именно, я сейчас покажу.

HTML-код будет выглядеть следующим образом (все элементы вы можете разделить и поместить в нужные участки вашего сайта):

<div id="content">Hello, world!</div>

Ваш скриншот:
<div id="result"></div>

<a href="javascript: void(0);" id="get_images">Сделать скриншот элемента</a>

И, соответственно, скрипт:

<script>

	window.onload = function() {
		
		document.getElementById("get_images").onclick = function() {

			html2canvas(document.getElementById("content")).then(function(canvas) {

				var my_screen = canvas;

				document.getElementById("result").appendChild(my_screen);

			});

		};
	
	}

</script>

В таком случае скриншот элемента будет создаваться и выводиться только после нажатия на указанную ссылку.

Вот все, что я хотел вам рассказать о данной библиотеке и о том, как сделать скриншот отдельного элемента на вашем сайте. Если что-то вам показалось непонятным – пишите об этом в комментариях.

Файл
Размер
Ссылка
html2canvas.zip
60,07 Kb
Скачать с сервера
Рекомендуем к просмотру
Четыре красивых эффекта падающего снега на jQuery/JavaScript/CSS3
Модули и скрипты
Увеличение изображения с эффектом лупы на jQuery
Модули и скрипты
Выводим изображение в кодировке Base64 на HTML/CSS и сохраняем его на jQuery+PHP
Статьи и советы
28
комментариев
Форма комментирования этого поста скрыта. Авторизуйтесь, чтобы расширить привилегии гостевого посещения и получить необходимую помощь от сообщества Pandoge.
    • 0
    1
      •  Пользователь
    17 ноя в 02:04

    А как реализовать скриншот на iframe

    • 2
    1
      •  Пользователь
    1 сен в 16:46

    Артем Мáлков, спасибо за статью, полезно.

    Подскажите, как дальше можно поступить, необходимо сделать кнопку для копирования полученного изображения. html2canvas умеет это?

      • 1
      1066
        •  Команда Pandoge
      1 сен в 18:15

      V Tapok, копировать нужно в буфер?

      • 1
      1
        •  Проверенный
      3 мая в 06:38

      Артём Мáлков, А как можно скачать полученный скриншот в формате jpg для клиента?

    • 1
    5
      •  Проверенный
    19 июл в 20:52

    Артем, вы обещали попозже написать статью на вопрос вашего тезки: "А как взять скриншот элемента с другой страницы и вставить в текущую. В пределах одного сайта." У меня похожий вопрос - как сделать скриншот блока с текущей страницы и вставить ее в другую в пределах сайта?

      • 1
      1066
        •  Команда Pandoge
      19 июл в 21:38

      Jan, здравствуйте.

      В Вашем случае:

      1. Делаете скриншот.

      2. Сохраняете его на сервере + ссылку записываете в куки.

      3. На нужной странице (если куки не пустые) вставляете ссылку на ранее загруженный файл.

      • 1
      5
        •  Проверенный
      19 июл в 22:29

      Спасибо, Артем! У меня не получается сохранить на сервере. Делал все как написано в https://www.pandoge.com/stati_i_sovety/vyvodim-izobrazhenie-v-kodirovke-base64-na-html-css-i-sohranyaem-ego-na-jqueryphp и ваш ответ на комментарий Саше велиханову. Ни в какую. Папка images всегда пустая.

      • 1
      1066
        •  Команда Pandoge
      19 июл в 23:40

      Jan, покажите сайт, где пробуете реализацию.

      • 1
      5
        •  Проверенный
      20 июл в 23:01

      Здравствуйте, Артем! Специально для тестирования создал http://canvas.hys.cz/index.html – здесь все в порядке. И http://canvas.hys.cz/test2.html – пытаюсь сохранить скриншот на сервер. Файл base-image.php (у меня все в root, поэтому слэши перед images удалил):

      $name = $_SERVER["REMOTE_ADDR"]."_".time().".jpg";

      $check_save = @file_put_contents("images/".$name, base64_decode($_POST["data"]));

      • 1
      1066
        •  Команда Pandoge
      20 июл в 23:54

      > http://canvas.hys.cz/index.html – здесь все в порядке.

      У меня не работает. И по консоли я не вижу, чтобы при клике происходил запрос на сервер.

      • 1
      5
        •  Проверенный
      21 июл в 00:06

      Странно, но вдруг заработало))

      • 1
      1066
        •  Команда Pandoge
      21 июл в 00:12

      Jan, магия slim

      В хроме - о.к, но в firefox не работает.

      • 1
      5
        •  Проверенный
      21 июл в 00:35

      В коде я не допустил ошибку?

      • 1
      1066
        •  Команда Pandoge
      21 июл в 01:52

      Jan, нет, просто FF считает это небезопасной операцией.

      В index.html скрипт:

      <script>
      	window.onload = function() {
      		document.getElementById("get_images").onclick = function() {
      			html2canvas(document.getElementById("content")).then(function(canvas) {
      				var my_screen = canvas;
      				document.getElementById("result").appendChild(my_screen);
      			});
      		};
      	}
      </script>

      замените на:

      <script>
      	window.onload = function() {
      		document.getElementById("get_images").onclick = function() {
      			html2canvas(document.getElementById("content")).then(function(canvas) {
      				var my_screen = canvas;
      				my_screen.crossOrigin = "anonymous";
      				document.getElementById("result").appendChild(my_screen);
      			});
      		};
      	}
      </script>
    • 1
    6
      •  Пользователь
    7 мая в 20:52

    Не подскажете ли можно вместо (html): Ваш скриншот: и (php) document.getElementById("result").appendChild(my_screen); указать путь сохранения изображения к папке на сервере сайта, пр этом, чтобы клик нового пользователя сохранял изображение под "своим" именем (не перезаписывая предшествующее).

      • 1
      1066
        •  Команда Pandoge
      8 мая в 03:18

      Саша велиханов, Здравствуйте. Совсем забыл, что на эту тему у нас уже есть статья - https://www.pandoge.com/stati_i_sovety/vyvodim-izobrazhenie-v-kodirovke-base64-na-html-css-i-sohranyaem-ego-na-jqueryphp

      Но раз я поздно о ней вспомнил, держите простую реализацию. smiley

      1. В head подключите jQuery + библиотеку html2canvas:

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
      <script src="/js/html2canvas.js"></script>

      2. Выведите кнопку для создания скриншота + определите элемент, который будете снимать.

      <div id="content">Hello, world!</div>
      
      <a href="javascript: void(0);" id="get_images">Сделать скриншот элемента</a>

      3. Создайте PHP-файл base-image.php с содержимым:

      <?php
      
      	$name = $_SERVER["REMOTE_ADDR"]."_".time().".jpg";
      
      	$check_save = @file_put_contents("./images/".$name, base64_decode($_POST["data"]));
      	
      ?>

      Где images - папка для сохранения скриншотов, которая находится нарядом со скриптом (если ее нет - создайте).

      На страницу, в низ сайта вставьте:

      <script>
      
      	$(document).ready(function() {
      
      		$("#get_images").on("click", function() {
      
      			html2canvas(document.getElementById("content")).then(function(canvas) {
      
      				$.post("/base-image.php", {
      		
      					data: canvas.toDataURL("image/jpeg").replace("data:image/jpeg;base64,", "")
      			
      				});
      
      			});
      
      		});
      	
      	});
      
      </script>

      Где get_images - ID ссылки, по нажатию на которую будет отправляться файл для сохранения, а /base-image.php - путь до PHP-файла на вашем сайте.

      Все скриншоты будут иметь имена в виде IP-адрес пользователя_время.jpg

      Как-то так glass

      • 1
      6
        •  Пользователь
      8 мая в 12:40

      Артем, спасибо вам за оперативный ответ. Ваш код работает! Однако, html2canvas похоже не тянет делать снимок большой области экрана. Если между <div id="content"> </div> помещаю пару абзацев - без проблем, а при снимке всей страницы jpg получается пустой,и открыть его не получается, файл поврежден либо слишком велик.

      • 1
      1066
        •  Команда Pandoge
      8 мая в 13:15

      Саша велиханов, попробуйте использовать этот скрипт:

      <script>
      
      	$(document).ready(function() {
      
      		$("#get_images").on("click", function() {
      
      			html2canvas(document.getElementById("content")).then(function(canvas) {
      
      				canvas.width = document.body.clientWidth;
      				canvas.height = document.body.clientHeight;
      				canvasW = canvas.width;
      				canvasH = canvas.height;
      	
      				$.post("/base-image.php", {
      
      					data: canvas.toDataURL("image/jpeg").replace("data:image/jpeg;base64,", "")
      
      				});
      
      			});
      
      		});
      
      	});
      
      </script>
      • 1
      6
        •  Пользователь
      8 мая в 15:37

      Артем, если правильно понял, добавлены

      canvas.width = document.body.clientWidth;

      canvas.height = document.body.clientHeight;

      canvasW = canvas.width;

      canvasH = canvas.height;

      Теперь вместо картинки изображение черный квадрат. К сожалению...

      • 1
      1066
        •  Команда Pandoge
      8 мая в 17:44

      Саша велиханов, скрипт замените на этот:

      <script>
      
      	$(document).ready(function() {
      
      		$("#get_images").on("click", function() {
      
      			html2canvas(document.getElementById("content")).then(function(canvas) {
      
      				$.post("/base-image.php", {
      
      					data: canvas.toDataURL("image/png").replace("data:image/png;base64,", "")
      
      				});
      
      			});
      
      		});
      
      	});
      
      </script>

      Файл base-image.php замените на:

      <?php
      
      	$name = $_SERVER["REMOTE_ADDR"]."_".time().".png";
      
      	$check_save = @file_put_contents("./".$name, base64_decode($_POST["data"]));
      	
      ?>

      В стили добавьте:

      .html2canvas-container {
      	width: 5000px !important;
      	height: 5000px !important;
      }
      • 1
      6
        •  Пользователь
      8 мая в 18:36

      Увы и ах, Артем. Между <script></script> изменений не увидел, но перенес его к себе вслепую. Сохранение .png вместо .jpg в корневую директорию .php файла не помогает. Стили добавил и между <style></style> и в основной css файл дублировал на всякий случай. Склонен думать, что сам html2canvas выше какого-то пограничного размера не тянет. Картинка открывается с пометкой поврежден или слишком большой (1кб).

      • 1
      1066
        •  Команда Pandoge
      8 мая в 18:55

      Саша велиханов, исключено. Когда я проверял, вышел скриншот размерами 1349x936 px. Покажите адрес сайта, где используется скрипт.

      • 1
      6
        •  Пользователь
      9 мая в 10:56

      Артем, если у вас выходит скриншот - значит проблемы где-то на моей стороне. Еще раз буду пытаться по инструкции все прогнать заново. По результатам отпишусь, спасибо вам.

      • 2
      6
        •  Пользователь
      10 мая в 13:30

      Артем, выяснил в чем было дело. Оказался на странице задвоен jquery. Зашел в консоль браузера, а там сплошные ошибки. Убрал лишний jquery и все работает как часы. Еще раз спасибо за поддержку и ваш сайт.

    • 1
    766
      •  Гости
    7 сен в 22:20

    Здравствуйте. У меня на сайте на странице есть блок с flash:

    <object width="600" height="600">
    	<param name="movie" value="/kitsane.swf">
    	<embed src="/tobor/identikit.swf" width="1000" height="700"></embed>
    </object>

    Как сделать применив ваш код выше чтобы получался скриншот именно этого блока с флэшем? Пробую вставлять код вывода флэша между вашим <div id="content"> и </div> , получается просто чистый белый скриншот ( Заранее благодарю за ответ!!!

    • 1
    766
      •  Гости
    28 авг в 13:06

    А как взять скриншот элемента с другой страницы и вставить в текущую. В пределах одного сайта.

      • 1
      1066
        •  Команда Pandoge
      28 авг в 22:54

      Артем, попозже напишем статью как сделать.

      • 2
      1
        •  Пользователь
      21 фев в 09:42

      NodeJS в помощь)

Подняться наверх
«Pandoge» - помощник вебмастера