Is it possible to show gradients with react-svgmt? - reactjs

I would like to use react-svgmt to manipulate SVG's. These SVG's can be uploaded from the users. My problem is, that if the SVG has a gradient these parts of the SVG are not shown.
Has anybody a solution for my problem to reactivate these links after the import of the SVG via react-svgmt?
With the developertools of my browser I was be able the see that the elements are in the code, but the grandients will be linked to the elements and these links are broken.
I have seen that other people has the same problem with gradients and created an issue on github, but the developer did not respond.

I found a solution for my problem.
react-svgmt add to elements like linearGradients "-{nr}" to its id-names. Then this fill:url(#linear-gradient-2); does not work anymore in the style-tags, because it must be fill:url(#linear-gradient-2-{nr});.
So the first SVGProxy after loading is <SvgProxy selector="linearGradient" onElementSelected={handleGradients} ></ SvgProxy>
an the function handleGradients looks like following and saves the {nr}
const handleGradients = (gradients) => { if (typeof gradients.length !== 'undefined') { const output = gradients.map((g, i) => { nr = g.id.substring(g.id.lastIndexOf("-")+1); setNr(g.id.substring(g.id.lastIndexOf("-")+1)); if(g.href.baseVal.length > 0) { var base = g.href.baseVal; g.href.baseVal = base + '-' + nr; } return g; }); } else { nr = gradients.id.substring(gradients.id.lastIndexOf("-")+1); setNr(gradients.id.substring(gradients.id.lastIndexOf("-")+1)); if(gradients.href.baseVal.length > 0) { var base = gradients.href.baseVal; gradients.href.baseVal = base + '-' + nr; } } };
Then I had another SVGProxy
<SvgProxy selector="defs > style" onElementSelected={handleStyleElem} ></ SvgProxy>
with the following handlefunction which replaces all urls with the schema from above
const handleStyleElem = (svgStyle) => { var styleStr = svgStyle.outerHTML; styleStr = styleStr.replaceAll(/url\(#((\w|-)*)\);/g, 'url(#$1-'+ nr +');'); svgStyle.outerHTML = styleStr; };

Related

Run function for an array of values

I'm trying to run a couple of functions for an array of values and it's not working. Essentially what I want to do is paste and export a PDF of the range A1:C15 for every cell in Z. I have tried a couple of things and nothing seems to work, the latest code I tried is the following:
function GuardarPDF(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var refesSheet = ss.getSheetByName("etiqueta");
var lista_refes = refesSheet.getRange("Z4:Z" + refesSheet.getLastRow()).getValues();
var lista_refes_ok = lista_refes.filter(([a]) => a);
for (var i = 0; i < lista_refes_ok.length; i++) {
console.log(lista_refes_ok[i][0]) // Here, you can see the folder ID in the log.
var refes = lista_refes_ok[i][0];
try {
for (var i = 0; i < lista_refes_ok.length; i++) {
console.log(lista_refes_ok[i][0]) // Here, you can see the folder ID in the log.
var refes = lista_refes_ok[i][0];
try {
var referencia2 = refesSheet.getRange("B5").setvalue(refes);
CreaPDF();
}}
(CreaPDF works fine, I'm having trouble generating the iteration so that a PDF for every row in Z is generated)
Does anybody know where the problem is or how to solve it? Thank you so much in advance!
Your code had a variety of errors, but I think this is what you are looking for:
Try:
function GuardarPDF() {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const refesSheet = ss.getSheetByName(`etiqueta`)
const lista_refes = refesSheet.getRange(`Z4:Z${refesSheet.getLastRow()}`)
.getValues()
.flat()
.filter(cell => cell != ``)
lista_refes.forEach(ref => {
refesSheet.getRange(`B5`).setValue(ref)
CreaPDF()
Utilities.sleep(5000)
})
}
This will get all values listed in Z4:Z(lastRow), then remove any blank cells. For each of the values, it will write the ref to cell B5 (potential error), and run CreaPDF.
If you need any further explanation, have any questions, or need modification, please let me know!
Learn More:
Array.forEach()
Utilities.sleep()
Try this:
function myfunk() {
const ss = SpreadsheetApp.getActive()
const rsh = ss.getSheetByName(`Your Sheet Name`)
const vs = rsh.getRange(4,26,rsh.getLastRow() - 3).getValues().flat().filter(e => e);
vs.forEach(e => {
rsh.getRange(`B5`).setValue(e);
SpreadsheetApp.flush();
CreaPDF()
});
}

Why do my Component lost while rendering the next page?

I'm using MathJax for the first time and I did success to display some simple formule like
'a x b = c' in a quizz whith several questions.
On the first page, my formula displayed well but not the others, as you can see on the inspector the component disappear...
Here is the first question :
And the second question :
Here is the code where I am mounting the component :
function createRandomQuestions() {
var nbQuestions = 10;
var maxInt = 15;
var randomQuestions = [];
for (var i = 0; i < nbQuestions; i++) {
var randomInt1 = getRandomInt(maxInt);
var randomInt2 = getRandomInt(maxInt);
var enounceModel = "\\({" + randomInt1 + "}\\times{"+ randomInt2 + "} = \\)";
console.log(enounceModel)
var question = {
enounce: <MathJaxDisplay
enounceModel={enounceModel}/>
,
answer: randomInt1*randomInt2
}
randomQuestions.push(question);
}
CustomLogger("randomQuestions", randomQuestions, 'TableTestHome')
setQuestions(randomQuestions);
return randomQuestions;
}
And
MathJaxDisplay
is just a custom Component englobing the regex :
"\\({a}\\times{b} = \\)";
import React from 'react';
import { MathJax, MathJaxContext } from "better-react-mathjax";
const MathJaxDisplay = ({enounceModel}) => {
return (
<MathJaxContext>
<MathJax>
{enounceModel}
</MathJax>
</MathJaxContext>
);
}
export default MathJaxDisplay;
Thank you for your help

Typescript pagination

I am trying to create a pagination functionality for an Angular project and I have to do this only with typescript.
Task: paginate an array, number of objects displayed per page is 15.
My declarations are:
PAGE_SIZE: number = 15;
total: number = this.booksArray.length;
pageNumber: number = 1;
pageBooks!: BookModel[];
numberOfPages: number = Math.ceil(this.total/this.PAGE_SIZE);
currentPage!: number;
Total will be the number of the objects within the array, pageNumber is initialized to 1.
pageBooks should be a subarray of the booksArray, and it is the array to be displayed on the page.
Getting the books to display on the page is done through the following method, however if I use the pageBooks variable in the *ngFor html it won't yield anything; instead I use the full method name and arg.(1st problem)
getPageBooks(pageNumber: number) {
var trimLeft: any = (pageNumber - 1) * this.PAGE_SIZE;
var trimRight: any = pageNumber * this.PAGE_SIZE;
(trimRight < this.booksArray[this.total - 1]) ? pageNumber * this.PAGE_SIZE : this.booksArray[(this.total - 1)];
const pageBooks = this.booksArray.slice(trimLeft, trimRight);
return pageBooks;
}
Console logging in the ngOnInit() returns an undefined or 0, which halts my progress(2nd problem).
I have also prepared several methods to add to my html as pagination events:
showPage(index) {
let displayedPage = this.getPageBooks(index);
this.displayBooks(displayedPage);
this.currentPage = index;
}
showFirstPage() {
this.showPage(1);
}
showLastPage() {
this.showPage(numberOfPages);
}
showNextPage() {
let pageToDisplay = this.currentPage + 1;
this.currentPage = pageToDisplay;
this.showPage(this.currentPage);
}
showPreviousPage() {
let pageToDisplay = this.currentPage - 1;
this.currentPage = pageToDisplay;
this.showPage(this.currentPage);
}
Could someone please help and advise on what I am doing wrong?
Thanks!

How to show changed image after dowloading it in SVG in React?

I'm trying to figure out how to show an image in another page after you have clicked on download button. The application itself is a Meme generator where you can add your own text. Adding text and downloading it works perfectly. I also have a way to like the memes and save the likes on firebase. I have another page that displays memes that have more than 10 likes. But I want to show memes that users have added text to and have some way to display them after the user has downloaded it.
The code I'm using to download looks like this. This excludes the return statement that attaches the text added to the meme.
saveMeme = () => {
let name = document.getElementById("memename").value
name.length > 0 ?
svg.saveSvgAsPng(document.getElementById("svg_ref"), `${name}.png`) :
svg.saveSvgAsPng(document.getElementById("svg_ref"), "meme.png")
};
My question is what could I add here to have the changed image be displayed.?
My code for liking the memes looks like this(if it's useful)
getMemesWithHigherLikes = () => {
let memesWithLikes = [];
const { memeLikesList, images} = this.props;
for (let i = 0; i < memeLikesList.length; i++) {
if (memeLikesList[i]?.likes >= 10) {
for (let j = 0; j < images.length; j++) {
if (images[j].id === memeLikesList[i].memeId) {
memesWithLikes.push(images[j]);
}
}
}
}
return memesWithLikes;
}
render() {
const memesList = !this.state?.showMemesWithHighLikes ? this.props.images :
this.getMemesWithHigherLikes();

Open multiple tab creating function in controller in angularjs

my controller function is :-
vm.selectSales = function () {
var url = "";
if ($scope.selection.length > 0) {
for (var i = 0, len = $scope.selection.length; i < len; i++) {
url=($state.href('work-area', { 'saleId': $scope.selection[i] ;
window.open(data, '_blank');
$window.location.reload();
}}};
According to this, i want to open multiple tab, but only one tab is open. Please suggest me a way to open multiple tab with different sale id.
After searched a lot i found that code is fine, i.e. below code work perfectly :-
vm.selectSales = function () {
var url = "";
if ($scope.selection.length > 0) {
for (var i = 0, len = $scope.selection.length; i < len; i++) {
url = ($state.href('work-area', { 'saleId': $scope.selection[i] }));
window.open(url, '_blank');
}}
};
But it is not work due to chrome popups setting its not work.
Now, to work with this code, i need to change my chrome setting :-
Click on Setting----->Advanced Setting----->Content Settings----->allow all sites to show popups.
Thanks to all.
For starters you didn't close $state.href's second parameter.
Also, ¿why are you doing a location.reload inside the for? It will reload the main page on execution, making it impossible for you to do what you want.
If window.open(url, '_blank') really opens a tab, you could give this a go:
vm.selectSales = function () {
var url = "";
if ($scope.selection.length > 0) {
for (var i = 0, len = $scope.selection.length; i < len; i++) {
url=($state.href('work-area', { 'saleId': $scope.selection[i]};
window.open(data, '_blank');
}
$window.location.reload();
}
};
Having serious doubts on the location reload though .

Resources