I tried this logic but it didn't work:
var canvas = document.getElementById("canvas");
document.body.appendChild(rasterizeHTML.drawHTML(document.body.innerHTML, canvas, {height:'1000px'}));
Options is an object and I tried to pass in it the width and height, but it is not working.
The script that I'm using for this library is from cloud flare:
<script src="https://cdnjs.cloudflare.com/ajax/libs/rasterizehtml/1.2.2/rasterizeHTML.allinone.js"></script>
I did it some how but I don't understand why the canvas is not displaying correctly.
const context = canvas.getContext('2d');
canvas.style.width = "100%";
canvas.style.height = "600px";
html = document.querySelector('#main').innerHTML;
document.body.appendChild(
rasterizeHTML.drawHTML(html).then(function (renderResult) {
context.scale(window.devicePixelRatio, window.devicePixelRatio);
context.drawImage(renderResult.image, 0, 0, 1600, 800);
})
);
I tried to put the content of the entire web page in canvas(below under the box with the green border) but it looks like this:
Related
Suppose I have an image and a div whose position is absolute and is above that image (z-index of div more than z-index of image).Something like this :
I want to take screenshot of what is visible through the div using JavaScript. At first I thought of changing the div to a canvas and then I wrote this code:
<div class="utility-btn">
<button class="enquiry-btn" onclick="openEnquiry()">?</button>
</div>
<div id="enquiry">
<button id="close" onclick="closeEnquiry()">X</button>
<div class="cover">
<canvas id="capture"></canvas>
<button class="btn" onclick="takeScreenshot()">
Click to enquiry
</button>
</div>
</div>
Function to take screenshot:
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
backCtx.drawImage(canvas, 0, 0);
ctx.drawImage(backCanvas, 0, 0);
var dataURL = backCanvas.toDataURL();
console.log(dataURL);
}
But the image of dataURL was not what I expected it was just a blank image:
How can I implement this feature. How can I do it without using any external library?
There are two problems:
#1
If we look at your bit of code responsible for actually taking the screenshot
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
backCtx.drawImage(canvas, 0, 0);
ctx.drawImage(backCanvas, 0, 0);
var dataURL = backCanvas.toDataURL();
console.log(dataURL);
}
we can see that canvas is the element you want to have the screenshot taken onto. Later on you're creating an empty new canvas backCanvas and make it the size of the first canvas. Afterwards you're drawing the empty first canvas on the second and finally the empty second canvas back to the first.
So that does not make too much sense.
Instead you need to take the actual canvas generated by threeJS. These lines of your code append a <canvas> element to the container <div>, threeJS is using:
const container = document.getElementById('container');
container.appendChild(renderer.domElement);
We can reference it using:
document.getElementById("container").children[0]
#2
As threeJS uses WebGL to draw stuff, it's rendering context is not the regular and for performance reasons the browser is clearing the drawing buffer after something has been drawn onto - so your screenshot would come up empty all the time. There is an option you need to pass to the THREE.WebGLRenderer constructor to keep the drawingbuffer called preserveDrawingBuffer.
So change this line:
renderer = new THREE.WebGLRenderer();
to this
renderer = new THREE.WebGLRenderer({preserveDrawingBuffer: true});
and your screenshot function to this:
function takeScreenshot() {
var canvas = document.getElementById('capture');
ctx = canvas.getContext('2d');
ctx.drawImage(document.getElementById("container").children[0], 0, 0);
var dataURL = canvas.toDataURL();
console.log(dataURL);
}
I'm trying to print a canvas in a PDF file that I'm creating. The issue is that I always get a black rectangle in my PDF instead of the graph that I can see on my web page.
I generate the canvas like this:
<div class="col-md-6 featurePanel" style="display: none;">
<div id="canvasContainer_#featureID"></div>
</div>
It's filled by JS:
function SetFeatureValues(measID, measIndex, measCount, featureID, canvasID, name, humL, humR, femL, femR, thor, lumb, reference, type, color, ResTable) {
if (ResTable.length == measCount) {
var element = document.createElement("canvas");
element.id = canvasID;
element.classList.add("ThreeDDogGraph");
document.getElementById('canvasContainer_' + featureID).appendChild(element);
_3ddogvis.scene(0.0, true, ResTable, canvasID);
}
}
Then I export it to a PDF file:
function RenderFeature(pdf, currentTopPosition, currentLeftPasition, canvas) {
var newCanvas = document.createElement('canvas');
let context = newCanvas.getContext('2d');
newCanvas.width = width;
newCanvas.height = height;
context.drawImage(document.querySelector('#' + canvas.id), 0, 0, width, height);
var newCanvasImg = newCanvas.toDataURL("image/png");
pdf.addImage(newCanvasImg, 'png', currentLeftPasition, currentTopPosition, graphWidth, graphHeight, undefined, 'FAST');
}
After downloading the file I get a black rectangle in my PDF with the dimensions of my canvas.
EDIT:
If I try to copy the canvas (as propose obscure) I also get a black picture and the error message:
Unable to clone WebGL context as it has preserveDrawingBuffer=false
As I use a library done by someone else, I cannot set the preserveDrawingBuffer to true.
Is there a solution to get a picture from a canvas with preserveDrawingBuffer set to false?
I have a function that draw a CANVAS line and make its get the same coordinates of a <div> by using offsetLeft. The line searchs the same position of the <div> making its get glued on the <div> It is working good BUT ONLY when the page loads and the browser refreshs.
drawCanvas() {
const c = document.getElementById("canvas");
const lineH = c.getContext("2d");
c.width = window.innerWidth;
c.height = window.innerHeight;
const lineV = c.getContext("2d");
const positionCanvas = () => {
lineV.clearRect(0, 0, c.width, c.height);
const divPosition = document.querySelector('.myDiv').offsetLeft
lineV.fillStyle = "grey";
lineV.fillRect(divPosition , 0, 2, window.innerHeight);
lineV.fill();
}
positionCanvas()
window.onresize = () => {
lineV.height = window.innerHeight;
positionCanvas()
}
I would like to make it work good everytime even and especially when I'm handling the resizing of the window. How can I solve it?
Example:
The page is loaded:
OK!!! The canvas line is glued on <div>
While the user is manually resizing the window's browser:
NOT WORKING!!! The canvas search the <div> but not get glued on its,
there is a distance between both.
After the stop of the browser resizing:
NOT WORKING!!! the lline still separated from the <div>
Refresh the browser in a new position:
OK!!! canvas line is glued on <div>
I found the solution.
Just put the function drawCanvas() into the window.onresize rather the positionCanvas().
Just like that:
window.onresize = () => {
drawCanvas()
}
i'm working with an hybrid Android app and I need to take a picture from camera, process the image and then show the results obtained on another window that should contain a small preview of the picture taken and some text with the results.
Here is the relevant code that is not currently working as I need:
From script of first window:
.
.
.
CameraPreview.takePicture(function(imgData){
var mImage = new Image();
mImage.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = mImage.width;
canvas.height = mImage.height;
var context = canvas.getContext('2d');
context.drawImage(mImage, 0, 0);
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
.
.(Process imgData[])
.
localStorage.setItem("resultImage", mImage.src);
window.open('result.html','_blank','location=no');
};
mImage.src = 'data:image/jpeg;base64,'+imgData;
});
Then, "result.html" pops up, which has the following html content:
...
<body>
...
<canvas id="resultCanvas" style="position: absolute; top: 0%; left: 0%;"></canvas>
...
</body>
...
And the following javascript code:
...
var mImage = new Image();
mImage.onload = function(){
var canvas = document.getElementById('resultCanvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight*0.3; // 1/3 of phone screen size
var context = canvas.getContext('2d');
context.drawImage(mImage);
navigator.notification.alert('Height = '+mImage.height+'\n'+'Width ='+mImage.width, function(){},'Image','Done');
};
mImage.src = localStorage.getItem("resultImage");
...
The alert window shows the 640x480 of the image, but the canvas is transparent where it should contain the picture taken.
If I replace the "context.drawImage()" statement with "context.fillrect()" I can see the black rectangle drawn on screen, so it looks that the canvas is there, but somehow I can not make it draw the desired image.
Hope I explained myself correctly.
I really appreciate any help. Thanks!
Well, finally I solved it, first I tryied using an "img" element instead of a canvas, and that works fine, but the problem is I need to make some drawings over the picture, so insisting on code I posted before, I realized the problem was on the use of drawImage() method in the second script, it is necessary to specify position, so replacing:
context.drawImage(mImage);
with
context.drawImage(mImage,0,0);
solved everything.
I am working on an ebook application, I draw each page on canvas using PDF.js , the problem is , when I click on the button and turn to other page, I tried simply render on the same canvas again , but the canvas seems move to a wrong location or wrong size .
function renderPage(url) {
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
//clearCanvasGrid('canvas');
PDFJS.getDocument(url).then(function (pdf) {
// Using promise to fetch the page
pdf.getPage(1).then(function(page) {
var viewport = page.getViewport(5); //scale 5
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext).then(function() {
initialZoomPage(viewport.height,viewport.width);
});
});
});
}
So, are there any necessary step I need to do before redraw the page? Also , how can I destroy it if I would like to close the page? Thanks
Update:
function clearCanvasGrid(canvasID){
canvas = document.getElementById(canvasID); //because we are looping //each location has its own canvas ID
context = canvas.getContext('2d');
//context.beginPath();
// Store the current transformation matrix
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
context.restore(); //CLEARS THE SPECIFIC CANVAS COMPLETELY FOR NEW DRAWING
}
I found a function to clear the canvas but it has .save , .setTransform and .restore besides clearRect, are they necessary? thanks
One way is to clear out the canvas using context.clearRect(0,0, width, height) (Reference).
Alternatively, you can append a new canvas element (and possibly remove the old one, depending on whether you will want to display it again) each time you want a new page. Something like this should do it:
var oldcanv = document.getElementById('canvas');
document.removeChild(oldcanv)
var canv = document.createElement('canvas');
canv.id = 'canvas';
document.body.appendChild(canv);
Just note that if you plan to keep more than one, each one must have a unique id instead of just id="canvas" (perhaps based on the page number - something like canvas-1).
Answer to updated question:
The save, setTransform, and restore are only necessary if you are doing (or somehow allowing users to do) transformation. I don't know if the PDF.js library does any transformation behind the scenes, so it may be best to leave it there.
try using clearRect(), like:
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
In Lightning Aura components, a different approach is required:
The chart object, once created, is stored in an attribute.
<aura:attribute name="chartObject" type="Object"/>
<canvas id="chartId" aura:id="chartCanvas" </canvas>
let theChart = component.get("v.chartObject");
if (theChart != undefined) {
//alternative
//let chartStatus = Chart.getChart("chartId");
//if (chartStatus != undefined) {
//update data if necessary
//theChart.data.datasets[0].data[i] = etc
theChart.update();
}
else{
var ctx = component.find("chartCanvas").getElement();
var chart = new Chart(ctx, {
type: 'line',
data: myData,
options: {
tension: 0.25,
responsive: false,
maintainAspectRatio :false,
fill: true,
}
});
component.set("v.chartObject", chart);
}//endif chart exists