Nuxt styled component webpack image from assets directory - vue.js

I create button using styled components:
import styled from 'vue-styled-components';
const buttonProps = {
color: String,
br: String,
pad: String,
bgc: String,
bgch: String,
icon: String,
};
export default styled('button', buttonProps)`
color: ${props => props.color};
border-radius: ${props => props.br};
padding: ${props => props.pad};
background-color: ${props => props.bgc};
&:hover {
background-color: ${props => props.bgch};
}
&::before {
content: '';
background-image: url('~/assets/img/svg/${props => props.icon}');
width: 22px;
height: 22px;
}
`;
I try add background-image from assets directory but Nuxt return error 404 not found image. When I move image from assets to static and change in component:
...
background-image: url('/${props => props.icon}');
...
Image work correctly.
My structure images directory:
Run button:
<TestButton color="#000" br="red" pad="10px" bgc="green" bgch="red" icon="advertisement.svg">aaa</TestButton>
How I can send to styled component image from assets ?

I think you need to reference them differently
background-image: url('/${props => props.icon}'); // is for static
background-image: url('~assets/img/svg/${props => props.icon}'); // is for assets
// or
background-image: url('#assets/img/svg/${props => props.icon}');
Hope this helps!

Related

Flickity Slider Animation and Gsap

The slider I am building have the active slider bigger than the others. I managed to make it work without the animation with flkty.reposition(). However, I am trying now to add the animation where the next slide grows in and the active decrease out. For The animation I am using GSAP.
The issue I am facing is to overwrite the left property with gsap so that it continuous animate. As of now, the left property (controlled by Flickity) does not take into account the final size (controlled by GSAP) of the selected slide.
https://codepen.io/stefanomonteiro/pen/VwzwjLw?editors=0010
As the left property of each slide is controlled by Flickity, we could use margin-left with a minus value as an alternative property to pull the selected slide to the left. I know margin is not a good property to animate but it works in this case without digging too deep into the Flickity core.
Here is the GSAP code:
gsap.to(slides, {
duration: 1,
width: "220px",
height: "336px"
});
gsap.to(selectedSlide, {
duration: 1,
marginLeft: "-248px", // the empty space calculated by newWidth - oldWidth
width: "468px",
height: "630px",
onComplete: () => {
// once all animations have been settled, we reset the margin
gsap.set(selectedSlide, { marginLeft: "" });
// and tell Flickity to update
flkty.resize();
flkty.reposition();
}
});
And the snippets
const animate = () => {
const flkty = Flickity.data(".carousel");
const selectedSlide = flkty.selectedElement;
const slides = flkty.getCellElements();
// remove the selected slides
slides.splice(flkty.selectedIndex, 1);
gsap.to(slides, {
duration: 1,
width: "220px",
height: "336px"
});
gsap.to(selectedSlide, {
duration: 1,
marginLeft: "-248px", // the empty space calculated by newWidth - oldWidth
width: "468px",
height: "630px",
onComplete: () => {
// once all animations have been settled, we reset the margin
gsap.set(selectedSlide, {
marginLeft: ""
});
// and tell Flickity to update
flkty.resize();
flkty.reposition();
}
});
};
new Flickity(".carousel", {
cellAlign: "right",
wrapAround: true,
percentPosition: false,
on: {
ready: () => animate()
}
});
const nextButton = document.querySelector(".flickity-button.next");
nextButton.addEventListener("click", () => animate());
/* external css: flickity.css */
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
.carousel {
background: #EEE;
}
.carousel-cell {
width: 220px;
height: 336px;
margin-right: 20px;
background: #8C8;
border-radius: 5px;
counter-increment: carousel-cell;
}
.carousel-cell.is-selected {
width: 468px;
height: 630px;
z-index: 1;
}
/* cell number */
.carousel-cell:before {
display: block;
text-align: center;
content: counter(carousel-cell);
line-height: 200px;
font-size: 80px;
color: white;
}
<link href="https://npmcdn.com/flickity#2/dist/flickity.css" rel="stylesheet" />
<script src="https://unpkg.co/gsap#3/dist/gsap.min.js"></script>
<script src="https://npmcdn.com/flickity#2/dist/flickity.pkgd.js"></script>
<h1>Flickity - wrapAround</h1>
<!-- Flickity HTML init -->
<div class="carousel">
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
</div>
And the Codepen
You can also notice that we have to wait until the animation is finished until we perform the next click, otherwise, it would mess up the whole process. This is predictable. Hence, I personally will try not to manipulate this Flickity slider for this kind of animation. Just want to give you a solution, anyway.

Nuxt.js: add custom loading component

I have been trying to add loading spinner to my NuxtJS project using the loading configuration: https://nuxtjs.org/api/configuration-loading.
However, the documentation is hard to understand, I have no idea how to apply it to my project. Did any have any ideas of how to add loading spinner using that?
Thanks in advance,
So you can create a custom loading:
We can create our custom component in components/loading.vue:
<template lang="html">
<div class="loading-page" v-if="loading">
<p>Loading...</p>
</div>
</template>
<script>
export default {
data: () => ({
loading: false
}),
methods: {
start () {
this.loading = true
},
finish () {
this.loading = false
}
}
}
</script>
<style scoped>
.loading-page {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
text-align: center;
padding-top: 200px;
font-size: 30px;
font-family: sans-serif;
}
</style>
Then, we update our nuxt.config.js to tell Nuxt.js to use our component:
export default {
loading: '~/components/loading.vue'
}
And then in your compenent you can show and hide with the:
this.$nuxt.$loading.start() to start the loading bar and this.$nuxt.$loading.finish() to finish it.
You can put this in the callbacks of a request.
probably it's about z-index value

How to make blueimp gallery textFactory work with an iframe

I have followed the documentation here:
https://github.com/blueimp/Gallery
First loaded assets separatedly.
Then created blueimp-gallery-textFactory.js and loaded after core file, before video file, with the following contents:
blueimp.Gallery.prototype.textFactory = function (obj, callback) {
var $element = $('<div>')
.addClass('text-content')
.attr('title', obj.title);
var iframe=$('<iframe>', {
src: obj.href,
frameborder: 0,
height: '100%',
width: '100%',
scrolling: 'no'
});
$element.html(iframe);
callback({
type: 'load',
target: $element[0]
});
return $element[0];
};
So what changes from original example is that I'm not making an ajax request and then running callback, but instead creating an iframe and then running callback.
And also added the aditional css style to the stylesheet:
.blueimp-gallery > .slides > .slide > .text-content {
overflow: auto;
margin: 60px auto;
padding: 0 60px;
max-width: 920px;
text-align: left;
}
The issue I ran into is that the onLoad/complete event would never fire and the slideLoading class will be always on top of the iframe.
I started to look into the videoFactory plugin and youtube one to see what could be wrong.
So I've stole some CSS from the video plugin:
.blueimp-gallery > .slides > .slide > .text-content > iframe {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 100%;
border: none;
}
.blueimp-gallery > .slides > .slide > .text-content > iframe {
top: 0;
}
This (helps) but did not solve the problem.
What did solve the problem was taken from blueimp-gallery-video.js and that is running the callback with this setTimeout function.
blueimp.Gallery.prototype.textFactory = function (obj, callback) {
var $element = $('<div>')
.addClass('text-content')
.attr('title', obj.title);
var iframe=$('<iframe>', {
src: obj.href,
frameborder: 0,
height: '100%',
width: '100%',
scrolling: 'no'
});
$element.html(iframe);
// callback({
// type: 'load',
// target: $element[0]
// });
this.setTimeout(callback, [
{
type: 'load',
target: $element[0]
}
]);
return $element[0];
};
This time the problem got solved. I guess with the $.get ajax call from original example there was no need to call setTimeout but with the iframe it was required.

How can I add header and footer in PDF page using phantom-html2pdf

I am unable to find way of adding header and footer in pdf page using phantom-html2pdf with Express and Coffeescript. My code is as follows can you please review it and tell me what I am missing:
pdf = require('phantom-html2pdf')
exports.test_pdf = (req, res) ->
paperSize = {
format: 'A4',
margin: "1cm",
orientation: 'portrait'
header: {
height: "200cm",
contents: '<h1>This is the Header</h1>'
},
}
htmls = '<html><body><h2>PDF CONTENT</h2></body></html>';
options = {
html: htmls,
css: "./public/stylesheets/foundation.css",
paperSize : page.paperSize
}
pdf.convert options, (err, result) ->
if !err
result.toBuffer()
# Using a readable stream
result.toStream()
# Using the temp file path */
result.getTmpPath()
# Using the file writer and callback */
result.toFile("./html/pdf_file.pdf")
else
res.render('index', { title: 'Social Media'})
I have already done some research that to add header and footer, I need to export a paperSize object from a runnings file. https://github.com/bauhausjs/phantom-html2pdf/issues/30
but adding that too could not help me or I am not adding it correctly.
A little help will be much appreciated. Thanks in advance.
module.exports will resolve your problem. After creating the page object for header & footer. you will export the object with module.export.
Here is the sample code
module.exports = {
header: {
height: '3cm', contents: function (page) {
return '<header class="pdf-header" style=" overflow:hidden; font-size: 10px; padding: 10px; margin: 0 -15px; color: #fff; background: none repeat scroll 0 0 #00396f;"><img style="float: left;" alt="" src="../images/logo.jpg"><p> XYZ </p></header>'
}
},
footer: {
height: '3cm', contents: function (page) {
return '<footer class="pdf-footer" style="font-size: 10px; font-weight: bold; color: #000;><p style="margin: 0">Powered by XYZ</p></footer>'
}
},
}
Note: You need to create runing file and copy & paste given code in it.

wicked_pdf and wkhtmltopdf page size issue

I used these settings
WickedPdf::config = {
:layout => 'application.pdf.html', # use 'pdf.html' for a pfd.html.erb file
:wkhtmltopdf => '/bin/wkhtmltopdf', # path to binary
:orientation => 'Portrait', # default , Landscape
:page_size => 'A4',
:dpi => '300',
:print_media_type => true,
:no_background => true,
:margin => {:top => 0, # default 10 (mm)
:bottom => 0,
:left => 0,
:right => 0},
}
and set the body style to
body {
margin: 0;
padding: 0;
background-color: #FFF;
width: 210mm;
height: 297mm;
}
and a div of class .page
.page {
display: inline-block;
clear: both;
border: 2px solid #FF0000;
width: 210mm;
height: 297mm;
page-break-after: auto;
}
but when the pdf is created, the .page divs are almost half of the pdf page.
If you are floating your page container, then it won't work. I had the exact same problem and once I removed the floating pro.
So your page container should be:
.page {
display: block;
clear: both;
border: 2px solid #FF0000;
page-break-after: auto;}
Because the inline-block is just like floating it left.
Try putting in your css
#media print
{ .page {
display: inline-block;
clear: both;
border: 2px solid #FF0000;
width: 210mm;
height: 297mm;
page-break-after: auto;
}
}
Also make sure you add media="all" if you are referencing external stylesheet:
<link href="/stylesheets/scaffold.css?1304060088"
media="all" rel="stylesheet" type="text/css">