jssor size adjustor without maintaining aspect ratio - jssor

Since one of our organization's client asked us to change the slide show height slightly not width (reason on maintaining aspect ratio in small screen device the slider gets very small).
I know about this jssor function $ScaleWidth(width); but only have to adjust height.
So created the following function to resize based on the scale value of transform css property of jssor instantiated object's tag id, which is passed as parameter for the following function.
function jssorResolutionAdjustor(id)
{
setTimeout(function() {
var idObj = $('#' + id);
var immediateChild = idObj.children('div');
var transformMatrix = '';
var transformMatrixValues = '';
var transformCss = '';
transformMatrix = immediateChild.css('transform');
transformMatrixValues = transformMatrix.match(/-?[\d\.]+/g);
var scaleXValue = transformMatrixValues[0];
var scaleXValueFixed = parseFloat(scaleXValue).toFixed(2);
var scaleYValue = (scaleXValue * 1.2).toFixed(2);
if (scaleXValueFixed >= 0.75)
{
scaleYValue = 1;
}
if ('WebkitTransform' in document.body.style)
{
transformCss = {'-webkit-transform': 'scale(' + scaleXValue + ',' + scaleYValue + ')',
'transform': ''};
}
else if ('MozTransform' in document.body.style)
{
transformCss = {'-moz-transform': 'scale(' + scaleXValue + ',' + scaleYValue + ')'};
}
else if ('transform' in document.body.style)
{
transformCss = {'tansform': 'scale(' + scaleXValue + ',' + scaleYValue + ')'};
}
$(immediateChild).css(transformCss);
}, 0);
}
It worked flawlessly in desktop browser (firefox, chrome only I checked) but if opened on mobile phone (iphone, android) means it scaled to too big size. Also I checked the value in mobile and in desktop by adjusting browser screen size to phone screen size same value is returned in alert('scaleXValue=' + scaleXValue + '<-->' + 'scaleXValueFixed=' + scaleXValueFixed + '<-->' + 'scaleYValue=' + scaleYValue);.
I can't get any clue so here I attach the screen shot of failed solution in mobile.
And I call this function on loading and resizing the window.
jssorResolutionAdjustor('jssor_image_gallery');
$(window).resize(function() {
jssorResolutionAdjustor('jssor_image_gallery');
});
jssor_image_gallery is the id given in jssor instance
jssor_slider_image = new $JssorSlider$('jssor_image_gallery', options);
Updated (1):
Here is my jssor function
function imageJssor()
{
var _CaptionTransitions = [];
_CaptionTransitions["MCLIP|B"] = {$Duration: 600, $Clip: 8, $Move: true, $Easing: $JssorEasing$.$EaseOutExpo};
var options = {
$AutoPlay: false,
$ThumbnailNavigatorOptions: {
$Class: $JssorThumbnailNavigator$,
$ChanceToShow: 2,
$Cols: 6,
$Align: 260,
$SpacingX: 3, //[Optional] Horizontal space between each thumbnail in pixel, default value is 0
$ArrowNavigatorOptions: {
$Class: $JssorArrowNavigator$, //[Requried] Class to create arrow navigator instance
$ChanceToShow: 2, //[Required] 0 Never, 1 Mouse Over, 2 Always
$Steps: 6 //[Optional] Steps to go for each navigation request, default value is 1
}
},
$ArrowNavigatorOptions: {
$Class: $JssorArrowNavigator$,
$ChanceToShow: 2
},
$CaptionSliderOptions: {//[Optional] Options which specifies how to animate caption
$Class: $JssorCaptionSlider$, //[Required] Class to create instance to animate caption
$CaptionTransitions: _CaptionTransitions, //[Required] An array of caption transitions to play caption, see caption transition section at jssor slideshow transition builder
$PlayInMode: 0, //[Optional] 0 None (no play), 1 Chain (goes after main slide), 3 Chain Flatten (goes after main slide and flatten all caption animations), default value is 1
$PlayOutMode: 0 //[Optional] 0 None (no play), 1 Chain (goes before main slide), 3 Chain Flatten (goes before main slide and flatten all caption animations), default value is 1
}
};
jssor_slider_image = new $JssorSlider$('jssor_image_gallery', options);
//responsive code begin
//you can remove responsive code if you don't want the slider scales while window resizes
function ScaleSlider() {
/* var windowWidth = $(window).width();
if (windowWidth) {
var windowHeight = $(window).height();
var originalWidth = jssor_slider_image.$OriginalWidth();
var originalHeight = jssor_slider_image.$OriginalHeight();
var scaleWidth = windowWidth;
if (originalWidth / windowWidth > originalHeight / windowHeight) {
scaleWidth = Math.ceil(windowHeight / originalHeight * originalWidth);
alert(scaleWidth);
}
jssor_slider_image.$ScaleWidth(scaleWidth);
}
else
window.setTimeout(ScaleSlider, 30);
var bodyWidth = document.body.clientWidth;
alert(bodyWidth);
if (bodyWidth)
jssor_slider_image.$ScaleWidth(Math.min(bodyWidth-150, 1920));
else
window.setTimeout(ScaleSlider, 30); */
var parentWidth = jssor_slider_image.$Elmt.parentNode.clientWidth;
//alert(parentWidth);
if (parentWidth)
jssor_slider_image.$ScaleWidth(Math.min(parentWidth, 720));
else
window.setTimeout(ScaleSlider, 30);
}
ScaleSlider();
$(window).bind("load", ScaleSlider);
$(window).bind("resize", ScaleSlider);
$(window).bind("orientationchange", ScaleSlider);
//responsive code end
}
imageJssor();
$(document).on('click', '#one li', function() {
var imageStartFrom = $(this).index();
$('#image_gallery').hide();
$('#jssor_image_gallery').show();
jssor_slider_image.$PlayTo(imageStartFrom);
jssor_slider_image.$Pause();
jssorResolutionAdjustor('jssor_image_gallery');
$(window).resize(function() {
jssorResolutionAdjustor('jssor_image_gallery');
});
});
Updated (2):
Here in both images (web & mobile) the default scale ratio and my calculated values or looking same but as shown below image its working properly in website in desktop browser but not in mobile. Here I attached that image too for reference.
Here in the above image on left side the deer image get scaled to high with compare to right side image which is took from desktop browser.
Updated (3):
Please see below image's alert to verify the parentWidth both represents the same value only
Also I attach my html dom structure with id which is used in jssor is highlighted in blue background.

I found the solution that if -webkit-transform was set means instead emptying the transform css property have to check browser (gecko, webkit, etc) engine also have transform. If it exist the priority will goes to transform while rendering the dom compared to -webkit-transform.
FROM:
if ('WebkitTransform' in document.body.style)
{
transformCss = {'-webkit-transform': 'scale(' + scaleXValue + ',' + scaleYValue + ')',
'transform': ''};
}
TO:
if ('WebkitTransform' in document.body.style)
{
transformCss = {'-webkit-transform': 'scale(' + scaleXValue + ',' + scaleYValue + ')'};
if ('transform' in document.body.style)
{
transformCss = {'tansform': 'scale(' + scaleXValue + ',' + scaleYValue + ')'};
}
}

Related

Google sheets apps script, how to format a pdf saved to google drive?

im using this script in order to save the curren tab as a pdf to specific folder
function SaveAsPDF() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSpreadsheet = SpreadsheetApp.getActive(); // Get active spreadsheet.
var sheetName = sourceSpreadsheet.getActiveSheet().getName();
var pdfName = sheetName + ".pdf"; // Set the output filename as SheetName.
folder = DriveApp.getFolderById('ID');
var theBlob = createblobpdf(sheetName, pdfName);
var existing = folder.getFilesByName(pdfName); //returns file iterator;
var hasFile = existing.hasNext(); //check if iterator isn't empty;
if (hasFile) {
var duplicate = existing.next(); //access file;
//delete file;
var durl = 'https://www.googleapis.com/drive/v3/files/' + duplicate.getId();
var token = ScriptApp.getOAuthToken();
var dres = UrlFetchApp.fetch(durl, {
method: 'delete',
muteHttpExceptions: true,
headers: { 'Authorization': 'Bearer ' + token }
});
if (dres.getResponseCode() >= 400) {
//handle errors;
}
}
var newFile = folder.createFile(theBlob);
sourceSpreadsheet.toast("Saved ", "Success");
}
function createblobpdf(sheetName, pdfName) {
var sourceSpreadsheet = SpreadsheetApp.getActive();
var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
var url = 'https://docs.google.com/spreadsheets/d/' + sourceSpreadsheet.getId()
+ '/export'
+ '?format=pdf'
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=true' // orientation, false for landscape
+ '&scale=4' // 1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&fitw=true' // fit to width, false for actual size
+ '&top_margin=1.00' // All four margins must be set!
+ '&bottom_margin=0.00' // All four margins must be set!
+ '&left_margin=2.00' // All four margins must be set!
+ '&right_margin=0.00' // All four margins must be set!
+ '&sheetnames=true&printtitle=false' // hide optional headers and footers
+ '&pagenum=RIGHT&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
+ '&vertical_alignment=TOP' //TOP/MIDDLE/BOTTOM
+ '&gid=' + sourceSheet.getSheetId(); // the sheet's Id
var token = ScriptApp.getOAuthToken();
// request export url
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var theBlob = response.getBlob().setName(pdfName);
return theBlob;
};
my problem is that im not being able to format the pdf, I have been trying different ways but its like not responding to my changes (size, scale, margins fzr=false, etc) am I doing something wrong ?
the main thing I need is to fit to height in a letter size
any help please ?
Your code for formatting the pdf works correctly
The error must be elsewhere.
Mind that you have a loop that checks either the the file already exists before creating a new one. Most liekly you are not creating a new file because of the already existing file.
Try the following code:
function SaveAsPDF() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSpreadsheet = SpreadsheetApp.getActive(); // Get active spreadsheet.
var sheetName = sourceSpreadsheet.getActiveSheet().getName();
var pdfName = "thisFileisNew.pdf"; // Set the output filename as SheetName.
// folder = DriveApp.getFolderById('ID');
var theBlob = createblobpdf(sheetName, pdfName);
var newFile = DriveApp.createFile(theBlob);
sourceSpreadsheet.toast("Saved ", "Success");
}
function createblobpdf(sheetName, pdfName) {
var sourceSpreadsheet = SpreadsheetApp.getActive();
var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
var url = 'https://docs.google.com/spreadsheets/d/' + sourceSpreadsheet.getId()
+ '/export'
+ '?format=pdf'
+ '&size=A4' // paper size legal / letter / A4
+ '&portrait=false' // orientation, false for landscape
+ '&scale=4' // 1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&fitw=true' // fit to width, false for actual size
+ '&top_margin=1.00' // All four margins must be set!
+ '&bottom_margin=0.00' // All four margins must be set!
+ '&left_margin=2.00' // All four margins must be set!
+ '&right_margin=0.00' // All four margins must be set!
+ '&sheetnames=true&printtitle=false' // hide optional headers and footers
+ '&pagenum=RIGHT&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
+ '&vertical_alignment=TOP' //TOP/MIDDLE/BOTTOM
+ '&gid=' + sourceSheet.getSheetId(); // the sheet's Id
var token = ScriptApp.getOAuthToken();
// request export url
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var theBlob = response.getBlob().setName(pdfName);
return theBlob;
};
It will create in the root directory of your Drive a file called thisFileisNew.pdf - I set the format to landscape, so you see the change in the formatting easier.

ChartJS: Custom tooltip always displaying

Im using ChartJS to create a graph on my website.
Im trying to create a custom tooltip. According to the documentation, this should be easy:
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
custom: function(tooltip) {
// tooltip will be false if tooltip is not visible or should be hidden
if (!tooltip) {
return;
}
}
}
}
});
My problem is that the tooptip is never false and because of this my custom tooltip is always displayed.
Please see this JSFiddle (line 42 is never executed)
Question: Is it a bug that tooltip is never false, or am I missing something?
The custom tooltip option is used for when you want to create/style your own tooltip using HTLM/CSS outside of the scope of the canvas (and not use the built in tooltips at all).
In order to do this, you must define a place outside of your canvas to contain your tooltip (e.g. a div) and then use that container within your tooltips.custom function.
Here is an example where I used a custom tooltip to display the hovered pie chart section percentage in the middle of the chart. In this example I'm generating my tooltip inside a div with id "chartjs-tooltip". Notice how I interact with this div in my tooltips.custom function to position and change the value.
Also, the correct way to check if the tooltip should be hidden is to check it's opacity. The tooltip object will always exist, but when it should not be visible, the opacity is set to 0.
Chart.defaults.global.tooltips.custom = function(tooltip) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set Text
if (tooltip.body) {
var total = 0;
// get the value of the datapoint
var value = this._data.datasets[tooltip.dataPoints[0].datasetIndex].data[tooltip.dataPoints[0].index].toLocaleString();
// calculate value of all datapoints
this._data.datasets[tooltip.dataPoints[0].datasetIndex].data.forEach(function(e) {
total += e;
});
// calculate percentage and set tooltip value
tooltipEl.innerHTML = '<h1>' + (value / total * 100) + '%</h1>';
}
// calculate position of tooltip
var centerX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
var centerY = ((this._chartInstance.chartArea.top + this._chartInstance.chartArea.bottom) / 2);
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = centerX + 'px';
tooltipEl.style.top = centerY + 'px';
tooltipEl.style.fontFamily = tooltip._fontFamily;
tooltipEl.style.fontSize = tooltip.fontSize;
tooltipEl.style.fontStyle = tooltip._fontStyle;
tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};
Here is the full codepen example.
I hope that helps clear things up!

What is wrong with my coffeescript translation of this JS?

Trying to improve my Coffeescript skills, so thought I'd covert this jcrop demo. However it's not working as expect. Specifically, the redraw function does not appear to be being called.
This works fine.
// Create a new Selection object extended from Selection
var CircleSel = function(){ };
// Set the custom selection's prototype object to be an instance
// of the built-in Selection object
CircleSel.prototype = new $.Jcrop.component.Selection();
// Then we can continue extending it
$.extend(CircleSel.prototype,{
zoomscale: 1,
attach: function(){
this.frame.css({
background: 'url(' + $('#target')[0].src.replace('750','750') + ')'
});
},
positionBg: function(b){
var midx = ( b.x + b.x2 ) / 2;
var midy = ( b.y + b.y2 ) / 2;
var ox = (-midx*this.zoomscale)+(b.w/2);
var oy = (-midy*this.zoomscale)+(b.h/2);
//this.frame.css({ backgroundPosition: ox+'px '+oy+'px' });
this.frame.css({ backgroundPosition: -(b.x+1)+'px '+(-b.y-1)+'px' });
},
redraw: function(b){
// Call original update() method first, with arguments
$.Jcrop.component.Selection.prototype.redraw.call(this,b);
this.positionBg(this.last);
return this;
},
prototype: $.Jcrop.component.Selection.prototype
});
But when I try to write this in Coffescript it fails
CircleSel.prototype = new ($.Jcrop.component.Selection)
$.extend CircleSel.prototype,
zoomscale: 1
attach: ->
#frame.css background: 'url(' + $('#target')[0].src.replace('750', '750') + ')'
return
positionBg: (b) ->
midx = (b.x + b.x2) / 2
midy = (b.y + b.y2) / 2
ox = -midx * #zoomscale + b.w / 2
oy = -midy * #zoomscale + b.h / 2
#frame.css backgroundPosition: -(b.x + 1) + 'px ' + -b.y - 1 + 'px'
return
# this redraw function is not being called, everything else appears to work fine
redraw: (b) ->
$.Jcrop.component.Selection::redraw.call this, b
#positionBg #last
this
prototype: $.Jcrop.component.Selection.prototype
What have I done wrong?

OpenLayers: Open popup when hovering vector, without closing it when mouse is over popup itself

I have a map with a vector layer showing features from GeoJSON. When I hover the feature, a pop-up shows up at the beginning of the linestring. But it is flickering, it appears and disappears. I guess the feature somehow gets deselected. Maybe popup gets in the middle between mouse and the feature so the condition of feature being hovered is no more fulfilled. How can I solve it? I want the pop up to be displayed when the mouse is over the feature, no matter if the popup is in the way.
I think it can be replicated even with example code: http://openlayers.org/dev/examples/light-basic.html .
It happens even if my mouse is not directly over the white part of the popup.
It seems to me the problem is more severe in chrome than in firefox. Maybe this is not the problem of my code, but bug. If so, sorry for posting here.
I am using foollowing code :
layer = new OpenLayers.Layer.Vector("JOSM", {
eventListeners: {
'featureselected': function(evt) {
var feature = evt.feature;
var detailsTextHtml = "";
var lines = feature.attributes.evaluations.split("\n");
for (var i = 0; i < lines.length; i++) {
if (lines[i] !== "") {
detailsTextHtml += " <br> " + lines[i];
}
}
popup = new OpenLayers.Popup.FramedCloud("popup",
OpenLayers.LonLat.fromString(feature.geometry.getVertices()[0].toShortString()),
null,
"<div style='font-size:.8em'>Coefficient: " + feature.attributes.coefficient + "<br>Color:" + feature.attributes.color + "<br>Details: " + detailsTextHtml + "</div>",
null,
true
);
feature.popup = popup;
map.addPopup(popup);
},
'featureunselected': function(evt) {
var feature = evt.feature;
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
},
styleMap: styleMap,
strategies: [new OpenLayers.Strategy.Fixed()],
projection: geographic,
protocol: new OpenLayers.Protocol.HTTP({
url: "webresources/getJosmAspectsDetailed?startLon=" + document.getElementById('startLon').value +
"&startLat=" + document.getElementById('startLat').value +
"&endLon=" + document.getElementById('endLon').value +
"&endLat=" + document.getElementById('endLat').value + "&speed=17&comfort=0&quietness=0",
format: new OpenLayers.Format.GeoJSON()
})
});

JCrop: previous image not updated?

I developed a small JCrop file upload app; here is my code:
function createCropImage(event)
{
//alert(event.target.result);
document.getElementById("Imgpreview").src = event.target.result;
var img2 = document.getElementById("Imgpreview1").src = event.target.result;
// Create variables (in this scope) to hold the API and image size
var jcrop_api, boundx, boundy;
$('#Imgpreview1').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
});
function updatePreview(c)
{
$('#Xcoardinate').val( Math.round(c.x));
$('#Ycoardinate').val( Math.round(c.y));
$('#width').val( Math.round(c.w));
$('#height').val( Math.round(c.h));
if (parseInt(c.w) > 0)
{
var rx = 100 / c.w;
var ry = 100 / c.h;
$('#Imgpreview').css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
}
};
}
Here Imgpreview is the preview image and Imgpreview1 is the source image. I first select an image through the browse button:
<input type="file" size="45" id="photoUploadElmt" name="upload" onchange="previewImg()" style="width:430px;"/>
The original image (Imgpreview1) and preview image (Imgpreview) are showing fine, but if I select another image, the preview image is correct but in place of Imgpreview1 I see the older image.
If I put following code in comments, then images are displayed properly but I lose the JCrop instance:
$('#Imgpreview1').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
});
The destroy method is unreliable, so create a custom one as in this similar question