Saving image as Base64 string in Javascript using LiterallyCanvas - javascript

I've taken a demo from the open source LiterallyCanvas, where you can take an image from your desktop and draw on it, then click save to get it as a base64 string. I've modified the code a bit and it currently allows me to draw an arrow, ellipsis and free drawing. But since the code sets the image as a background image, when I hit save, the base64 string only saves with the drawings I made, not the image I chose as well.
Can anyone tell me where I've gone wrong? I assume it's because I just set the background, but I don't know how to save that as well. I basically want the program to load an image, draw perhaps an arrow on it, then save the image with the arrow on it as well. As a Base64 string.
Here is the current code:
<html><head>
<title>Canvas</title>
<link href="../_assets/literallycanvas.css" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
</head>
<body>
<div class="fs-container">
<div class="literally toolbar-hidden toolbar-hidden toolbar-hidden toolbar-hidden toolbar-hidden">
<div class="lc-drawing" style="background-color: transparent;">
<canvas width="1158" height="600" style="width: 1158px; height: 600;"></canvas>
<canvas width="1158" height="600" style="background-color: transparent; width: 1158px; height: 600;"></canvas>
</div>
</div>
<div class="toolset">
<span class="toolLabel">Actions:</span>
<input type='file' id='getval' name="background-image" onchange="readURL(event)" /><br/><br/>
Save
Cancel
</div>
<div class="toolset">
<span class="toolLabel">Tools:</span>
Pencil
Arrow
Ellipse
</div>
<div class="toolset" id="tools-colors">
<span class="toolLabel">Colors:</span>
Red
</div>
<script src="../_js_libs/jquery-3.0.0.js"></script>
<script src="../_js_libs/literallycanvas-core.js"></script>
<script type="text/javascript">
var lc = null;
var tools;
var strokeWidths;
var colors;
var setCurrentByName;
var findByName;
function readURL(event){
var getImagePath = URL.createObjectURL(event.target.files[0]);
$('.lc-drawing').css('background-image', 'url(' + getImagePath + ')'),
$('.lc-drawing').css('background-repeat', 'no-repeat');
}
// the only LC-specific thing we have to do
var containerOne = document.getElementsByClassName('literally')[0];
var showLC = function() {
lc = LC.init(containerOne, {
snapshot: JSON.parse(localStorage.getItem('drawing')),
defaultStrokeWidth: 10,
strokeWidths: [10, 20, 50],
secondaryColor: 'transparent'
});
window.demoLC = lc;
var save = function() {
localStorage.setItem('drawing', JSON.stringify(lc.getSnapshot()));
}
lc.on('drawingChange', save);
lc.on('pan', save);
lc.on('zoom', save);
$("#open-image").click(function() {
window.open(lc.getImage({
scale: 1, margin: {top: 10, right: 10, bottom: 10, left: 10}
}).toDataURL());
});
$("#change-size").click(function() {
lc.setImageSize(null, 200);
});
$("#reset-size").click(function() {
lc.setImageSize(null, null);
});
$("#clear-lc").click(function() {
lc.clear();
});
tools = [
{
name: 'pencil',
el: document.getElementById('tool-pencil'),
tool: new LC.tools.Pencil(lc)
},{
name: 'arrow',
el: document.getElementById('tool-arrow'),
tool: function() {
arrow = new LC.tools.Line(lc);
arrow.hasEndArrow = true;
return arrow;
}()
},{
name: 'ellipse',
el: document.getElementById('tool-ellipse'),
tool: new LC.tools.Ellipse(lc)
},{
name: 'tool-rectangle',
el: document.getElementById('tool-rectangle'),
tool: new LC.tools.Rectangle(lc)
}
];
colors = [
{
name: 'black',
el: document.getElementById('colorTool-black'),
color: '#000000'
},{
name: 'red',
el: document.getElementById('colorTool-red'),
color: '#ff0000'
}
];
setCurrentByName = function(ary, val) {
ary.forEach(function(i) {
$(i.el).toggleClass('current', (i.name == val));
});
};
findByName = function(ary, val) {
var vals;
vals = ary.filter(function(v){
return v.name == val;
});
if ( vals.length == 0 )
return null;
else
return vals[0];
};
// Wire tools
tools.forEach(function(t) {
$(t.el).click(function() {
var sw;
lc.setTool(t.tool);
setCurrentByName(tools, t.name);
setCurrentByName(strokeWidths, t.tool.strokeWidth);
$('#tools-sizes').toggleClass('disabled', (t.name == 'text'));
});
});
setCurrentByName(tools, tools[0].name);
// Wire Stroke Widths
strokeWidths.forEach(function(sw) {
$(sw.el).click(function() {
lc.trigger('setStrokeWidth', sw.size);
setCurrentByName(strokeWidths, sw.name);
})
})
setCurrentByName(strokeWidths, strokeWidths[0].name);
// Wire Colors
colors.forEach(function(clr) {
$(clr.el).click(function() {
lc.setColor('primary', clr.color)
setCurrentByName(red, red);
})
})
setCurrentByName(red, red);
};
$(document).ready(function() {
$(document).bind('touchmove', function(e) {
if (e.target === document.documentElement) {
return e.preventDefault();
}
});
showLC();
});
$('#hide-lc').click(function() {
if (lc) {
lc.teardown();
lc = null;
}
});
$('#show-lc').click(function() {
if (!lc) { showLC(); }
});
</script>

Use the getImage() function from the Literallycanvas instance to get a drawn canvas and then you can call toDataURL() to get the base64 string.
Read more in their docs: http://literallycanvas.com/examples/export.html
Regardless of what’s displayed in the viewport, you can export the complete drawing, or any subset of the drawing, using getImage().
These examples export your drawing as a PNG in a new window. The conversion to PNG is handled by the built-in canvas function toDataURL(). To learn more about what image formats are available, refer to Mozilla’s canvas element reference.
I personally use file-saver to download the image instead of using the base64 myself:
lc.getImage().toBlob(
blob => {
saveAs(blob, fileName);
},
"image/jpeg",
1
);

Related

How can I add a menu screen that loads first to my Phaser.js game?

Im trying to add a simple menu to my Phaser game that loads first, then once someone clicks on a button the game actually starts. I can figure out how to add the buttons later, I just cannot figure out how to add the menu screen. Ive researched quite a few ways online on how to get this done but none have worked for me. I've also tried breaking the code up into different states but that didnt work for me either. Maybe I was doing it incorrectly. Can someone show me correct way to add a menu to my game that loads before the actual game does?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>test</title>
<script src="//cdn.jsdelivr.net/npm/phaser#3.1.1/dist/phaser.js"></script>
<script type="text/javascript" src="menu.js"></script>
<style type="text/css">
body {
margin-top: 45px;
margin-left: 250px;
background-color: black;
}
.page-title {
color: white;
}
</style>
</head>
<body>
<script type="text/javascript">
//CONFIGURE GAME
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update,
}
};
var player;
var stars;
var bombs;
var platforms;
var cursors;
var score = 0;
var gameOver = false;
var scoreText;
var game = new Phaser.Game(config);
game.state.add('title', title);
game.state.start('title');
//PRELOAD FUNCTION
function preload ()
{
this.load.image('sky', 'phaser_assets/sky.png');
this.load.image('background', 'phaser_assets/background.png');
this.load.image('ground', 'phaser_assets/platform.png');
this.load.image('star', 'phaser_assets/star.png');
this.load.image('bomb', 'phaser_assets/head1.png', { frameWidth: 48, frameHeight: 100 });
this.load.spritesheet('trump', 'phaser_assets/trump.png', { frameWidth: 48, frameHeight: 100 });
}
//CREATE FUNCTION
function create ()
{
// A simple background for our game
this.add.image(400, 300, 'sky');
// The platforms group contains the ground and the 2 ledges we can jump on
platforms = this.physics.add.staticGroup();
// Here we create the ground.
// Scale it to fit the width of the game (the original sprite is 400x32 in size)
platforms.create(400, 568, 'ground').setScale(2).refreshBody();
// Now let's create some ledges
platforms.create(600, 400, 'ground');
platforms.create(50, 250, 'ground');
platforms.create(750, 220, 'ground');
// The player and its settings
player = this.physics.add.sprite(100, 450, 'trump');
// Player physics properties. Give the little guy a slight bounce.
player.setBounce(0.2);
player.setCollideWorldBounds(true);
}
//UPDATE FUNCTION
function update ()
{
if (gameOver)
{
return;
}
if (cursors.left.isDown)
{
player.setVelocityX(-200);
player.anims.play('left', true);
}
else if (cursors.right.isDown)
{
player.setVelocityX(200);
player.anims.play('right', true);
}
else
{
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down)
{
player.setVelocityY(-330);
}
}
</script>
</body>
</html>

Let user delete a selected fabric js object

I have a simple fabric js based application where I will let users add shapes connect them and animate them.
Following is my JS
var canvas;
window.newAnimation = function(){
canvas = new fabric.Canvas('canvas');
}
window.addRect = function(){
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'red',
width: 20,
height: 20,
});
canvas.add(rect);
}
window.addCircle = function(){
var circle = new fabric.Circle({
radius: 20, fill: 'green', left: 100, top: 100
});
canvas.add(circle);
}
This is my Fiddle. You can click on new animation and then add objects as of now.
I want the user to select some object and then also be able to delete it I am not sure how. I found this Delete multiple Objects at once on a fabric.js canvas in html5 But i was not able to implement it successfully. I basically want users to be able to select an object and delete it.
Since new version of fabric.js was released - you should use:
canvas.remove(canvas.getActiveObject());
Edit: This is for older versions now.
You can use the remove() method, eg.
window.deleteObject = function() {
canvas.getActiveObject().remove();
}
jsfiddle
Delete all selected objects:
canvas.getActiveObjects().forEach((obj) => {
canvas.remove(obj)
});
canvas.discardActiveObject().renderAll()
I am using Fabric JS 2.3.6.
I wanted to allow the user to select one or more objects on the canvas and delete them by clicking the delete button.
Removed methods from old versions
The following methods are no longer available since the introduction of ActiveSelection:
setActiveGroup(group);
getActiveGroup();
deactivateAll();
discardActiveGroup();
deactivateAllWithDispatch();
Here is my code that works great for me and hopefully you as well.
$('html').keyup(function(e){
if(e.keyCode == 46) {
deleteSelectedObjectsFromCanvas();
}
});
function deleteSelectedObjectsFromCanvas(){
var selection = canvas.getActiveObject();
if (selection.type === 'activeSelection') {
selection.forEachObject(function(element) {
console.log(element);
canvas.remove(element);
});
}
else{
canvas.remove(selection);
}
canvas.discardActiveObject();
canvas.requestRenderAll();
}
It's pretty simple actually.
Just use Fabric's event handling to manage the object selection, and then fire the delete function for whatever object is selected.
I'm using the canvas selection events to cover all the objects of the canvas. The idea is to add a delete button, keeping it hidden unless needed, and then handling its display on canvas selection events.
Deletion is made easy with the help of remove property of the Fabric library, which obviously triggers when the delete button is clicked.
Here is some sample code to demo what I said above.
// Grab the required elements
var canvas = new fabric.Canvas('c'),
delBtn = document.getElementById('delete')
// Hide the delete button until needed
delBtn.style.display = 'none'
// Initialize a rectangle object
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'red',
width: 100,
height: 50
})
// Initialize a circle object
var circle = new fabric.Circle({
left: 250,
top: 100,
radius: 20,
fill: 'purple'
})
// Add objects to the canvas
canvas.add(rect)
canvas.add(circle)
// When a selection is being made
canvas.on({
'selection:created': () => {
delBtn.style.display = 'inline-block'
}
})
// When a selection is cleared
canvas.on({
'selection:cleared': () => {
delBtn.style.display = 'none'
}
})
// Rmove the active object on clicking the delete button
delBtn.addEventListener('click', e => {
canvas.remove(canvas.getActiveObject())
})
body {
background-color: #eee;
color: #333;
}
#c {
background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>
<h4>Select an object</h4>
<canvas id="c" width="600" height="200"></canvas>
<input type="button" id="delete" value="Delete selection">
Easy, wasn't it? Cheers!
On further improving #Rahul answer, we can also support deletion of selected object using key events like 'Delete', 'Backscape'.
// Grab the required elements
var canvas = new fabric.Canvas('c'),
delBtn = document.getElementById('delete'),
wrapper= document.getElementById('canvasWrapper')
// Hide the delete button until needed
delBtn.style.display = 'none'
// Initialize a rectangle object
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'red',
width: 100,
height: 50
})
// Initialize a circle object
var circle = new fabric.Circle({
left: 250,
top: 100,
radius: 20,
fill: 'purple'
})
// Add objects to the canvas
canvas.add(rect)
canvas.add(circle)
// When a selection is being made
canvas.on({
'selection:created': () => {
delBtn.style.display = 'inline-block'
}
})
// When a selection is cleared
canvas.on({
'selection:cleared': () => {
delBtn.style.display = 'none'
}
})
// Rmove the active object on clicking the delete button
delBtn.addEventListener('click', e => {
canvas.remove(canvas.getActiveObject())
})
//Remove using keyboard events
wrapper.addEventListener('keyup', e => {
if (
e.keyCode == 46 ||
e.key == 'Delete' ||
e.code == 'Delete' ||
e.key == 'Backspace'
) {
if (canvas.getActiveObject()) {
if (canvas.getActiveObject().isEditing) {
return
}
canvas.remove(canvas.getActiveObject())
}
}
})
body {
background-color: #eee;
color: #333;
}
#c {
background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>
<h4>Select an object</h4>
<div tabIndex="1000"id="canvasWrapper" #keyup="checkDelete($event)" >
<canvas id="c" width="600" height="200"></canvas>
</div>
<input type="button" id="delete" value="Delete selection">
Delete object in Fabricjs. This works completely fine.
this.canvas.getActiveObjects().forEach((o) => {
this.canvas.remove(o);
});
you can delete active object by using backspace key
$(document).keydown(function(event){
if (event.which == 8) {
if (canvas.getActiveObject()) {
canvas.getActiveObject().remove();
}
}
});

Capture html div content as image object [duplicate]

I am building something called the "HTML Quiz". It's completely ran on JavaScript and it's pretty cool.
At the end, a results box pops up that says "Your Results:" and it shows how much time they took, what percentage they got, and how many questions they got right out of 10. I would like to have a button that says "Capture results" and have it somehow take a screenshot or something of the div, and then just show the image captured on the page where they can right click and "Save image as."
I really would love to do this so they can share their results with others. I don't want them to "copy" the results because they can easily change that. If they change what it says in the image, oh well.
Does anyone know a way to do this or something similar?
No, I don't know of a way to 'screenshot' an element, but what you could do, is draw the quiz results into a canvas element, then use the HTMLCanvasElement object's toDataURL function to get a data: URI with the image's contents.
When the quiz is finished, do this:
var c = document.getElementById('the_canvas_element_id');
var t = c.getContext('2d');
/* then use the canvas 2D drawing functions to add text, etc. for the result */
When the user clicks "Capture", do this:
window.open('', document.getElementById('the_canvas_element_id').toDataURL());
This will open a new tab or window with the 'screenshot', allowing the user to save it. There is no way to invoke a 'save as' dialog of sorts, so this is the best you can do in my opinion.
This is an expansion of #Dathan's answer, using html2canvas and FileSaver.js.
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
theCanvas = canvas;
canvas.toBlob(function(blob) {
saveAs(blob, "Dashboard.png");
});
}
});
});
});
This code block waits for the button with the id btnSave to be clicked. When it is, it converts the widget div to a canvas element and then uses the saveAs() FileSaver interface (via FileSaver.js in browsers that don't support it natively) to save the div as an image named "Dashboard.png".
An example of this working is available at this fiddle.
After hours of research, I finally found a solution to take a screenshot of an element, even if the origin-clean FLAG is set (to prevent XSS), that´s why you can even capture for example Google Maps (in my case). I wrote a universal function to get a screenshot. The only thing you need in addition is the html2canvas library (https://html2canvas.hertzen.com/).
Example:
getScreenshotOfElement($("div#toBeCaptured").get(0), 0, 0, 100, 100, function(data) {
// in the data variable there is the base64 image
// exmaple for displaying the image in an <img>
$("img#captured").attr("src", "data:image/png;base64,"+data);
});
Keep in mind console.log() and alert() won´t generate output if the size of the image is great.
Function:
function getScreenshotOfElement(element, posX, posY, width, height, callback) {
html2canvas(element, {
onrendered: function (canvas) {
var context = canvas.getContext('2d');
var imageData = context.getImageData(posX, posY, width, height).data;
var outputCanvas = document.createElement('canvas');
var outputContext = outputCanvas.getContext('2d');
outputCanvas.width = width;
outputCanvas.height = height;
var idata = outputContext.createImageData(width, height);
idata.data.set(imageData);
outputContext.putImageData(idata, 0, 0);
callback(outputCanvas.toDataURL().replace("data:image/png;base64,", ""));
},
width: width,
height: height,
useCORS: true,
taintTest: false,
allowTaint: false
});
}
If you wish to have "Save as" dialog, just pass image into php script, which adds appropriate headers
Example "all-in-one" script script.php
<?php if(isset($_GET['image'])):
$image = $_GET['image'];
if(preg_match('#^data:image/(.*);base64,(.*)$#s', $image, $match)){
$base64 = $match[2];
$imageBody = base64_decode($base64);
$imageFormat = $match[1];
header('Content-type: application/octet-stream');
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Disposition: attachment; filename=\"file.".$imageFormat."\";" ); //png is default for toDataURL
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".strlen($imageBody));
echo $imageBody;
}
exit();
endif;?>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver=1.7.2'></script>
<canvas id="canvas" width="300" height="150"></canvas>
<button id="btn">Save</button>
<script>
$(document).ready(function(){
var canvas = document.getElementById('canvas');
var oCtx = canvas.getContext("2d");
oCtx.beginPath();
oCtx.moveTo(0,0);
oCtx.lineTo(300,150);
oCtx.stroke();
$('#btn').on('click', function(){
// opens dialog but location doesnt change due to SaveAs Dialog
document.location.href = '/script.php?image=' + canvas.toDataURL();
});
});
</script>
Add this Script in your index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
Use this function to get screenshot of div tag
getScreenShot(){
let c = this.elem.nativeElement.querySelector('.chartContainer'); // or document.getElementById('canvas');
html2canvas(c).then((canvas:any)=>{
var t = canvas.toDataURL().replace("data:image/png;base64,", "");
this.downloadBase64File('image/png',t,'image');
})
}
downloadBase64File(contentType:any, base64Data:any, fileName:any) {
const linkSource = `data:${contentType};base64,${base64Data}`;
const downloadLink = document.createElement("a");
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
}
You can't take a screen-shot: it would be an irresponsible security risk to let you do so. However, you can:
Do things server-side and generate an image
Draw something similar to a Canvas and render that to an image (in a browser that supports it)
Use some other drawing library to draw directly to the image (slow, but would work on any browser)
var shot1=imagify($('#widget')[0], (base64) => {
$('img.screenshot').attr('src', base64);
});
Take a look at htmlshot package , then, check deeply the client side section:
npm install htmlshot
<script src="/assets/backend/js/html2canvas.min.js"></script>
<script>
$("#download").on('click', function(){
html2canvas($("#printform"), {
onrendered: function (canvas) {
var url = canvas.toDataURL();
var triggerDownload = $("<a>").attr("href", url).attr("download", getNowFormatDate()+"电子签名详细信息.jpeg").appendTo("body");
triggerDownload[0].click();
triggerDownload.remove();
}
});
})
</script>
quotation
It's to simple you can use this code for capture the screenshot of particular area
you have to define the div id in html2canvas. I'm using here 2 div-:
div id="car"
div id ="chartContainer"
if you want to capture only cars then use car i'm capture here car only you can change chartContainer for capture the graph
html2canvas($('#car')
copy and paste this code
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Simple Line Chart"
},
axisY:{
includeZero: false
},
data: [{
type: "line",
dataPoints: [
{ y: 450 },
{ y: 414},
{ y: 520, indexLabel: "highest",markerColor: "red", markerType: "triangle" },
{ y: 460 },
{ y: 450 },
{ y: 500 },
{ y: 480 },
{ y: 480 },
{ y: 410 , indexLabel: "lowest",markerColor: "DarkSlateGrey", markerType: "cross" },
{ y: 500 },
{ y: 480 },
{ y: 510 }
]
}]
});
chart.render();
}
</script>
</head>
<body bgcolor="black">
<div id="wholebody">
<button style="background:aqua; cursor:pointer">Get Screenshot of Cars onl </button>
<div id="car" align="center">
<i class="fa fa-car" style="font-size:70px;color:red;"></i>
<i class="fa fa-car" style="font-size:60px;color:red;"></i>
<i class="fa fa-car" style="font-size:50px;color:red;"></i>
<i class="fa fa-car" style="font-size:20px;color:red;"></i>
<i class="fa fa-car" style="font-size:50px;color:red;"></i>
<i class="fa fa-car" style="font-size:60px;color:red;"></i>
<i class="fa fa-car" style="font-size:70px;color:red;"></i>
</div>
<br>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="box1">
</div>
</div>>
</body>
<script>
function genScreenshotgraph()
{
html2canvas($('#car'), {
onrendered: function(canvas) {
var imgData = canvas.toDataURL("image/jpeg");
var pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0, -180, -180);
pdf.save("download.pdf");
}
});
}
</script>
</html>
As far as I know you can't do that, I may be wrong. However I'd do this with php, generate a JPEG using php standard functions and then display the image, should not be a very hard job, however depends on how flashy the contents of the DIV are
Add to your html file and id="capture" to the div you want to take screenshot
<a id="btn-Convert-Html2Image" href="#">Download</a>
<script src="capture.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js" type="text/javascript"></script>
In capture.js add:
document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
html2canvas(document.getElementById("capture")).then(function (canvas) {
var anchorTag = document.createElement("a");
anchorTag.download = "filename.jpg";
anchorTag.href = canvas.toDataURL();
anchorTag.target = '_blank';
anchorTag.click();
});
});
Then, just press download and it will download the screenshot
Or you can view screenshot img by add
<div id="previewImg"></div>
in html code is where you want to view that img and js code will be
document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
html2canvas(document.getElementById("capture")).then(function (canvas) {
var anchorTag = document.createElement("a");
document.body.appendChild(anchorTag);
document.getElementById("previewImg").appendChild(canvas);
anchorTag.click();
});
});
This is an ~11 year old answer. Please ignore this answer and check other recent answers here
As far as I know its not possible with javascript.
What you can do for every result create a screenshot, save it somewhere and point the user when clicked on save result. (I guess no of result is only 10 so not a big deal to create 10 jpeg image of results)

How to change color of a set of nodes in kinetic js?

SO I have a lot of Kinetic polygons, and I collect them and store in a variable like this:
var midr = layer.find('.midr');
I want to change their colors, so I want to delete them and draw them with different colour:
midr.on('mouseover',function(){
midr.destroy();
Boxes.MidR(color.R,color.G,color.B,1,'midr');
midr = layer.find('.midr');
});
midr.on('mouseout',function(){
midr.destroy();
Boxes.MidR(color.R,color.G,color.B,0,'midr');
midr = layer.find('.midr');
});
where:
var Boxes={
.....
MidR:function(R,G,B,A,group){
var C = shade(R,G,B,25,"+");
Mid_right.left(C.r,C.g,C.b,A,group);
var C = shade(R,G,B,20,"-");
Mid_right.back(C.r,C.g,C.b,A,group);
Mid_right.right(R,G,B,A,group);
Mid_right.bottom(R,G,B,A,group);
Mid_right.shelf(R,G,B,A,group);
}, ....
}
and
var Mid_right={
left:function(R,G,B,A,group){
frame([89,192,120,192,120,309,89,315],150,150,150,A,group);
frame([75,311,89,315,89,192,75,192],R,G,B,A,group)
},
right:function(R,G,B,A,group){
frame([99,193.5,99,306,118.5,309,118.5,193.5],R,G,B,A,group)
},
back:function(R,G,B,A,group){
frame([90.5,308,99,306,99,193.5,90.5,193.5],R,G,B,A,group);
},
shelf:function(R,G,B,A,group){
frame([90.5,270,118.5,266,99,264,90.5,265],R,G,B,A,group)
},
bottom:function(R,G,B,A,group){
frame([120,309,99,306,90.5,308,90.5,315],R,G,B,A,group)
}
};
and
function frame(array,R,G,B,A,group){
poly = new Kinetic.Polygon({
points: array,
stroke: 'white',
strokeWidth: 1,
name: group
});
if(R!=null||G!=null||B!=null){
poly.setFill('rgba('+R+','+G+','+B+','+A+')');
} else {
poly.setFill('rgba(0,0,0,0)');
};
layer.add(poly);
};
maybe it is kind of stupid and I could do it much easier, but there are other things I have to think about, which are not included here and I thought this should be a good way.
so what I want is to delete a set of polygons then redraw them with different colour, when the mouse hovers them and when it leaves, it should change back to original. but using destroy, redraw, and then collecting them again does not seem to work, dont know why. any ideas?
Instead of removing/recreating the poly, just use myPoly.setFill inside the mouseover and mouseleave events:
Add 2 additional properties to your poly: hoverColor and blurColor,
On mouseover: this.setFill(this.hoverColor);
On mouseleave: this.setFill(this.blurColor);
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/GTe9j/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
newPoly("red","green",[50,50, 100,50, 50,100]);
newPoly("blue","green",[100,50, 150,50, 150,100]);
newPoly("orange","green",[150,100, 150,150, 100,150]);
newPoly("purple","green",[100,150, 50,150, 50,100]);
function newPoly(hovercolor,blurcolor,array){
var poly = new Kinetic.Polygon({
points: array,
stroke: 'gray',
strokeWidth: 1,
fill:blurcolor
});
poly.hoverColor=hovercolor;
poly.blurColor=blurcolor;
poly.on("mouseover",function(){
this.setFill(this.hoverColor);
this.draw();
});
poly.on("mouseleave",function(){
this.setFill(this.blurColor);
this.draw();
});
layer.add(poly);
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Hover over a triangle to change its hover-color</h4>
<div id="container"></div>
</body>
</html>

How to take screenshot of a div with JavaScript?

I am building something called the "HTML Quiz". It's completely ran on JavaScript and it's pretty cool.
At the end, a results box pops up that says "Your Results:" and it shows how much time they took, what percentage they got, and how many questions they got right out of 10. I would like to have a button that says "Capture results" and have it somehow take a screenshot or something of the div, and then just show the image captured on the page where they can right click and "Save image as."
I really would love to do this so they can share their results with others. I don't want them to "copy" the results because they can easily change that. If they change what it says in the image, oh well.
Does anyone know a way to do this or something similar?
No, I don't know of a way to 'screenshot' an element, but what you could do, is draw the quiz results into a canvas element, then use the HTMLCanvasElement object's toDataURL function to get a data: URI with the image's contents.
When the quiz is finished, do this:
var c = document.getElementById('the_canvas_element_id');
var t = c.getContext('2d');
/* then use the canvas 2D drawing functions to add text, etc. for the result */
When the user clicks "Capture", do this:
window.open('', document.getElementById('the_canvas_element_id').toDataURL());
This will open a new tab or window with the 'screenshot', allowing the user to save it. There is no way to invoke a 'save as' dialog of sorts, so this is the best you can do in my opinion.
This is an expansion of #Dathan's answer, using html2canvas and FileSaver.js.
$(function() {
$("#btnSave").click(function() {
html2canvas($("#widget"), {
onrendered: function(canvas) {
theCanvas = canvas;
canvas.toBlob(function(blob) {
saveAs(blob, "Dashboard.png");
});
}
});
});
});
This code block waits for the button with the id btnSave to be clicked. When it is, it converts the widget div to a canvas element and then uses the saveAs() FileSaver interface (via FileSaver.js in browsers that don't support it natively) to save the div as an image named "Dashboard.png".
An example of this working is available at this fiddle.
After hours of research, I finally found a solution to take a screenshot of an element, even if the origin-clean FLAG is set (to prevent XSS), that´s why you can even capture for example Google Maps (in my case). I wrote a universal function to get a screenshot. The only thing you need in addition is the html2canvas library (https://html2canvas.hertzen.com/).
Example:
getScreenshotOfElement($("div#toBeCaptured").get(0), 0, 0, 100, 100, function(data) {
// in the data variable there is the base64 image
// exmaple for displaying the image in an <img>
$("img#captured").attr("src", "data:image/png;base64,"+data);
});
Keep in mind console.log() and alert() won´t generate output if the size of the image is great.
Function:
function getScreenshotOfElement(element, posX, posY, width, height, callback) {
html2canvas(element, {
onrendered: function (canvas) {
var context = canvas.getContext('2d');
var imageData = context.getImageData(posX, posY, width, height).data;
var outputCanvas = document.createElement('canvas');
var outputContext = outputCanvas.getContext('2d');
outputCanvas.width = width;
outputCanvas.height = height;
var idata = outputContext.createImageData(width, height);
idata.data.set(imageData);
outputContext.putImageData(idata, 0, 0);
callback(outputCanvas.toDataURL().replace("data:image/png;base64,", ""));
},
width: width,
height: height,
useCORS: true,
taintTest: false,
allowTaint: false
});
}
If you wish to have "Save as" dialog, just pass image into php script, which adds appropriate headers
Example "all-in-one" script script.php
<?php if(isset($_GET['image'])):
$image = $_GET['image'];
if(preg_match('#^data:image/(.*);base64,(.*)$#s', $image, $match)){
$base64 = $match[2];
$imageBody = base64_decode($base64);
$imageFormat = $match[1];
header('Content-type: application/octet-stream');
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Disposition: attachment; filename=\"file.".$imageFormat."\";" ); //png is default for toDataURL
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".strlen($imageBody));
echo $imageBody;
}
exit();
endif;?>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver=1.7.2'></script>
<canvas id="canvas" width="300" height="150"></canvas>
<button id="btn">Save</button>
<script>
$(document).ready(function(){
var canvas = document.getElementById('canvas');
var oCtx = canvas.getContext("2d");
oCtx.beginPath();
oCtx.moveTo(0,0);
oCtx.lineTo(300,150);
oCtx.stroke();
$('#btn').on('click', function(){
// opens dialog but location doesnt change due to SaveAs Dialog
document.location.href = '/script.php?image=' + canvas.toDataURL();
});
});
</script>
Add this Script in your index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
Use this function to get screenshot of div tag
getScreenShot(){
let c = this.elem.nativeElement.querySelector('.chartContainer'); // or document.getElementById('canvas');
html2canvas(c).then((canvas:any)=>{
var t = canvas.toDataURL().replace("data:image/png;base64,", "");
this.downloadBase64File('image/png',t,'image');
})
}
downloadBase64File(contentType:any, base64Data:any, fileName:any) {
const linkSource = `data:${contentType};base64,${base64Data}`;
const downloadLink = document.createElement("a");
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
}
You can't take a screen-shot: it would be an irresponsible security risk to let you do so. However, you can:
Do things server-side and generate an image
Draw something similar to a Canvas and render that to an image (in a browser that supports it)
Use some other drawing library to draw directly to the image (slow, but would work on any browser)
var shot1=imagify($('#widget')[0], (base64) => {
$('img.screenshot').attr('src', base64);
});
Take a look at htmlshot package , then, check deeply the client side section:
npm install htmlshot
<script src="/assets/backend/js/html2canvas.min.js"></script>
<script>
$("#download").on('click', function(){
html2canvas($("#printform"), {
onrendered: function (canvas) {
var url = canvas.toDataURL();
var triggerDownload = $("<a>").attr("href", url).attr("download", getNowFormatDate()+"电子签名详细信息.jpeg").appendTo("body");
triggerDownload[0].click();
triggerDownload.remove();
}
});
})
</script>
quotation
It's to simple you can use this code for capture the screenshot of particular area
you have to define the div id in html2canvas. I'm using here 2 div-:
div id="car"
div id ="chartContainer"
if you want to capture only cars then use car i'm capture here car only you can change chartContainer for capture the graph
html2canvas($('#car')
copy and paste this code
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Simple Line Chart"
},
axisY:{
includeZero: false
},
data: [{
type: "line",
dataPoints: [
{ y: 450 },
{ y: 414},
{ y: 520, indexLabel: "highest",markerColor: "red", markerType: "triangle" },
{ y: 460 },
{ y: 450 },
{ y: 500 },
{ y: 480 },
{ y: 480 },
{ y: 410 , indexLabel: "lowest",markerColor: "DarkSlateGrey", markerType: "cross" },
{ y: 500 },
{ y: 480 },
{ y: 510 }
]
}]
});
chart.render();
}
</script>
</head>
<body bgcolor="black">
<div id="wholebody">
<button style="background:aqua; cursor:pointer">Get Screenshot of Cars onl </button>
<div id="car" align="center">
<i class="fa fa-car" style="font-size:70px;color:red;"></i>
<i class="fa fa-car" style="font-size:60px;color:red;"></i>
<i class="fa fa-car" style="font-size:50px;color:red;"></i>
<i class="fa fa-car" style="font-size:20px;color:red;"></i>
<i class="fa fa-car" style="font-size:50px;color:red;"></i>
<i class="fa fa-car" style="font-size:60px;color:red;"></i>
<i class="fa fa-car" style="font-size:70px;color:red;"></i>
</div>
<br>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="box1">
</div>
</div>>
</body>
<script>
function genScreenshotgraph()
{
html2canvas($('#car'), {
onrendered: function(canvas) {
var imgData = canvas.toDataURL("image/jpeg");
var pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0, -180, -180);
pdf.save("download.pdf");
}
});
}
</script>
</html>
As far as I know you can't do that, I may be wrong. However I'd do this with php, generate a JPEG using php standard functions and then display the image, should not be a very hard job, however depends on how flashy the contents of the DIV are
Add to your html file and id="capture" to the div you want to take screenshot
<a id="btn-Convert-Html2Image" href="#">Download</a>
<script src="capture.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js" type="text/javascript"></script>
In capture.js add:
document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
html2canvas(document.getElementById("capture")).then(function (canvas) {
var anchorTag = document.createElement("a");
anchorTag.download = "filename.jpg";
anchorTag.href = canvas.toDataURL();
anchorTag.target = '_blank';
anchorTag.click();
});
});
Then, just press download and it will download the screenshot
Or you can view screenshot img by add
<div id="previewImg"></div>
in html code is where you want to view that img and js code will be
document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
html2canvas(document.getElementById("capture")).then(function (canvas) {
var anchorTag = document.createElement("a");
document.body.appendChild(anchorTag);
document.getElementById("previewImg").appendChild(canvas);
anchorTag.click();
});
});
This is an ~11 year old answer. Please ignore this answer and check other recent answers here
As far as I know its not possible with javascript.
What you can do for every result create a screenshot, save it somewhere and point the user when clicked on save result. (I guess no of result is only 10 so not a big deal to create 10 jpeg image of results)

Categories

Resources