Itext not rendering base64 transform rotated images - html
I am trying to rotate a base64 embedded image in the html using transform rotate, the image is rotated fine in the html page, but when i am trying to render the same in pdf using itext, the transformation properties has no effect.
Below is my sample html code.
<?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<style type="text/css">
body,div,td,th,span,h1,h2 {
font:9pt/12pt "Roboto", serif;
}
.fleft {
float:left;
overflow-x: wrap;
}
.rotate90 {
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
.gift-icon{
width: 21mm;
height: 21mm;
}
</style>
</head>
<body>
<div>
<img class="fleft gift-icon rotate90" alt="" src="data:image/png;base64,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"/>
</div>
</body>
</html>
I am using ReplacedElementFactory to re-generate the image, although the width and height of the image is getting rendered properly, the image is not getting rotated.
Please find the ReplacedElementFactory class below.
public class B64ImgReplacedElementFactory implements ReplacedElementFactory {
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try {
fsImage = buildImage(attribute, uac);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) {
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException, BadElementException {
FSImage fsImage;
if (srcAttr.startsWith("data:image/")) {
String b64encoded = srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(), srcAttr.length());
byte[] decodedBytes = Base64.decode(b64encoded);
fsImage = new ITextFSImage(Image.getInstance(decodedBytes));
} else {
fsImage = uac.getImageResource(srcAttr).getImage();
}
return fsImage;
}
public void remove(Element e) {
}
public void reset() {
}
#Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
}
}
Can someone please help me solve this?
Thanks in advance
Related
Retriggering a switch in HTML and Arduino
I'm trying to set up a wifi switch to turn my computer on wirelessly. I'm using a program that has a web server and password. The issue I am having is I only want the button to be triggered for a 1 second then come off. I want the slider to turn on then off after the delay. I'm struggling with the HTML language to accomplish this. I've tried adjusting the Arduino code but it has not worked. I believe the HTML code needs to be changed so that there's a delay and re-triggers the off switch. Here is the code that I am using: // Import required libraries #ifdef ESP32 #include <WiFi.h> #include <AsyncTCP.h> #else #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #endif #include <ESPAsyncWebServer.h> // Replace with your network credentials const char* ssid = ""; const char* password = ""; const char* http_username = "admin"; const char* http_password = "admin"; const char* PARAM_INPUT_1 = "state"; const int output = 26; int delaytime = 5000; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <title>Wifi Computer Switch</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> html {font-family: Arial; display: inline-block; text-align: center;} h2 {font-size: 2.6rem;} body {max-width: 600px; margin:0px auto; padding-bottom: 10px;} .switch {position: relative; display: inline-block; width: 120px; height: 68px} .switch input {display: none} .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px} .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px} input:checked+.slider {background-color: #2196F3} input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)} </style> </head> <body> <h2>Wifi Computer Switch</h2> <button onclick="logoutButton()">Logout</button> <p>Ouput - GPIO 2 - State <span id="state">%STATE%</span></p> %BUTTONPLACEHOLDER% <script>function toggleCheckbox(element) { var xhr = new XMLHttpRequest(); if(element.checked){ xhr.open("GET", "/update?state=1", true); document.getElementById("state").innerHTML = "ON"; } else { xhr.open("GET", "/update?state=0", true); document.getElementById("state").innerHTML = "OFF"; } xhr.send(); } function logoutButton() { var xhr = new XMLHttpRequest(); xhr.open("GET", "/logout", true); xhr.send(); setTimeout(function(){ window.open("/logged-out","_self"); }, 1000); } function powerbutton() { } </script> </body> </html> )rawliteral"; const char logout_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>Logged out or return to homepage.</p> <p><strong>Note:</strong> close all web browser tabs to complete the logout process.</p> </body> </html> )rawliteral"; // Replaces placeholder with button section in your web page String processor(const String& var){ //Serial.println(var); if(var == "BUTTONPLACEHOLDER"){ String buttons =""; String outputStateValue = outputState(); buttons+= "<p><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label></p>"; return buttons; } if (var == "STATE"){ if(digitalRead(output)){ return "ON"; } else { return "OFF"; } } return String(); } String outputState(){ if(digitalRead(output)){ return "checked"; } else { return ""; } return ""; } void setup(){ // Serial port for debugging purposes Serial.begin(115200); pinMode(output, OUTPUT); digitalWrite(output, LOW); // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); request->send_P(200, "text/html", index_html, processor); }); server.on("/logout", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(401); }); server.on("/logged-out", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", logout_html, processor); }); // Send a GET request to <ESP_IP>/update?state=<inputMessage> server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) { if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); String inputMessage; String inputParam; // GET input1 value on <ESP_IP>/update?state=<inputMessage> if (request->hasParam(PARAM_INPUT_1)) { inputMessage = request->getParam(PARAM_INPUT_1)->value(); inputParam = PARAM_INPUT_1; digitalWrite(output, inputMessage.toInt()); } else { inputMessage = "No message sent"; inputParam = "none"; } Serial.println(inputMessage); request->send(200, "text/plain", "OK"); }); // Start server server.begin(); } void loop() { } When I run the program, this is what the web page looks like Web Page Display The button slides but I would like it to turn off again after a certain amount of time. [edit: added web page photo]
how to make a loading animation with my code
I can't seem to figure out how to make the boxes rotate. I tried transformation, JS, and even html special code. I do suck at CSS, so this is my code so far: <!DOCTYPE html> <html> <head> <script> //great code from Scriptkiddy1337 on stack overflow const pageStack=[]; function getParameterByName(name, url) { url = url || window.location.href; name = name.replace(/[\[\]]/g, '\\$&'); var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } window.addEventListener('load', function (e) { var templates = document.getElementsByClassName('sitecontent'); for (var i = 0, v; v = templates[i]; i++) { for (var j = 0, x; x = v.childNodes[j]; j++) { if (x.nodeType === Node.ELEMENT_NODE) { pageStack.push(x); } } } var pageIndex = getParameterByName('page') || '0'; loadPage(pageIndex); }); function loadPage(index) { if (index >= pageStack.length || index < 0) { document.body.innerText = '404 Page not found'; return; } document.body.innerHTML = ''; document.body.appendChild(pageStack[index]); } </script> <style> box{ transition: 3s; width:50px; height:50px; position:fixed; transform:/*im confused here*/; } </style> </head> <body> <pageholder class="sitecontent"> <page> <animator> <!--I want them to rotate in a circle--> <box style="background-color:red">.</box><br><br><br> <box style="background-color:red">.</box><br><br><br> <box style="background-color:red">.</box><br><br><br> </animator> Next Page </page> <page> <h1>Homepage</h1> <hr> <p>Need help :(</p> </page> </pageholder> </body> </html> I tried to transform CSSstuff, JS animations (which I also kinda suck at), and even special HTML code. I might be missing something, but as far as I know (which isn't a lot, unfortunately), I have done nearly everything I can think of.
I would highly recommend you read up on CSS Animations <style> /* The animation code */ #keyframes rotateBox { to {transform: rotate(360deg)} } box{ transition: 3s; width: 50px; height: 50px; position: fixed; /* Use the animation here */ animation: rotateBox 3s; } </style>
Dynamically create column and row in HTML
I have data structure like this. and <param1> could be repeating . We can have multiple value for param1 <param> <param1> <name> <value> </param1> <param1> <name1> <value1> </param1> </param> I want to display in html dynamically like this(like column row ). How can we do it ??? name name1 value value1 Can someone suggest how to do it . I am new to this area
The solution should be: <!DOCTYPE html> <html> <style> param-list { font-size : 20px; display:inline-block; border:1px solid gray; } param-list > *{ font-size : 20px; display:block; } </style> <body> <param-list> <my-name></my-name> <my-value></my-value> </param-list> <param-list> <my-name1></my-name1> <my-value1></my-value1> </param-list> <script> class ParamList extends HTMLElement { connectedCallback() { this.children; } } customElements.define('param-list', ParamList); class Name extends HTMLElement { connectedCallback() { this.innerHTML = `name`; } } customElements.define('my-name', Name); class Name1 extends HTMLElement { connectedCallback() { this.innerHTML = `name1`; } } customElements.define('my-name1', Name1); class Value extends HTMLElement { connectedCallback() { this.innerHTML = `value`; } } customElements.define('my-value', Value); class Value1 extends HTMLElement { connectedCallback() { this.innerHTML = `value1`; } } customElements.define('my-value1', Value1); </script> </body> </html> Live at custom-element ref: https://www.html5rocks.com/en/tutorials/webcomponents/customelements/ How to create custom tags for html https://dev.to/jfbrennan/custom-html-tags-4788 https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
Vaadin cache.js
I am trying to build a treeSelectView using checkboxes. It implements HasValue so setValue hands over a list of nodes which should have checked checkboxes. and those checkboxes will be checked whenever the function is called. And here comes the downpart. When the treeSelectView reaches the client a script with the name https://localhost:8443/VAADIN/static/client/client-BF4676DDAFDA5E40AE93EFEB692AAAD5.cache.js is invoked which sets all the checkboxes in the tree to unchecked. This is the logoutput: Sending xhr message to server: {"csrfToken":"8eb266a3-ec2b-4238-9d2e-00da55a02c27","rpc":[{"type":"mSync","node":313,"feature":1,"property":"selected","value":false},{"type":"mSync","node":307,"feature":1,"property":"selected","value":false},{"type":"mSync","node":301,"feature":1,"property":"selected","value":false},{"type":"mSync","node":295,"feature":1,"property":"selected","value":false},{"type":"mSync","node":289,"feature":1,"property":"selected","value":false},{"type":"mSync","node":283,"feature":1,"property":"selected","value":false},{"type":"mSync","node":277,"feature":1,"property":"selected","value":false},{"type":"mSync","node":271,"feature":1,"property":"selected","value":false},{"type":"mSync","node":265,"feature":1,"property":"selected","value":false},{"type":"mSync","node":259,"feature":1,"property":"selected","value":false},{"type":"mSync","node":253,"feature":1,"property":"selected","value":false},{"type":"mSync","node":247,"feature":1,"property":"selected","value":false},{"type":"mSync","node":241,"feature":1,"property":"selected","value":false},{"type":"mSync","node":235,"feature":1,"property":"selected","value":false},{"type":"mSync","node":229,"feature":1,"property":"selected","value":false},{"type":"mSync","node":223,"feature":1,"property":"selected","value":false},{"type":"mSync","node":217,"feature":1,"property":"selected","value":false},{"type":"mSync","node":211,"feature":1,"property":"selected","value":false},{"type":"mSync","node":205,"feature":1,"property":"selected","value":false},{"type":"mSync","node":199,"feature":1,"property":"selected","value":false},{"type":"mSync","node":193,"feature":1,"property":"selected","value":false},{"type":"mSync","node":187,"feature":1,"property":"selected","value":false},{"type":"mSync","node":181,"feature":1,"property":"selected","value":false},{"type":"mSync","node":175,"feature":1,"property":"selected","value":false},{"type":"mSync","node":169,"feature":1,"property":"selected","value":false},{"type":"mSync","node":163,"feature":1,"property":"selected","value":false},{"type":"mSync","node":157,"feature":1,"property":"selected","value":false},{"type":"mSync","node":151,"feature":1,"property":"selected","value":false},{"type":"mSync","node":145,"feature":1,"property":"selected","value":false},{"type":"mSync","node":139,"feature":1,"property":"selected","value":false},{"type":"mSync","node":133,"feature":1,"property":"selected","value":false},{"type":"mSync","node":127,"feature":1,"property":"selected","value":false},{"type":"mSync","node":121,"feature":1,"property":"selected","value":false},{"type":"mSync","node":115,"feature":1,"property":"selected","value":false},{"type":"mSync","node":109,"feature":1,"property":"selected","value":false},{"type":"mSync","node":103,"feature":1,"property":"selected","value":false},{"type":"mSync","node":97,"feature":1,"property":"selected","value":false},{"type":"mSync","node":91,"feature":1,"property":"selected","value":false},{"type":"mSync","node":85,"feature":1,"property":"selected","value":false},{"type":"mSync","node":79,"feature":1,"property":"selected","value":false},{"type":"mSync","node":73,"feature":1,"property":"selected","value":false},{"type":"mSync","node":67,"feature":1,"property":"selected","value":false},{"type":"mSync","node":61,"feature":1,"property":"selected","value":false},{"type":"mSync","node":55,"feature":1,"property":"selected","value":false},{"type":"mSync","node":49,"feature":1,"property":"selected","value":false},{"type":"mSync","node":43,"feature":1,"property":"selected","value":false},{"type":"mSync","node":37,"feature":1,"property":"selected","value":false},{"type":"mSync","node":31,"feature":1,"property":"selected","value":false},{"type":"mSync","node":25,"feature":1,"property":"selected","value":false},{"type":"mSync","node":19,"feature":1,"property":"selected","value":false}],"syncId":1,"clientId":1} This is completely unexpected and unwanted behaviour. Can anybody tell me why this is happening? UPDATE Here is my TreeSelectItem: <link rel="import" href="../../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../../bower_components/vaadin-checkbox/src/vaadin-checkbox.html"> <link rel="import" href="../../../bower_components/vaadin-button/src/vaadin-button.html"> <dom-module id="tree-select-item"> <template> <style> #currentItemContainer{ background-color: var(--lumo-contrast-10pct); border-radius: var(--lumo-border-radius); padding: 5px; margin: 3px; overflow: auto; } .hidden{ display: none; } </style> <div id="currentItemContainer" style$="{{_getStyle(level)}}" class$="{{_isHidden(hidden)}}"> <div style="width: 90px; float: left"> <vaadin-checkbox id="checkbox" checked="{{selected}}" indeterminate="{{indeterminate}}" disabled="{{readOnly}}"></vaadin-checkbox> <vaadin-button class$="{{_isToggleHidden(hasDescendents)}}" theme="icon" on-click="collapse" style="--lumo-button-size: var(--lumo-size-xs);"> <iron-icon icon="{{_getCollapseToggle(collapsed)}}" slot="prefix"></iron-icon> </vaadin-button> </div> <div id="layout" float: left></div> </div> </template> <script> { class TreeSelectItem extends Polymer.Element { static get is() { return 'tree-select-item'; } /* collapse(){ this.collapsed = !this.collapsed; var parentElement = this.parentNode.__dataHost; parentElement.collapse(this.id,this.collapsed); } */ _getCollapseToggle(collapsed){ return collapsed ? "lumo:angle-right" : "lumo:angle-down"; } _isToggleHidden(hidden){ return !hidden ? "hidden" : ""; } _isHidden(hidden){ return hidden ? "hidden" : ""; } _getStyle(marginFactor){ return "margin-left:"+(20*marginFactor)+"px;"; } } window.customElements.define(TreeSelectItem.is, TreeSelectItem); } </script> </dom-module> Here is the java part #Data #Tag("tree-select-item") #HtmlImport("base/template/component/tree-select-item.html") public class TreeSelectItem<T extends BasicTreeObject<T>> extends PolymerTemplate<TreeSelectItemTemplateModel> { /** * The element containing this item */ private TreeSelect<T> treeSelect; private T item; #Id("layout") private Div layout; #Id("checkbox") private Checkbox checkbox; public TreeSelectItem(T item, TreeSelect<T> treeSelect) { setCollapsed(false); setSelected(false); getModel().setLevel(item.getLevel()); getModel().setId(item.getId().intValue()); getModel().setHasDescendents(CollectionUtils.isNotEmpty(item.getChildren())); getModel().setHidden(false); getModel().setReadOnly(false); this.treeSelect = treeSelect; this.item = item; render(); } public void render() { layout.removeAll(); Component label = treeSelect.getItemRenderer().createComponent(item); layout.add(label); } #EventHandler public void collapse() { treeSelect.collapse(this); } public void setCollapsed(boolean collapsed) { getModel().setCollapsed(collapsed); } public boolean isCollapsed() { return getModel().isCollapsed(); } public void setSelected(boolean selected) { setIndeterminate(false); getModel().setSelected(selected); } public boolean isSelected() { return getModel().isSelected(); } public void addSelectionListener(PropertyChangeListener listener) { getElement().addPropertyChangeListener("selected", listener); } public void setHidden(boolean hidden) { getModel().setHidden(hidden); } public void setIndeterminate(boolean indeterminate) { getModel().setIndeterminate(indeterminate); } public void setReadOnly(boolean readOnly) { getModel().setReadOnly(readOnly); } public String toString() { return this.item.toString(); } } And here is the function that sets the values: #Override public void setValue(List<T> value) { for (TreeSelectItem<T> tsi : this.treeSelectItems) { tsi.setSelected(value.contains(tsi.getItem())); } updateParentNodesCheckbox(); }
How to enable a dark theme by default, instead of toggle button?
I'm specifically looking at this site here: https://coin.dance/ In the upper left corner there is a dark/light theme toggle button, and I wanted to know how to enable something like this by default(dark style would be enabled before light). I've been looking through the index.html, and all I can see of interest is this snippet of javascript: <body class="dark"> <script type="text/javascript"> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); } function localStorageSave(key, value) { if (supportsLocalStorage()) { localStorage.setItem(key, JSON.stringify(value)); return true; } return false; } function localStorageLoad(key) { if (supportsLocalStorage()) { var value; try { value = JSON.parse(localStorage.getItem(key)); } catch (e) { return false; } if (value) { return value; } } return false; } function supportsLocalStorage() { try { if (typeof localStorage !== 'undefined') { try { localStorage.setItem('cd_ls_test', 'yes'); if (localStorage.getItem('cd_ls_test') === 'yes') { localStorage.removeItem('cd_ls_test'); return true; } else { return false; } } catch(e) { return false; } } } catch(e) { return false; } return false; } if (supportsLocalStorage()) { $('body').toggleClass('dark', localStorageLoad('dark')); } I'm interested because I like the overall theme of the site, and it's simplicity, but I wanted to know how it was done, and I cannot grasp where to start looking and editing.
You can easily do this with jquery just set a dark color background on your css by default and turn it on light color with button : $(".button").click(function(){ if ($(this).hasClass("clicked")){ $(".bg").css("background-color","black"); $(this).removeClass("clicked"); } else { $(".bg").css("background-color","white") $(this).addClass("clicked")} }); body{ margin:0px; } .bg{ height:100vh; width: 100%; background-color:black; } .button{ color:red; position:absolute; margin:0px; cursor:pointer; padding:20px; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="bg"> <p class="button">Dark-light</p> </div>