Image getting cut off from top using html2canvas and JSPdf - javascript

I am creating a multi page PDF from html using jspdf and html2canvas but my image is getting cut off little from top side. I tried all possible solutions from different forums but no success. below is the code
[Attached image for reference]
https://i.stack.imgur.com/7FoF5.png
var data = document.getElementsByClassName('divtocapture');
for(let content=0;content<data.length;content++)
{
html2canvas(data[content] as HTMLElement,{scale: 2,width:1150,scrollX: 0,scrollY: 0, allowTaint: true, backgroundColor: '#fff'}).then(canvas => {
var imgWidth = pdf.internal.pageSize.getWidth()
var imgHeight = canvas.height * imgWidth / canvas.width;
const contentDataURL = canvas.toDataURL('image/JPEG',1.0)
pdf.addImage(contentDataURL, 'JPEG', 5, 10, imgWidth, imgHeight)
pdf.save('mypdf.pdf');
})
}```
<div class="divtocapture">
<div class="card-header mat-elevation-z20" >
Article Transfers
</div>
<br>
<!-- Transfer -->
<div class="row ">
<div class="col col-sm-12">
<div class="card mb-12">
<div class="card-header">
Transfers
</div>
</div>
</div>
<div class="col col-sm-4 ">
<div class="card mb-3">
<div class="card-body">
<canvas baseChart [datasets]="this.service.NoofRejectionsChartData" [labels]="this.service.NoofRejectionslabels" [options]="this.graphSettings._barChart27Options"
[colors]="this.graphSettings._barChartColourList" [legend]="this.graphSettings.barChartLegend" [chartType]="this.graphSettings.barChartType" >
</canvas>
</div>
</div>
</div>
<div class="col col-sm-4">
<div class="card mb-3">
<div class="card-body">
<canvas baseChart [datasets]="this.service.OfferedChartData" [labels]="this.service.Offeredlabels" [options]="this.graphSettings._barChart13Options"
[colors]="this.graphSettings._barChartColourList" [legend]="this.graphSettings.barChartLegend" [chartType]="this.graphSettings.barChartType" >
</canvas>
</div>
</div>
</div>
<div class="col col-sm-4">
<div class="card mb-3">
<div class="card-body">
<canvas baseChart [datasets]="this.service.ReceivedChartData" [labels]="this.service.Receivedlabels" [options]="this.graphSettings._barChart14Options"
[colors]="this.graphSettings._barChartColourList" [legend]="this.graphSettings.barChartLegend" [chartType]="this.graphSettings.barChartType" >
</canvas>
</div>
</div>
</div>
</div>
</div>

Maybe it's because of x,y offset?
Try to set zero:
pdf.addImage(contentDataURL, 'JPEG', 0, 0, imgWidth, imgHeight)
Also double check the imgHeight, maybe your calculation is wrong and imgHeight is lower that thay should be.

Related

Javascript auto "transform: scale()" iframe, preserving aspect ratio

I am trying to show a couple of iframes in my site, but want them to be responsive - keeping their aspect ratio (16:9) - and scale their contents using CSS scale() function - so preserving actual frame width & height.
Below you may find my attempt, which works fine on page load, but it's not responsive on page resize.
var iframe = document.getElementById('frame'),
iframeinitialwidth = $('iframe').width();
jQuery.fn.fitToParent = function () {
this.each(function () {
var $iframe = jQuery(this);
var width = $iframe.width();
var height = $iframe.height();
var parentWidth = $iframe.parent().width();
var parentHeight = $iframe.parent().height();
var aspect = width / height;
var parentAspect = parentWidth / parentHeight;
if (aspect > parentAspect) {
newWidth = parentWidth;
newHeight = newWidth / aspect;
} else {
newHeight = parentHeight;
newWidth = newHeight * aspect;
}
});
var scaleFactor = newWidth/iframeinitialwidth;
$('iframe').css({'-webkit-transform': 'scale('+scaleFactor+')', '-webkit-transform-origin': '0 0'});
};
$('.frame').fitToParent();
$( window ).resize(function() {
console.log("resizing window");
$('.frame').fitToParent();
});
.frame-wrapper{
aspect-ratio: 16 / 9;
background-color: red;
position: relative;
}
.frame {
position: absolute;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="bg-light">
<div class="container">
<div class="row mt-4 px-2">
<div class="col ms-sm-auto col-lg-12 px-md-4">
<h1 class="h2">Dashboard</h1>
<div class="row">
<div class="col-12 col-md-6 mb-4 mb-lg-0 col-lg-3 my-4">
<div class="card">
<h5 class="card-header">Test</h5>
<div class="card-body p-0">
<div class="frame-wrapper">
<iframe frameborder="no" class="frame" src="https://www.wikipedia.org/" id="frame" width="1280px" height="720px"></iframe>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 mb-4 mb-lg-0 col-lg-3 my-4">
<div class="card">
<h5 class="card-header">Test</h5>
<div class="card-body p-0">
<div class="frame-wrapper">
<iframe frameborder="no" class="frame" src="https://en.wikipedia.org/wiki/Acquisition_of_Twitter_by_Elon_Musk" id="frame" width="1280px" height="720px"></iframe>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 mb-4 mb-lg-0 col-lg-3 my-4">
<div class="card">
<h5 class="card-header">Test</h5>
<div class="card-body p-0">
<div class="frame-wrapper">
<iframe frameborder="no" class="frame" src="https://en.wikipedia.org/wiki/2022_French_presidential_election" id="frame" width="1280px" height="720px"></iframe>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 mb-4 mb-lg-0 col-lg-3 my-4">
<div class="card">
<h5 class="card-header">Test</h5>
<div class="card-body p-0">
<div class="frame-wrapper">
<iframe frameborder="no" class="frame" src="https://en.wikipedia.org/wiki/Sinking_of_the_Moskva" id="frame" width="1280px" height="720px"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>

How to know the selected card style and pass the value to the backend

I want to get the value in a single card selected by the user and post it to the backend
<div class="card-body">
<div class="swiper-container swipercards">
<div class="swiper-wrapper pb-4">
<div class="swiper-slide ">
<div class="card border-0 bg-default text-white">
<div class="card-header">
<div class="row">
<div class="col-auto">
<i class="material-icons vm text-template">credit_card</i>
</div>
<div class="col pl-0">
<h6 class="mb-1">Visa</h6>
</div>
</div>
</div>
<div class="card-body">
<h5 class="mb-0 mt-3">4444 5264 2541 26651</h5>
</div>
<div class="card-footer">
<div class="row">
<div class="col">
<p class="mb-0">26/21</p>
<p class="small ">Expiry date</p>
</div>
<div class="col-auto align-self-center text-right">
<p class="mb-0">Agnish Carvan</p>
<p class="small">Card Holder</p>
</div>
</div>
</div>
</div>
</div>
<div class="swiper-slide ">
<div class="card border-0 bg-warning text-white">
<div class="card-header">
<div class="row">
<div class="col-auto">
<i class="material-icons vm text-template">credit_card</i>
</div>
<div class="col pl-0">
<h6 class="mb-1">Maestro</h6>
</div>
</div>
</div>
<div class="card-body">
<h5 class="mb-0 mt-3">4444 5264 2541 26651</h5>
</div>
<div class="card-footer">
<div class="row">
<div class="col">
<p class="mb-0">26/21</p>
<p class="small ">Expiry date</p>
</div>
<div class="col-auto align-self-center text-right">
<p class="mb-0">Agnish Carvan</p>
<p class="small">Card Holder</p>
</div>
</div>
</div>
</div>
</div>
Welcome AegisFor. It looks like you're using Swiper.js?
According to the docs, under events, here is how you determine the selected item in the carousel:
const swiper = new Swiper('.swiper', {
// ...
});
swiper.on('slideChange', function () {
console.log('slide changed', swiper.activeIndex);
});
https://swiperjs.com/swiper-api#events
You could get the values by referring to the slide's attributes, like this:
....
<div class="swiper-wrapper pb-4" >
<div class="swiper-slide " id="card-1" data-card-number="12345">
....
When you change slides, refer to the div that matches the activeIndex of the carousel:
var activeCard = document.getElementById("card-" + swiper.activeIndex);
Now you can get the card number:
var cardNumber = activeCard.getAttribute("data-card-number")
How you send it to your backend depends on what backed you have. You might do something similar to this:
fetch('http://example.com/card?card-number=' + cardNumber)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
The documentation at https://swiperjs.com/swiper-api is quite good. Remember to read the docs thoroughly before posting to SO.

Owl Carousel change content of the element on click

I have a problem with owl carousel and till now I don't have any ideas how to fix it.
So on the image 1 you can see the normal behaviour of the slider. On the second one you will see the extended functionality of it. The idea is very simple, when user click on the element, he should expand it, but when the element is expanded all other element goes to 2 rows and I don't want to happen.
Image 1
Image 2
also Source code of one element
<div class="element box-shadow">
<div class="child">
<div class="row">
<div class="col-xs-12 col-md-8">
<span>05.</span>
<h3>Graphic Designer</h3>
<p class="inventive">Inventive Studio</p>
<p class="view-more">View more <img src="assets/images/view-more.svg" /></p>
</div>
<div class="col-xs-12 col-md-4 portfolio-image" >
<img src="assets/images/inventive-small-img.png" />
</div>
</div>
</div>
<div class="parent hidden">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="row">
<div class="col-xs-12 col-md-8">
<div class="row " style="margin-bottom: 15px;" >
<div class="col-xs-12 col-md-3">
<img src="assets/images/inventive-small-img.png" style="width:34px" class="rounded-circle">
</div>
<div class="col-xs-12 col-md-9 text no-padding" >
<h3>Graphic Designer</h3>
<p class="inventive">Inventive Studio</p>
</div>
</div>
</div>
<div class="col-xs-12 col-md-4 social-el" style="padding-left:0;">
<div class="stars">
<img class="mr-2" src="assets/images/full_star.svg" />
<img class="mr-2" src="assets/images/full_star.svg" />
<img class="mr-2" src="assets/images/half_star.svg" />
<img class="mr-2" src="assets/images/empty_star.svg" />
<img src="assets/images/empty_star.svg" />
</div>
</div>
</div>
<img src="assets/images/inventive-studio-img.png" class="img-fluid">
<div class="content">
<p >Designing and producing catalogs, sales sheets, proposals, scenario illustrations, brochures, posters, custom displays for trade shows and in-house exhibits and all others items.</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<a class="view-less" href="#"><img src="assets/images/view-more.svg"/> View Less</a>
</div>
<div class="col-xs-12 col-md-6">
<div class="stars">
<img src="assets/images/Facebook.svg"/>
<img class="mr-10" src="assets/images/twitter.svg"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
also will share and jquery code
$(".owl-carousel").owlCarousel({
margin:10,
loop: true,
autoWidth: true,
items:3,
rewind: true,
autoplay: true,
responsiveClass:true,
});
$('.work').each(function(i, el) {
$parent = $(el);
$('.element', $parent).each(function(i, item) {
$element = $(item)
$element.on('click', function(e) {
$current = $(this)
console.log($current)
if ($('.parent', $current).hasClass('hidden')) {
$('.parent', $current).removeClass('hidden');
$current.addClass('expand-element');
$current.css('border-radius', 10)
$('.child', $current).addClass('hidden');
} else {
$current.removeClass('expand-element');
$('.parent', $current).removeClass('visible').addClass('hidden');
$current.css('border-radius', 20)
$('.child', $current).removeClass('hidden');
}
})
})
})

HTML javascript not able to destoy nth element by id

I am new to javascript and HTML. I developed website using node + express backend and using bootstrap + html + JS in front end. I have created few cards using BS4. It looks like following
Code:
<section id="cards">
<div class="container">
<div class="card-deck text-center">
<div class="card shadow-sm" id="mainCards">
<div class="card-header" id="mainCardHeader">
<h4 class="my-0 font-weight-normal">Total Cases</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title"><%= areaTotal%></h1>
</div>
</div>
<div class="card shadow-sm" id="mainCards">
<div class="card-header" id="mainCardHeader">
<h4 class="my-0 font-weight-normal">Last 30 days</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title"><%= arealast30%></h1>
</div>
</div>
<div class="card shadow-sm" id="mainCards">
<div class="card-header" id="mainCardHeader">
<h4 class="my-0 font-weight-normal">Last 7 days</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title"><%= arealast7%></h1>
</div>
</div>
<div class="card shadow-sm" id="mainCards">
<div class="card-header" id="mainCardHeader">
<h4 class="my-0 font-weight-normal">Growth</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title"><%= areaR%></h1>
</div>
</div>
<div class="card shadow-sm" id="mainCards">
<div class="card-header" id="mainCardHeader">
<h4 class="my-0 font-weight-normal">Deaths</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title"><%= areaDeaths%></h1>
</div>
</div>
</div>
</div>
</section>
I want to add one more card if count>0. I have created external div before 5th card and it is working fine with following script.
var deathCount = <%- areaDeaths%>;
if (deathCount == 0){
document.getElementById("divDeath").style.display = "none";
};
However new card is not aligned correctly. Is it anyway I can make 5th element of such id disappear without harming alignment of these cards.
tried so far:
var deathCount = <%- areaDeaths%>;
if (deathCount == 0){
var elements = document.getElementById("mainCards").children;
elements.item(4).style.display = "none";
};

The JS code fails to execute (or do anything) when I click the submit button

I'm just learning Javascript, and this is my first attempt to make something for myself, so forgive me if the solution is very simple. I'm trying to automate score keeping for a card game. When I click the submit button, nothing happens.
<div class="container body-content">
<div class="row mt-4 justify-content-center">
<div class="col-auto">
<img class="img-fluid logo" alt="cards" src="img/cards.png">
</div>
<div class="col-4">
<h1>Shayne's Golf Tally</h1>
</div>
</div>
<div class="row justify-content-center text-center round">
<div class="col">
<h2 id="round">Round: 0</h2>
</div>
</div>
<div class="row justify-content-center text-center mt-3">
<div class="col-3">
<h3 class="names">Shayne</h3>
<h3 id="shayne">0</h3>
</div>
<div class="col-3">
<h3 class="names">Amber</h3>
<h3 id="amber">0</h3>
</div>
</div>
<div class="row justify-content-center">
<div class="col-3 centered input-spacing">
<input class="form-control input-form" id="inputShayne">
</div>
<div class="col-3 centered input-spacing">
<input class="form-control input-form" id="inputAmber">
</div>
</div>
<div class="row justify-content-center text-center mt-4">
<div class="col">
<button class="btn btn-primary" onclick="tallyScore()">Submit</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="golf.js"></script>
And the javascript:
var round = 0;
var scoreShayne = 0;
var scoreAmber = 0;
function tallyScore() {
round += 1;
document.getElementById(round).innerHTML = "Round: " + round;
scoreShayne += document.getElementById("inputShayne").value;
scoreAmber += document.getElementById("inputAmber").value;
document.getElementById(shayne).innerHTML = scoreShayne;
document.getElementById(amber).innerHTML = scoreAmber;
}
some recommandations in this code, just to see ;)
// global values
var round = 0
, scoreShayne = 0
, scoreAmber = 0
;
// use constants to prevent the JS interpreter from recalculating each call
const hmi_round = document.getElementById('round')
, hmi_shayne = document.getElementById('shayne')
, hmi_amber = document.getElementById('amber')
, hmi_inputShayne = document.getElementById('inputShayne')
, hmi_inputAmber = document.getElementById('inputAmber')
;
function tallyScore()
{
hmi_round.textContent = "Round: " + ++round; // ++round is a direct increment (different from round++ )
hmi_shayne.textContent = scoreShayne += hmi_inputShayne.valueAsNumber; // HTML5 as valueAsNumber
hmi_amber.textContent = scoreAmber += hmi_inputAmber.valueAsNumber; // instead of parseInt(hmi_inputAmber.value)
hmi_inputShayne.value = "0"; // reset values for the next round
hmi_inputAmber.value = "0";
}
<div class="container body-content">
<div class="row mt-4 justify-content-center">
<div class="col-auto">
<img class="img-fluid logo" alt="cards" src="img/cards.png">
</div>
<div class="col-4">
<h1>Shayne's Golf Tally</h1>
</div>
</div>
<div class="row justify-content-center text-center round">
<div class="col">
<h2 id="round">Round: 0</h2>
</div>
</div>
<div class="row justify-content-center text-center mt-3">
<div class="col-3">
<h3 class="names">Shayne</h3>
<h3 id="shayne">0</h3>
</div>
<div class="col-3">
<h3 class="names">Amber</h3>
<h3 id="amber">0</h3>
</div>
</div>
<div class="row justify-content-center">
<div class="col-3 centered input-spacing">
<input class="form-control input-form" id="inputShayne" type="number"min="0" value="0"> <!-- don't forget to set the type -->
</div>
<div class="col-3 centered input-spacing">
<input class="form-control input-form" id="inputAmber" type="number" min="0" value="0"> <!-- don't forget to set the type -->
</div>
</div>
<div class="row justify-content-center text-center mt-4">
<div class="col">
<button class="btn btn-primary" onclick="tallyScore()">Submit</button>
</div>
</div>
</div>

Categories

Resources