I use PDF.JS to annotate PDFs on my website.
It works fine, but I have a problem with the "Text Layer" when the PDF contains pages in different orientations (portrait and landscape).
Here is a screenshot that shows the situation:
screenshot
Here is my code:
function renderPage(pageNumber, canvas, annotationLayer, textLayer) {
__PDF.getPage(pageNumber).then(function(page) {
viewport = page.getViewport({
scale: __SCALE
});
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: canvas.getContext('2d'),
viewport: viewport
};
// Render the page contents in the canvas
page.render(renderContext).promise.then(function() {
return page.getTextContent();
}).then(function(textContent) {
console.log(pageNumber, textContent);
var textLayer = new pdfjsLib.renderTextLayer({
container: $('.page-container-' + pageNumber + ' .text-layer').get(0),
pageIndex: page.pageIndex,
viewport: viewport,
textContent: textContent,
enhanceTextSelection: true,
});
// Clear HTML for text layer and show
$('.page-container-' + pageNumber + ' .text-layer').html('').show();
// Assign the CSS created to the text-layer element
$('.page-container-' + pageNumber + ' .text-layer').css({
height: canvas.height + 'px',
width: canvas.width + 'px'
});
})
});
}
PDF with only landscape or only portrait pages work fine...
Thanks for your help!
Related
How to convert html element into pdf and set it at the center of the page.
It is coming at the left top corner of the pdf page
Its not the exact solution but i think it will work . so it will create the pdf page with exact height and width of the html div
const invoiceSection = $("#customer_invoice_bill");
let invoiceName = invoiceSection.data("invoiceName");
var pdfConf = {
pagesplit: true,
background: "#fff",
};
var pdf = new jsPDF("p", "pt", [
invoiceSection.height() + 100,
invoiceSection.width(),
]);
pdf.addHTML(invoiceSection, pdfConf, function () {
pdf.save(`${invoiceName}.pdf`);
});
adding height and width of html div to the jsPDF() parameter works
new jsPDF("p", "pt", [
invoiceSection.height() + 100, ------ > ** adding html div height **
invoiceSection.width(), -------- > ** adding html div width **
]);
I have a chart with some indicators below it. Each indicator area consists
of a svg renderer button. so when I use resize property to drag and resize
the panes, the series resized perfectly but the button remains in its same
position, Can we move the button with the resizer?
Here I created a sample link to regenerate
https://jsfiddle.net/q0ybpnvx/2/
Any help will be appreciated. I am having great trouble. Thank you
You can add and position the custom button in render event:
chart: {
events: {
render: function() {
var chart = this;
if (chart.customBtn) {
chart.customBtn.attr({
y: chart.yAxis[1].top,
});
} else {
chart.customBtn = chart.renderer.button(
'sometext',
5,
chart.yAxis[1].top,
function() {
console.log('some task')
}).add()
}
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/b7vq4ecy/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I was able to do something by manually changing the x/y attributes of my svgRenderer label, the same should apply to buttons.
I'm in angular and have a listener for screen resizing:
Also Note that you can change the entire SVGRenderer label with the attr.text property.
this.chart = Highcharts.chart(.....);
// I used a helper method to create the label
this.chart.myLabel = this.labelCreationHelperMethod(this.chart, data);
this.windowEventService.resize$.subscribe(dimensions => {
if(dimensions.x < 500) { //this would be your charts resize breakpoint
// here I was using a specific chart series property to tell where to put my x coordinate,
// you can traverse through the chart object to find a similar number,
// or just use a hardcoded number
this.chart.myLabel.attr({ y: 15, x: this.chart.series[0].points[0].plotX + 20 });
} else {
this.chart.myLabel.attr({ y: 100, x: this.chart.series[0].points[0].plotX + 50 });
}
}
//Returns the label object that we keep a reference to in the chart object.
labelCreationHelperMethod() {
const y = screen.width > 500 ? 100 : 15;
const x = screen.width > 500 ? this.chart.series[0].points[0].plotX + 50 :
this.chart.series[0].points[0].plotX + 20
// your label
const label = `<div style="color: blue"...> My Label Stuff</div>`
return chart.renderer.label(label, x, y, 'callout', offset + chart.plotLeft, chart.plotTop + 80, true)
.attr({
fill: '#e8e8e8',
padding: 15,
r: 5,
zIndex: 6
})
.add();
}
I'm trying to figure out how to enable visitors to drag to rotate a 3D div using .draggable(). Currently the div rotates but also moves vertically and horizontally making the process touchy and unpredictable. I would like the origin of the div to stay fixed, and the "dragging" to only affect the rotation, so users can "spin" the div around to see the other sides.
here is link to the codepen: http://codepen.io/armandhammer8/pen/IiBga
$('.anime').draggable({
drag: function(event, ui){
var rotateCSS = 'rotate(' + ui.position.left + 'deg)';
$(this).css({
'transform': rotateCSS,
'-moz-transform': rotateCSS,
'-webkit-transform': rotateCSS
});
Thanks in advance!
The div element is a little house:
I want to be able to spin it around
The built in functionality of draggable is giving you the problems.
It's not so hard to get the functionality by yourself and stop using draggable.
Javascript:
var offset = 0, startX;
var elem = document.getElementById("element");
$('.draggable').on('mousedown', function (e) {
startX = e.pageX - offset;
})
.on('mouseup', function() {
startX = null;
})
.on('mousemove', function (e) {
if(startX) {
offset = e.pageX - startX;
elem.style['-webkit-transform'] = 'rotateY(' + offset + 'deg)';
}
});
demo
I'm working on Titanium SDK 3.1.1 and deploying for iOS. What I'm trying to do is to open the camera with an overlay, take a picture, crop the picture and save it. But I'm having trouble to take a picture with an overlay.
If I take a picture in portrait, the image returned is taken in landscape. When taking it in landscape, the result will be a portrait image. No idea why is this happening.
My overlay is really simple, it has three views that act as buttons, one of them closes the camera, another takes the picture and the other opens the gallery (which throws an exception, but that's a problem for a different question):
var testOverlay = Ti.UI.createView({
bottom:0,
height:200,
width: platformWidth,
height : platformHeight,
left:0
});
//just a black view on top to limit upper area
var topbarView = Ti.UI.createView({
width: platformWidth,
height : resultHeight,
top : 0,
left : 0,
backgroundColor : '#363636',
opcatity : 0.6
});
testOverlay.add(topbarView);
// just a black view on bottom to limit bottom area and display custom controls
var bottombarView = Ti.UI.createView({
width: platformWidth,
height : resultHeight,
bottom : 0,
left : 0,
backgroundColor : '#363636',
opcatity : 0.6
});
testOverlay.add(bottombarView);
// container view for custom controls
var cameraButtonHolder = Ti.UI.createView({
width : Ti.UI.FILL,
height : 80 + dpi,
bottom : 0
});
bottombarView.add(cameraButtonHolder);
//a view to close camera
var cancelCameraButton = Ti.UI.createView({
width:80 + dpi,
height:80 + dpi,
left:0,
backgroundColor:"pink"
});
// a view to take picture
var takePictureButton = Ti.UI.createView({
width : 80 + dpi,
height : 80 + dpi,
backgroundColor : 'blue'
});
//a view to open gallery
var galleryButton = Ti.UI.createView({
width:80 + dpi,
height:80 + dpi,
right:0,
backgroundColor:"green"
});
cameraButtonHolder.add(cancelCameraButton);
cameraButtonHolder.add(takePictureButton);
cameraButtonHolder.add(galleryButton);
// event handler to close camera
cancelCameraButton.addEventListener('click', function(e){
Ti.Media.hideCamera();
parentWindow.closeView();
});
//event handler to take picture
takePictureButton.addEventListener('click', function(e){
Ti.Media.takePicture();
});
// event handler to open gallery
galleryButton.addEventListener("click", function(e){
Titanium.Media.openPhotoGallery({
success : function(event) {
Ti.API.info('Returning from gallery');
var filename = 'baby_temp.png';
var tmp = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, (filename));
tmp.write(event.media);
var blob = tmp.read();
Ti.App.fireEvent(callback, {
media_type : 'photos'
});
},
cancel : function() {
Ti.API.info('Cancelled');
},
error : function(error) {
// if error, show message
var message = 'Unexpected error: ' + JSON.stringify(error);
Ti.UI.createAlertDialog({
title : 'Camera',
message : message
}).show();
},
mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO]
});
});
My function that opens the camera and handles the photo looks like this:
function showCamera() {
Ti.Media.showCamera({
success : function(event)
{
var tmp;
var mediaType;
if (event.mediaType.indexOf('PHOTO') > -1 || event.mediaType.indexOf('image') > -1)
{
tmp = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, ('baby_temp.png'));
mediaType = 'photos';
}
else
{
tmp = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, ('baby_temp.mp4'));
mediaType = 'videos'
}
Ti.App.Properties.setString('mediaType', mediaType);
if (mediaType == "photos")
{
//If it's a picture then crop it and save it
var image = event.media;
var imageWidth = image.width;
var imageHeight = image.height;
var scaleX = 0;
var scaleY = (imageHeight - imageWidth) / 2;
if(imageHeight > imageWidth)
{
scaleX = (imageWidth - imageHeight) / 2;
scaleY = 0;
}
var croppedImage = image.imageAsCropped({
x : scaleX,
y : scaleY,
width : imageWidth,
height : imageWidth
});
tmp.write(croppedImage);
}
else
{
// video
tmp.write(event.media);
}
Ti.App.fireEvent('changeCreateMoment', {
media_type : mediaType
});
Ti.Media.hideCamera();
},
cancel : function() {
// hide camera and close the window
Ti.Media.hideCamera();
parentWindow.closeView();
},
error : function(error) {
// if error, show message, hide camera and close window
var message;
if (error.code == Ti.Media.NO_CAMERA)
{
message = 'Device does not have camera capabilities';
}
else
{
message = 'Unexpected error: ' + error.code;
}
Ti.UI.createAlertDialog({
title : 'moments',
message : message
}).show();
Ti.Media.hideCamera();
parentWindow.closeView();
},
overlay:testOverlay,
mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO, Ti.Media.MEDIA_TYPE_VIDEO],
videoMaximumDuration : 10000,
videoQuality : Titanium.Media.QUALITY_MEDIUM,
saveToPhotoGallery : false,
showControls : false,
autohide : false
});
}
I have no idea why the photo is taken in landscape instead of portrait and vice versa. Am I missing a property in my showCamera function call? Why am I getting a photo like this?
How to do a reversed resize with jquery UI? (Enlarge instead of minimize and vice versa) (needs to be to done after rotation done be the user - it could be any degrees) because no consideration is take into account when rotating divs
newItem is a div.
newItem.resizable({
handles: {
'nw': '.nwgrip',
'ne': '.negrip',
'sw': '.swgrip',
'se': '.segrip'
},
aspectRatio: true,
resize: function( event, ui ) {
//Original size
var origWidth = ui.size.width;
var origHeight = ui.size.height;
//Fumbling in the dark... ...How do I do "reversed" resize?
//Tried this:
ui.helper.css("width", (origWidth - ui.helper.css("width") *-2) + "px");
ui.helper.css("height", (origHeight - ui.helper.css("height") *-2) + "px");
}
});