I have trouble in this code (I am working from my local PC).
Thks for your help.
My code is below:
<html>
<head>
<title>My Test</title>
<script src="../jquery/js/jquery-1.9.0.min.js"></script>
</head>
<body>
<script>
var _canvas = document.createElement('canvas');
_canvas.width="100";
_canvas.height="100";
var _context = _canvas.getContext("2d");
var _img = new Image();
_img.src = "image/myImgTest.png";
var _url;
_img.onload = function() {
DrawScreen(); // just some process: drawing image
_url = _canvas.toDataURL();
alert("test"); **// this alert is printed on FF not on Chrome ???**
// window.location = url; **// With this command on FF, I show my Image**
document.write("<img src='"+url+"' >"); **// on FF, I show my image but when I would like to see the source code on my current page, there is nothing just blank ?? And on Chrome, I never show my image.**
**// In fact, I am expected to generate something like this: <img src="data:image/png;base64,iVBORw0KGgo....."> at this place **
};
function DrawScreen() {
// my process
}
</script>
</body>
</html>
*// In fact, I am expected to generate something like this: at this place *
As you are "working on your local PC" ... do you have a webserver on your local PC or do you just open the HTML file directly from your hard drive?
You might want to move the assignment of .src to after the .onload event handler, because otherwise it might be possible that .onload never gets triggered.
var _img = new Image();
var _url;
_img.onload = function() {
...
};
_img.src = "image/myImgTest.png";
Related
In a blazor wasm, I want to create a pdf and make it downloadable. I tested pdfflow, but was only able to make it run in a console application. There are several commercial solutions (devexpress, syncfusion), but they are really expensive.
Next, I stepped over the blog post Generate PDF files using an html template and Playwright, that seemed much promising to me. Unfortunately, it does not contain a complete example and I cannot make it run. Here is, what I tried:
I added template.html to wwwroot folder.
template.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="invoice.css">
</head>
<body style="padding: 3rem">
<h1>Invoice</h1>
Awesome company<br />
</body>
</html>
I added a button, that invokes CreatePdf(). I copied the code from the link above and modified it according to my needs (and because e. g. there is no method LoadOrder(orderId) provided).
Index.razor
#page "/"
#using Scriban
#using System.IO
#using Microsoft.Playwright
#inject HttpClient Http
<button class="btn btn-primary" #onclick="CreatePdf">pdf</button>
#code{
private async Task CreatePdf()
{
//var templateContent = File.ReadAllText("template.html");
var templateContent = await Http.GetStringAsync("template.html");
var template = Template.Parse(templateContent);
//var templateData = new { Invoice = LoadOrder(orderId) };
//var pageContent = template.Render(templateData);
var pageContent = "testString";
//var dataUrl = "data:text/html;base64," + Convert.ToBase64String(Encoding.UTF8.GetBytes(pageContent));
var dataUrl = "data:text/html;base64," + pageContent;
I added the following two lines, because "browser" was not declared (Source from playwright).
// Here, the app crashes.
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Webkit.LaunchAsync();
await using var context = await browser.NewContextAsync();
var page = await context.NewPageAsync();
await page.GotoAsync(dataUrl, new PageGotoOptions { WaitUntil = WaitUntilState.NetworkIdle });
var output = await page.PdfAsync(new PagePdfOptions
{
Format = "A4",
Landscape = false,
});
await File.WriteAllBytesAsync("output.pdf", output);
} }
How can i make above code run?
You cannot use Playwright from a browser (js / wasm). So, you have to use another solution. For instance, you can use jsPDF. This library is not perfect when converting html to pdf, but maybe it will be ok for your usage.
Add a few script references in index.html to use jsPDF (you can also install them using npm if you prefer)
<script src="_framework/blazor.webassembly.js"></script>
<!-- jsPDF references -->
<script src="https://unpkg.com/jspdf#latest/dist/jspdf.umd.min.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify#2.3.3/dist/purify.min.js"></script>
Create a file wwwroot/HtmlToPdf.js with the following content:
export function generateAndDownloadPdf(htmlOrElement, filename) {
const doc = new jspdf.jsPDF({
orientation: 'p',
unit: 'pt',
format: 'a4'
});
return new Promise((resolve, reject) => {
doc.html(htmlOrElement, {
callback: doc => {
doc.save(filename);
resolve();
}
});
});
}
export function generatePdf(htmlOrElement) {
const doc = new jspdf.jsPDF();
return new Promise((resolve, reject) => {
doc.html(htmlOrElement, {
callback: doc => {
const output = doc.output("arraybuffer");
resolve(new Uint8Array(output));
}
});
});
}
Then, you can use the script from a Razor component:
#inject IJSRuntime JSRuntime
<button type="button" #onclick="DownloadPdf">Generate</button>
#code {
async Task DownloadPdf()
{
await using var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./HtmlToPdf.js");
// Generate and download the PDF
await module.InvokeVoidAsync("generateAndDownloadPdf", "<h1>sample</h1>", "sample.pdf");
// Generate the PDF and get its content as byte[] (need .NET 6 to support Uint8Array)
var bytes = await module.InvokeAsync<byte[]>("generatePdf", "<h1>sample</h1>");
}
}
I am using below code to share link on google plus.
<html>
<head>
<script type="text/javascript">
window.onPlusStart = function(x) {
console.log('ops', x)
}
window.onPlusDone = function(x) {
console.log('opd', x)
}
</script>
</head>
<body>
<div class="g-plus" data-action="share" data-href="http://test.com"
data-onstartinteraction="onPlusStart"
data-onendinteraction="onPlusDone">
</div>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
ISSUE : Right now i am getting response four times in console log for onPlusDone at the time of successfully share(response 1 : before login window, response 2 : after close login window, response 3 : after close login window, response 4 : after share successfully).
But i need response only one after successfully share.
I'm trying PhoneGap/Cordova 2.1.0 in WP7 for the first time, so I'm new in this.
What I should do is capturing a picture through the camera and uploading it to a server.
This is my code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>PhoneGap WP7</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.1.0.js"></script>
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() { }
function capturePhoto()
{
// Take picture using device camera and retrieve image
navigator.camera.getPicture(
onPhotoDataSuccess,
onFail,
{
quality: 50,
destinationType: Camera.DestinationType.DATA_URL
}
);
}
function onPhotoDataSuccess(imageData)
{
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageData.substr(imageData.lastIndexOf('/') + 1);
options.mimeType="image/jpeg";
var params = new Object();
options.params = params;
var ft = new FileTransfer();
ft.upload(imageData, "http://mysite.com/upload.php", win, fail, options);
}
function onFail(message)
{
navigator.notification.alert('Failed because: ' + message);
}
var win = function(r)
{
navigator.notification.alert(r.responseCode + " - " + r.response + " - " + r.bytesSent);
}
var fail = function(error)
{
navigator.notification.alert(eval(error));
}
</script>
</head>
<body>
<h1>PhoneGap Photo Demo</h1>
<button onclick="capturePhoto();">Capture a Photo</button>
</body>
</html>
When I try this, the upload doesn't work and I get an empty error object:
{ "code":null, "source":null, "target":null, "http_status":null }
Some notes:
I followed this trick for missing whitelist in WP7.
The php code is not written by me, I would do it in asp.net, if someone could provide a working example with an asp.net webservice would be really appreciated.
Thanks.
EDIT
I debugged FileTransfer class and I get an error in JsonHelper class:
using (MemoryStream mem = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
result = deserializer.ReadObject(mem);
}
The error is: InvalidCastException
EDIT
Try replacing
uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions[]>(options)[0];
with the the following
options = JSON.JsonHelper.Deserialize<string[]>(options)[0];
uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(options);
ORIGINAL ANSWER
The easiest way to troubleshot such issues is to add reference to Cordova library source code instead of compiled WP7CordovaClassLib.dll
cordova-2.1.0-incubating-src\cordova-2.1.0\incubator-cordova-wp7\framework\WP7CordovaClassLib.csproj
http://www.apache.org/dist/incubator/cordova/
and then add breakpoint to standalone\cordovalib\Commands\FileTransfer.cs
/// <summary>
/// sends a file to a server
/// </summary>
/// <param name="options">Upload options</param>
public void upload(string options)
{
Debug.WriteLine("options = " + options);
options = options.Replace("{}", "null");
Sounds complex, but from my experience line by line debugging is the simplest way to understand what particular goes wrong with Apache Cordova in many situations.
I am using jQuery AJAX Form plugin to upload images without refreshing the page. It is ok if I show the uploaded image within an image tag( setting src to uploaded image path.) However, I cannot draw that uploaded image on a canvas element. I actually do not know what the problem is.
if (isset($_FILES["image"]["name"]) && !empty($_FILES["image"]["name"])) {
$filename = $_FILES["image"]["name"];
$tmpname = $_FILES["image"]["tmp_name"];
$location = "uploads/";
move_uploaded_file($tmpname, $location.$filename);
echo $location.$filename;
} else {}
var canvas = document.getElementById("canv");
var contex = canvas.getContext("2d");
var img = new Image();
img.src = responseText;
img.onload = function(){ contex.putImageData(img, 0, 0); }
Above is my callback function(inside) when I call when the Ajax process is done. Thanks for any helpful answer.
UPDATE: FULL CODE
<html>
<head>
<script src="jq171.js"></script> <!--jQuery-->
<script src="jqform.js"></script> <!--jQuery ajax Form plugin-->
<script>
$(document).ready(function(){
$("#myform").ajaxForm(function({success: updateSrc}){
});
});
function updateSrc(responseText){
var canvas = document.getElementById("canv");
var contex = canvas.getContext("2d");
var img = new Image();
img.src = responseText;
img.onload = function(){ contex.drawImage(img, 0, 0); }
}
</script>
</head>
<body>
<form id="myform" action="this.php" method="post" enctype="multipart/form-data" >
<canvas id="canv" width="400px" height="400px"></canvas>
<input type="file" name="image"/>
<input type="submit"/>
</form>
</body>
</html>
Is there a reason why you don't just do an automatic request for the image?
As in leave the updateSrc as
function updateSrc(imagePath){
var canvas = document.getElementById("canv");
var contex = canvas.getContext("2d");
var img = new Image();
img.src = imagePath;
img.onload = function(){ contex.drawImage(img, 0, 0); }
}
Where the imagePath is the path to the image file.
for example:
updateSrc("images/example_image.jpg");
So jquery ajax request doesn't even need to be written.
You are using wrong function.
context.putImageData(imgData,x,y);
it takes image data, which is not an image object but raw pixel data. Instead, you want to use :
context.drawImage(img,0,0);
It should solve your problem
I have problem with Firefox6 (don't know if it also concerns earlier versions).
I want to embed Google Map on page, and when page has scrollbars (is longer than viewport) mouse wheel not only zooms map but also scrolls page. I tried to catch mousewheel event and stop propagation but this event isn catchable when cursor os over map. When cursor is over map controls (zoom control, google logo, etc) i can catch event and stop propagation.
What is more strange it not happens always. Sometimes page srolls and after few scrolls it stops and mousewheel only zooms map (as expected). Sometimes page doesn't scroll and sometimes it scrolls with zoom all the time. Can't find pattern.
Source code is simple:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>test</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
window.onload = function(){
var latlng = new google.maps.LatLng(52.25, 21.01);
mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl:true,
mapTypeControl:false
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
}
</script>
</head>
<body>
<p style="height:500px;">-lot of text-</p>
<div id="map_canvas" style="width:500px; height:500px;"></div>
<p style="height:500px;">-lot of text-</p>
</body>
</html>
Your problem is also described on code.google.com, this problem is only in Firefox, but it isn't a Firefox bug:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=3652
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1605
Have also found out a workaround, that is not re-scrolling or re-zooming and works fine:
A new ScrollInterceptOverlay derived from google.maps.OverlayView, prepending a div on MapPanes.overlayMouseTarget:
Version with jQuery
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map($googlemap[0], mapOptions);
// Define a ScrollInterceptOverlay function
var ScrollInterceptOverlay = function (gmap) {
if (!(this instanceof ScrollInterceptOverlay)) return;
var $div;
var $mapDiv;
var initialize = function () {
$div = $('<div />').css({
position: 'absolute', top: 0, left: 0,
display: 'inline-block'
});
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
this.setMap(gmap);
};
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
this.onAdd = function () {
$div.prependTo(this.getPanes().overlayMouseTarget);
};
this.onRemove = function () {
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
$div.detach();
};
this.draw = function () {
if ($mapDiv && $mapDiv.length === 1) {
$div.css({
width: $mapDiv.outerWidth(),
height: $mapDiv.outerHeight()
});
}
};
var base_setMap = this.setMap;
this.setMap = function (map) {
$mapDiv = $(map.getDiv());
base_setMap.call(this, map);
};
initialize.call(this);
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay(gmap);
This workaround is using jQuery, required for calculating outerWidth and outerHeight, but also for better reading.
Version with pure javaScript
Tested live: http://fiddle.jshell.net/fhSMM/7/
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map(googlemap, mapOptions);
// Define a ScrollInterceptOverlay class function
var ScrollInterceptOverlay = function () {
if (!(this instanceof ScrollInterceptOverlay)) return;
var div;
// private instance function
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
// public instance function
this.onAdd = function () {
div = document.createElement('div');
div.style.display = 'inline-block';
div.style.position = 'absolute';
div.style.top = div.style.left = 0;
if (div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
var pane = this.getPanes().overlayMouseTarget;
var firstChild = pane.firstChild;
if (!firstChild) {
pane.appendChild(div);
}
else {
pane.insertBefore(div, firstChild);
}
};
// public instance function
this.onRemove = function () {
if (div) {
if (div.removeEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.removeEventListener("mousewheel", mouseScrollStop);
// Firefox
div.removeEventListener("DOMMouseScroll", mouseScrollStop);
div.removeEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.detachEvent) { // IE before version 9
div.detachEvent("onmousewheel", mouseScrollStop);
}
var parent = div.parentNode;
parent.removeChild(div);
}
// do not delete div var'iable
div = undefined;
};
// public instance function
this.draw = function () {
var map = this.getMap();
if (map) {
var mapDiv = map.getDiv();
if (mapDiv) {
var rect = mapDiv.getBoundingClientRect();
div.style.width = rect.width + 'px';
div.style.height = rect.height + 'px';
}
}
};
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay();
mapScrollInterceptor.setMap(gmap);
Please visit also http://metadea.de/V/ about what (real) javaScript class functions are, and why I like jQuery :)
Works now for me.
Also in Firefox, the map is zooming on mousescroll, but no more scrolling the document.
Edit: Updated support for MozMousePixelScroll, refined jS
For now it looks like firefox bug. Will close question when bug will be fixed.
I had the same issue.
You could try to start Firefox with a brand new profile (e.g. by starting the Profile Manager - executing 'firefox -P' on windows systems - and choosing 'Create...') and see if the problem persists.
I had several old but seemingly empty user profiles lying around in the VMs I used to verify if this was a bug in FF 6 and obviously installing only the new binaries didn't help. On the other hand, creating a blank profile did, so I can only think of this being a migration glitch. If major versions of FF are going to be released on a bi-monthly basis, though, a lot of people are going to suffer from similar issues.
Why not take UI control of zooming? This works well for me.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
</head>
<body>
<div class="canvas" style="width:600px;height:400px;"></div>
<script>
// Load event
$(function() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($('.canvas')[0], myOptions);
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
// Only a Mozilla bug
if($.browser.mozilla) {
// Wait for the map DOM to be ready
google.maps.event.addListenerOnce(map, 'idle', function() {
$('.canvas > div > div:first-child > div').bind('DOMMouseScroll', function(e) {
// setTimeout needed otherwise the return false has no effect
setTimeout(function() {
// Calculate new center
var offset = $('.canvas').offset();
var pos = overlay.getProjection().fromContainerPixelToLatLng(new google.maps.Point(e.pageX-offset.left, e.pageY-offset.top));
// Calculate new zoom level
var zoom = map.getZoom();
if(e.detail < 0) zoom++;
else if(e.detail > 0) zoom--;
map.setCenter(pos);
map.setZoom(zoom);
}, 1);
// Stop propagation (prevent default)
return false;
});
});
}
});
</script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>