I am building a site about different picture frames and would like the end user to be able to upload an image file into a div that will then be displayed in the page? I have made a very basic fiddle:
http://jsfiddle.net/Margate/w8C5r/
The idea is that the user clicks on the upload image button and a window will open that will enable them to browse to the location of the file they want to upload to the page. They locate the file and select it. The picture then displays inside the div tag. Is this possible using Javascript?
Thank you very much for any help in advance.
<html>
<head>
<title>Upload Image Help!</title>
<style>
#addImage{position: absolute; top: 5px; left: 50px; width: 300px; height: 200px; border: 1px solid black;}
#button{position: absolute; top: 215px; left: 135px; width: 120px; height: 30px;}
</style>
</head>
<body>
<div id="addImage"></div>
<button id="button" type="button">Upload Image</button>
</body>
</html>
This is a hard question to answer, but the "correct" answer is "no, this cannot be natively done with just html, css, and js". The reason is because you cannot point to a local file via html tags for security reasons. The only choice you have is to actually have the JS upload the file to the server via an AJAX call, and then display the temporary uploaded file in the div itself.
i know this an old post but this is one way to do it.
started here...
https://www.w3schools.com/jsref/prop_fileupload_files.asp
ended here...
https://jsfiddle.net/trentHarlem/q6zutLjv/11/
uses only html css js
HTML
```<div id='input-container'>
<input type="file" id="fileElem" multiple accept="image/*">
<div id="fileList"></div>
</div>
<div id="image-container"></div>
<div id="image-container2"></div>```
CSS
#image-container {
height: 400px;
width: 400px;
background-size: 150%;
}
Javascript
const fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem"),
fileList = document.getElementById("fileList");
fileSelect.addEventListener("click", function(e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault();
}, false);
fileElem.addEventListener("change", handleFiles, false);
function handleFiles() {
if (!this.files.length) {} else {
const list = document.createElement("ul");
fileList.appendChild(list);
for (let i = 0; i < this.files.length; i++) {
const li = document.createElement("li");
list.appendChild(li);
const imgContainer = document.getElementById("image-container")
const imgContainer2 = document.getElementById("image-container2")
const img = document.createElement("img");
img.src = URL.createObjectURL(this.files[i]);
// for CSS Background-image
imgContainer.style.backgroundImage = `url("${img.src}")`;
// for HTML src
imgContainer2.innerHTML = `<img width='400px' height='auto'
src='${img.src}'/>`;
// hide input after file selected
fileElem.addEventListener("click", hide());
function hide() {
document.getElementById('input-container').style.display = 'none';
}
}
}
}
this needs some tightening up and a local storage mod but it works on safari brave firefox and chrome as of this post
Related
I have a file uploader that handles multiple files which all works as intended.
The previews of the files to be uploaded are place inside a container in the upload form. When I move this element to a different part of the form (or outside of the form) the uploader doesn't work? I would ideally like the preview container that holds the images to be below the submit button (either inside or outside of the form).
I cannot for the life of me work out why this is happening. The element itself is empty prior to the image previews populating it, and I don't think the issue is being caused by the javascript (although happy to take guidance on this).
The element in question is this one:
<div id="show-selected-images"></div>
It currently sits in the middle of the form between the drop zone and the (hidden) file input element and a visible submit button, but as mentioned I would like to move it below the submit button.
NOTE: I've included the JS so the uploader works, but I suspect the JS may not be the issue.
Codepen: https://codepen.io/pauljohnknight/pen/xxdrvmR
// Query all needed elements in one go
const [dropZone, showSelectedImages, fileUploader] = document.querySelectorAll(
"#standard-upload-files, #drop-zone, #show-selected-images"
);
dropZone.addEventListener("click", (evt) => {
// assigns the dropzone to the hidden input element so when you click 'select files' it brings up a file picker window
fileUploader.click();
});
// Prevent browser default when draging over
dropZone.addEventListener("dragover", (evt) => {
evt.preventDefault();
});
fileUploader.addEventListener("change", (evt) => {
// Clear the already selected images
showSelectedImages.innerHTML = "";
// this function is further down but declared here and shows a thumbnail of the image
[...fileUploader.files].forEach(updateThumbnail);
});
dropZone.addEventListener("drop", (evt) => {
evt.preventDefault();
// Clear the already selected images
showSelectedImages.innerHTML = "";
// assign dropped files to the hidden input element
if (evt.dataTransfer.files.length) {
fileUploader.files = evt.dataTransfer.files;
}
// function is declared here but written further down
[...evt.dataTransfer.files].forEach(updateThumbnail);
});
// updateThumbnail function that needs to be able to handle multiple files
function updateThumbnail(file) {
if (file.type.startsWith("image/")) {
const thumbnailElement = new Image();
thumbnailElement.classList.add("drop-zone__thumb");
thumbnailElement.src = URL.createObjectURL(file);
showSelectedImages.append(thumbnailElement);
}
} // end of 'updateThumbnail' function
body {
margin: 0;
display: flex;
justify-content: center;
width: 100%;
}
form {
width: 30%;
}
#drop-zone {
border: 1px dashed;
width: 100%;
padding: 1rem;
margin-bottom: 1rem;
}
.select-files {
text-decoration: underline;
cursor: pointer;
}
/* image that is previewed prior to form submission*/
.drop-zone__thumb {
width: 200px;
height: auto;
display: block;
}
#submit-images {
margin-top: 1rem;
}
<form id="upload-images-form" enctype="multipart/form-data" method="post">
<h1>Upload Your Images</h1>
<div id="drop-zone" class="drop-zone">
<p class="td text-center">DRAG AND DROP IMAGES HERE</p>
<p>Or</p>
<p class="select-files">Select Files</p>
</div>
<!-- below is the element that has the issue when moved -->
<div id="show-selected-images"></div>
<div class="inner-input-wrapper">
<div class="upload-label-wrapper">
<input id="standard-upload-files" style="display:none" type="file" name="standard-upload-files[]" multiple>
</div>
<input type="submit" name="submit-images" id="submit-images" value="SUBMIT IMAGES">
</div>
</form>
I think this part causes the issue:
// Query all needed elements in one go
const [dropZone, showSelectedImages, fileUploader] = document.querySelectorAll(
"#standard-upload-files, #drop-zone, #show-selected-images"
);
It is very bad practice to query elements like that, because then you cannot change their order inside html without changing elements inside destructured array. In your case you are moving previews in the end and now your showSelectedImages variable is actually uploader and fileUploader is now div which holds previews, and everything messes up.
You need to query them one by one:
const fileUploader = document.getElementById('standard-upload-files');
const dropZone = document.getElementById('drop-zone');
const showSelectedImages = document.getElementById('show-selected-images');
I've got an image on the page (I'll call it the background image) and I've allowed the user to enter some text that is positioned via css over the background image. As well, there are a few other small images that will be automatically position over the background image using css based on the text.
I want to turn what the user setup/created into an actual downloadable image now, essentially "flattening the layers" in photo editing terms.
I'd also ideally like to do this at a very high resolution as the original background image exists in a much larger and higher resolution format than the one the people see when editing.
I'm not sure the best way to do this. I'd be using NodeJS and Lambdas.
One solution I think would be to perhaps have another page exist with the full size background image and have the css reposition and resize everything perfectly and take a screenshot with puppeteer or something, although I don't know if that'll lose the quality of the original image somehow?
Or do I size the overlayed text and images correctly for the background and take screenshots of each of them, somehow add transparency, and then somehow merge the pictures?
Is there a way easier thing I'm missing or some package that can help?
If you create an element which has the full-size image, overlay the users' text and any other required image - both suitably scaled up in size and position, you can save that element on a canvas and then convert that to an image.
Here is some code to give the idea. It's using html2canvas but actually you could just create the canvas and draw the images and write the text to it without needing a library if preferred. (The code runs from my server and on my laptop and on https://codepen.io/rgspaces/pen/RwoNxVQ but does not run in a SO snippet - ??a CORS problem with iframe inside snippet system??).
<head>
<script src="https://ahweb.org.uk/html2canvas.js"></script>
<style>
body {
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
--t: 20px; /* distance from top of the user's text in the workspace */
--l: 20px; /* distance from left of the user's text */
--f: 30px; /* fontsize of the user's text in the workspace */
}
#big {
position: absolute;
left: 100vw;
display: none;
width: auto;
height: auto;
}
#workspace {
width: 50vw;
height: auto;
}
#workspace .mainimg {
width: 100%;
height: auto;
}
#workspace .text, #big .text {
position: absolute;
color: white;
}
#workspace .text {
top: var(--t);
left: var(--l);
font-size: var(--f);
}
</style>
</head>
<body>
<div id="big">
<img id="bigimg" src="https://picsum.photos/id/1016/3844/2563.jpg" class="mainimg" crossOrigin = "anonymous">
<div class="text"></div>
</div>
<div id="workspace">
<img src="https://picsum.photos/id/1016/3844/2563.jpg" class="mainimg">
<div class="text">User's text</div>
<!-- other imgs -->
</div>
<p>YOUR IMAGE WILL APPEAR BELOW - RIGHT CLICK TO SAVE IT TO FILE (WINDOWS); PRESS TO SAVE TO PHOTOS (IOS)</p>
<img id="resultimg" style="clear:both;" src=""/>
<script>
function start() {
let big = document.getElementById('big');
let bigImg = document.getElementById('bigimg');
let bigText = document.querySelector('#big .text');
let width = bigimg.width;
let height = bigimg.height;
let workspace = document.getElementById('workspace');
let workspaceText = document.querySelector('#workspace .text');
let props = window.getComputedStyle(workspace, null);
let scaling = width/props.getPropertyValue("width").replace('px','');
bigText.innerHTML = workspaceText.innerHTML;
// just some simple scaling to give an idea for now
bigText.style.fontSize = 'calc(var(--f) * ' + scaling + ')';
bigText.style.top = 'calc(var(--t) * ' + scaling + ')';
bigText.style.left = 'calc(var(--l) * ' + scaling + ')';
big.style.display = 'inline-block';
window.scrollTo(0, 0);
html2canvas(big, {allowTaint: true, useCORS: true, logging: true, width: width, height: height})
.then((canvas) => {
big.style.display = 'none';
document.body.style.overflow = 'visible';
const imgData = canvas.toDataURL('image/png', 1);
const resultImg = document.getElementById('resultimg')
resultImg.src = imgData;
resultImg.style.width = width + 'px';
resultImg.style.height = 'auto';
});
}
window.onload = start;
</script>
</body>
</html>
100% stuck on a homework assignment...
I have some simple JavaScript with the intent of changing the background image and text of a div upon mouseover over certain images. However, what I am trying to execute now is to revert the div back to its original state upon mouseout.
I am able to revert the divs background color with
document.getElementById('image').style.backgroundImage = "";
Essentially killing the background image and forcing it to revert to the background color that is there upon page load.
Now what I'm trying to do is store the original innerHTML text "Hover over an image below to display here." as a variable
var originalText = document.getElementById('image').innerHTML;
and then call it back when I need it.
function unDo() {
document.getElementById('image').style.backgroundImage = "";
document.getElementById('image').innerHTML = originalText;
however,
var originalText = document.getElementById('image').innerHTML;
is returning "undefined", which means I've goofed up somehow when storing the variable, right? I've tried innerText as well and that doesn't seem to do much for me. Below is the full HTML and JavaScript below.
/*Name this external file gallery.js*/
var originalText = document.getElementById('image').innerHTML;
function upDate(previewPic) {
document.getElementById('image').innerHTML = previewPic.alt;
document.getElementById('image').style.backgroundImage = "url('" + previewPic.src + "')";
/* In this function you should
1) change the url for the background image of the div with the id = "image"
to the source file of the preview image
2) Change the text of the div with the id = "image"
to the alt text of the preview image
*/
}
function unDo() {
document.getElementById('image').style.backgroundImage = "";
document.getElementById('image').innerHTML = originalText;
/* In this function you should
1) Update the url for the background image of the div with the id = "image"
back to the orginal-image. You can use the css code to see what that original URL was
2) Change the text of the div with the id = "image"
back to the original text. You can use the html code to see what that original text was
*/
}
body {
margin: 2%;
border: 1px solid black;
background-color: #b3b3b3;
}
#image {
line-height: 650px;
width: 575px;
height: 650px;
border: 5px solid black;
margin: 0 auto;
background-color: #8e68ff;
background-image: url('');
background-repeat: no-repeat;
color: #FFFFFF;
text-align: center;
background-size: 100%;
margin-bottom: 25px;
font-size: 150%;
}
.preview {
width: 10%;
margin-left: 17%;
border: 10px solid black;
}
img {
width: 95%;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Photo Gallery</title>
<link rel="stylesheet" href="css/gallery.css">
<script src="js/gallery.js"></script>
</head>
<body>
<div id="image">
Hover over an image below to display here.
</div>
<img class="preview" alt="Styling with a Bandana" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/389177/bacon.jpg" onmouseover="upDate(this)" onmouseout="unDo()">
<img class="preview" alt="With My Boy" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/389177/bacon2.JPG" onmouseover="upDate(this)" onmouseout="unDo()">
<img class="preview" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/389177/bacon3.jpg" alt="Young Puppy" onmouseover="upDate(this)" onmouseout="unDo()">
</body>
</html>
note: I'm not allowed to change the HTML for this assignment. Only the JavaScript. You do NOT have to do my homework for me. However, a hint in the right direction would be nice.
screenshotoflocalenvironment
Seems like this could be happening because your script tag in your html is above the body.
When you declare the "original text" variable at the beginning of your script, the page hasn't loaded yet, and so it comes back undefined, because it can't find anything in the document with an "image" class.
Sometimes it loads quick enough maybe, other times it doesn't
Instead, move your script tag in your html to right below the body tag. So the script loads after the body has loaded. Should fix it.
**additional tip.
Store your element (i.e: the "image") in a variable instead of calling getElementbyId multiple times. Every time you do this javaScript searches the entire DOM which is resource intensive in bigger applications and can get pretty slow. Just a pet peeve of mine.
First save the background color in a variable :
z = document.getElementById("mydiv").style.backgroundColor;
Then on mouse out, restore this color :
document.getElementById("mydiv").style.backgroundColor = z;
It works for me. My full code is :
` <script>
var z;
$( document ).ready(function() {
document.getElementById("mydiv").onmouseover = function() {mouseOver()};
document.getElementById("mydiv").onmouseout = function() {mouseOut()};
});
function mouseOver() {
z = document.getElementById("mydiv").style.backgroundColor;
document.getElementById("mydiv").style.backgroundImage = "url('londoneye.jpg')";
}
function mouseOut() {
document.getElementById("mydiv").style.backgroundImage = "";
document.getElementById("mydiv").style.backgroundColor = z;
}
</script>`
The html is :
<div id="mydiv" style="width:400px; height:400px; background-color:yellow;margin-left:50px; margin-top:50px;">
I have created an html5 banners and validated it here:
https://h5validator.appspot.com/dcm.
It returns the error: "Missing click tag check".
How do I implement a clickTag? I've found this code on google support:
<html>
<head>
<meta name="ad.size" content="width=300,height=250">
<script type="text/javascript">
var clickTag = "http://www.google.com";
</script>
</head>
<body>
<a href="javascript:window.open(window.clickTag)">
<img src="images/dclk.png" border=0>
</a>
</body>
</html>
But isn't the destination URL of the banner set after uploading the ZIP file in DoubleClick?
Do I have to set the destination URL hardcoded in the HTML? Doesn't make any sense to me..
I have made a lot of flash banners in the past and there you only referred to a variable _root.clickTag.
Can anyone help me out?
Thanks
In order to create a doubleclick studio banner you need to import doubleclick studio library and initialize enabler. Then set Exit_url. Save yourself all the trouble create the Banner in Google Web Designer its easy and will upload directly to DC studio
<script src="https://s0.2mdn.net/ads/studio/Enabler.js"></script>
<style>html, body {width: 100%; height: 100%}
#bg-exit {
background-color: rgba(255,255,255,0);
cursor: pointer;
height: 381px; //banner height
left: 0px;
position: absolute;
top: 19px;
width: 400px; //banner width
z-index: 1;
}</style>
<div id="bg-exit"></div> <!-- put this div inside your main container of banner -->
<script>
window.onload = function() {
if (Enabler.isInitialized()) {
enablerInitHandler();
} else {
Enabler.addEventListener(studio.events.StudioEvent.INIT, enablerInitHandler);
}
}
function enablerInitHandler() {
}
function bgExitHandler(e) {
Enabler.exit('Background Exit');
}
document.getElementById('bg-exit').addEventListener('click', bgExitHandler, false);
</script>
Using this code you can change the exit_url from DC studio Dynamically
I need your help.
I would like to design a javascript function, such that when I call it, it will open up a dialog box asking me to navigate to the selected file, once I click on the "open" button, it will then save the file's path into a var.
How do you do this? I would NOT like to the input type="file" method, as I dont require that particular input to be on my page.
ie:
function getlocation() {
var x = popup the open file dialog box and let the user select a file
}
The only way to allow the user to select a file is to use an <input type="file" />1. You don't have to have this element visible, just on the page.
When a user selects a file, all you can get from it is its name. You cannot get its path. Also, note that file upload elements are asynchronous. You need to use the onchange event (callback) to get the name.
You can hide the upload element using display: none, and then just have another JavaScript function programmatically trigger it. (NOTE: This method doesn't work in Opera, and possibly other browsers. It was tested in Chrome, Firefox, and IE 8/9)
<style>
#getFile{
display: none;
}
</style>
<input type="file" id="getFile" />
<button id="openFile" type="button">Click Me</button>
<script>
var uploadElement = document.getElementById('getFile'),
uploadTrigger = document.getElementById('openFile'),
openFileUpload = function(){
uploadElement.click();
},
alertValue = function () {
alert(uploadElement.value);
};
if (window.addEventListener) {
uploadTrigger.addEventListener('click', openFileUpload);
uploadElement.addEventListener('change', alertValue);
} else {
uploadTrigger.attachEvent('onclick', openFileUpload);
uploadElement.attachEvent('onchange', alertValue);
}
</script>
DEMO: http://jsfiddle.net/rJA7n/3/show (Edit it at: http://jsfiddle.net/rJA7n/3/)
Another method that should work in most browsers (including Opera) is to make the file upload element "invisible" and put an element on top of it. So, when you click on what you think is a button, you're really clicking on the upload element. AJAX uploaders (like http://fineuploader.com/) use this method to allow you to "style" upload buttons.
<style>
#getFile{
width: 100px;
opacity: 0;
filter: alpha(opacity = 0);
}
#openFile{
display: inline;
margin-left: -100px;
background-color: red;
height: 30px;
width: 100px;
padding: 10px;
color: white;
text-align: center;
}
</style>
<input type="file" id="getFile" />
<div id="openFile">Click Me</div>
<script>
var uploadElement = document.getElementById('getFile'),
alertValue = function(){
alert(uploadElement.value);
};
if(window.addEventListener){
uploadElement.addEventListener('change', alertValue);
}
else{
uploadElement.attachEvent('onchange', alertValue);
}
</script>
DEMO: http://jsfiddle.net/cKGft/4/show/ (Edit it at: http://jsfiddle.net/cKGft/4/)
1 Well, you can use drag and drop if you want to be really fancy. I made a quick demo of that here: http://jsfiddle.net/S6BY8/2/show (edit it at: http://jsfiddle.net/S6BY8/2/)