User-uploaded image as game background - javascript

I'm trying fix this game for a friend (so I don't exactly know what all his code is doing). What I want to do is take an image uploaded by the user and set it as the background permanently even after closing app. Here's what I have right now:
The assets are loaded here:
game.stage.backgroundColor = '#000000';
game.load.image('GameFrame.png', 'assets/GameFrame.png');
game.load.image('game_frame', 'assets/GameFrame.png');
The default image "game_frame" is set here:
create: function()
{
this.frameGroup = game.add.group();
this.game_frame_background = game.add.sprite(0, 0,
'game_frame_background');
this.frameGroup.add(this.game_frame_background);
this.frameGroup.add(this.wordGroup);
this.game_frame = game.add.sprite(0, 0, 'game_frame');
this.frameGroup.add(this.game_frame);
this.frameGroup.x = GAME_WIDTH / 2 - this.game_frame.width / 2;
this.frameGroup.y = GAME_HEIGHT / 2 - this.game_frame.height / 2;
}
Lastly, I put the file input js in the HTML file:
<body>
<div id="gameDiv">
<button onclick="document.getElementById('file-input').click();">Change Background</button>
<input id="file-input" type="file" name="name" style="display: none;"/>
</div>
</body>
This is where I'm stuck. I think I need to either change the name of the user's image to "GameFrame.png" OR I need to load the user's image as an asset replacing "assets/GameFrame.png" asset. But I don't know how to do either of these things.

Related

JS: Function works manually in console but not executed automatically in code

I copied this code snippet from here: https://codepen.io/duketeam/pen/ALEByA
This code is supposed to load a picture and make it grayscale after clicking on the button.
I want to change the code such that the picture comes out immediately as grayscale without having to click on the button, hence why I commented it out and included makeGray() in the onload part of the <input...>. But this doesnt work. Where am I going wrong here?
I have tried to leave out the makeGray()and just upload the picture and type makeGray() in the console and it does its job perfectly fine, but I need it to execute automatically. I also tried to just put all the code from the makeGray() function in the upload() function but also here it won't trigger.
var image = null;
function upload() {
//Get input from file input
var fileinput = document.getElementById("finput");
//Make new SimpleImage from file input
image = new SimpleImage(fileinput);
//Get canvas
var canvas = document.getElementById("can");
//Draw image on canvas
image.drawTo(canvas);
}
function makeGray() {
//change all pixels of image to gray
for (var pixel of image.values()) {
var avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;
pixel.setRed(avg);
pixel.setGreen(avg);
pixel.setBlue(avg);
}
//display new image
var canvas = document.getElementById("can");
image.drawTo(canvas);
}
<script src="https://www.dukelearntoprogram.com/course1/common/js/image/SimpleImage.js">
</script>
<h1>Convert Image to Grayscale</h1>
<canvas id="can"></canvas>
<p>
<input type="file" multiple="false" accept="image/*" id="finput" onchange="upload();makeGray()">
</p>
<p>
<!---- <input type="button" value="Make Grayscale" onclick="makeGray()" -->
</p>
<script src="./index.js"></script>
There's something you need to wait for, but I'm not sure exactly what it is. If you wrap the function in a setTimeout, it works fine. You might want to wait for a few more milliseconds for clients with slower systems or bigger files. If you ever figure out what is taking a while to do, you can instead use .then or await just to be safe.
var image = null;
function upload() {
//Get input from file input
var fileinput = document.getElementById("finput");
//Make new SimpleImage from file input
image = new SimpleImage(fileinput);
//Get canvas
var canvas = document.getElementById("can");
setTimeout(() => {
//change all pixels of image to gray
for (var pixel of image.values()) {
var avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;
pixel.setRed(avg);
pixel.setGreen(avg);
pixel.setBlue(avg);
}
image.drawTo(canvas);
}, 100);
}
<script src="https://www.dukelearntoprogram.com/course1/common/js/image/SimpleImage.js">
</script>
<h1>Convert Image to Grayscale</h1>
<canvas id="can"></canvas>
<p>
<input type="file" multiple="false" accept="image/*" id="finput" onchange="upload();">
</p>
<script src="./index.js"></script>

Connecting the HTML input page with p5.js

I want to get the data from input tags and use them in the equation.
I have tried a lot a lot of solutions, nothing worked.
I want it to start setup after click one button, and start animate after pressing the other button.
press button1
load the data from the html
set up the canvas using those data
execute draw() for ever.
I did not find much documentation.
Here is my html:
<label class="col-lg-2" for="n4" id="m2">mass sq 2</label>
<input class=" col-lg-2" name="n4" type="number" id="m2" label="mass sq 2" />
<label class="col-lg-2" for="n5" id="r">Ratio</label>
<input class="ana col-lg-2" name="n5" type="number" id="r" label="Ratio" />
<button class="col-lg-2 btn btn-danger" style="margin-left: 10%;
height:30px;"> <h3> change </h3> </button>
and here is the p5.js code:
button1 = CreateButton('submit1');
button2 = CreateButton('submit2');
let digits = document.getElementById('m2').Value;
const timeSteps = 10 ** (digits - 1);
let m1 = document.getElementById('m1').Value;
function preload() {
blockImg = loadImage('block.png');
clack = loadSound('clack.wav');
}
function setup() {
button2.mousePressed(start);
}
function draw() {
button2.mousePressed(finish);
}
function start() {
createCanvas(windowWidth, 200);
block1 = new Block(100, 20, m1, 0, 0);
const m2 = pow(100, digits - 1);
block2 = new Block(300, 100, m2, -1 / timeSteps, 20);
countDiv = createDiv(count);
countDiv.style('font-size', '72pt');
}
This answer uses instance mode to create a canvas with width and height set from user inputs. This allows us to call createCanvas() inside of setup. The code only allows us to create one canvas but it would not be hard to modify so that multiply canvases could be created, however, we should never call createCanvas more than once for each instance of p5.
var canvas = null;
function createP5 (){
let canvasWidth = document.getElementById("widthInput").value;
let canvasHeight = document.getElementById("heightInput").value;
if (canvas === null){
canvas = new p5(function (p) {
p.setup = function (){
p.createCanvas(canvasWidth, canvasHeight);
}
p.draw = function(){
p.background(55);
p.stroke(0);
p.rect(p.width/5, p.height/5, p.width/5 * 3, p.height/5 * 3);
}
}, "canvas-div");
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
<div id="canvas-div">
</div>
<input type="button" value="create canvas" onclick='createP5()'/>
<textarea id="widthInput"></textarea>
<textarea id="heightInput"></textarea>
You're asking a few different questions:
How do I run code when a user presses a button?
There are a few ways to do this, but it sounds like you're looking for the onclick attribute. You can Google "JavaScript onclick" for a ton of resources.
How do I run a P5.js sketch from JavaScript code?
For this, you probably want to use instance mode to have more control over exactly when the sketch is created. See this page for more info.
The best advice I can give you is to start smaller. Start with a simple page that shows a single button that prints something to the console when you click it. Then add a simple P5.js sketch using instance mode. Work forward in small steps instead of trying to do everything all at once.
Good luck.

How do I make my submit button display the uploaded file without leaving the current pagte

my code is n not working and I am sure its because the code is not
correct.I would like to get the submit button to display a picture of a
molecule using JSmol. Any help!??
<script>
var Info = {
width: 550,
height: 550,
serverURL: "http://chemapps.stolaf.edu/jmol/jsmol/jsmol.php ",
use: "HTML5 WEBGL JAVA",
j2sPath: "jsmol/j2s",
script: "load 1BNA.pdb; set spin x 15; set spin y 15; set spin z 15; spin on;
wireframe on; spacefill off",
console: "jmolApplet0_infodiv"
}
</script>
<form>
Select a file: <input type="file" name="usr_file" required>
<input type="submit" onclick="myFunction(Info)">
</form>
<p id="upload"></p>
<script>
function myFunction() {
var x = document.getElementById("Info").required;
document.getElementById("upload").innerHTML = x;
}
</script>
I may my answer a little bit off but im using the same logic in my vuejs component.
in input change event im catching the event so i can get file(s) from it ( onFilesUpload function ).
then im creating image using FileReader ( createImage function ) then i push e.target.result to my images array. then you can set image result to <img src="image_path" />

I would like to merge all images within DIV and allow user to download (js powered)

I'm working on a client's web design and development powered by Wordpress and Woocommerce, the plugin is great but there's a few functions I wish it had. The main one is giving the ability for the user to save the preview of their configuration.
The plug-in is 'Woocommerce Visual Products Configurator':
It allows buyers to build their own item by selecting from a series of different attributes for different parts of an item. Ex, choosing different types of Soles for a shoe, as well as being able to choose from a series of laces for the same shoe.
My Issue: The configuration images are layered on top of each other as the user selects their options so any normal "save as" function will just save the top image.
I have succesfully managed to combine and save the images using html2canvas-Data URL() but the way it generates the screenshots means the quality becomes very poor.
My thoughts are to merge all the images within the "vpc-preview" DIV then force the download.
Hunting through the functions of the plugin I found this:
function merge_pictures($images, $path = false, $url = false) {
$tmp_dir = uniqid();
$upload_dir = wp_upload_dir();
$generation_path = $upload_dir["basedir"] . "/VPC";
$generation_url = $upload_dir["baseurl"] . "/VPC";
if (wp_mkdir_p($generation_path)) {
$output_file_path = $generation_path . "/$tmp_dir.png";
$output_file_url = $generation_url . "/$tmp_dir.png";
foreach ($images as $imgs) {
list($width, $height) = getimagesize($imgs);
$img = imagecreatefrompng($imgs);
imagealphablending($img, true);
imagesavealpha($img, true);
if (isset($output_img)) {
imagecopy($output_img, $img, 0, 0, 0, 0, 1000, 500);
} else {
$output_img = $img;
imagealphablending($output_img, true);
imagesavealpha($output_img, true);
imagecopymerge($output_img, $img, 10, 12, 0, 0, 0, 0, 100);
}
}
imagepng($output_img, $output_file_path);
imagedestroy($output_img);
if ($path)
return $output_file_path;
if ($url)
return $output_file_url;
} else
return false;
}
However the function isn't called anywhere. There's also a couple of "save" buttons that are commented out which makes me wonder if they removed from a previous build.
Ideally I'd like the user to be able to instantly share their creation to facebook but thought this would be a good start.
Any ideas would be greatly appreciated!
Thanks!
UPDATE:
I've managed to use the following code to output an alert of the url's of each of the config images. Useless for the user but at least I know it's targeting exactly what I need.
function img_find() {
var imgs = document.querySelectorAll('#vpc-preview img');
var imgSrcs = [];
for (var i = 0; i < imgs.length; i++) {
imgSrcs.push(imgs[i].src);
}
return alert(imgSrcs);
}
Any suggestions on how to manipulate this and merge the corresponding image of each URL then force the download?
Cick to see Fiddle
UPDATE 2: The following fiddle lets users upload images and then merges them into a single photo for download. Unfortunately my coding skills aren't good enough to manipulate this into using the SRC urls of images within certain DIV and to Merge all the photos on top of each other.
Fiddle
function addToCanvas(img) {
// resize canvas to fit the image
// height should be the max width of the images added, since we rotate -90 degree
// width is just a sum of all images' height
canvas.height = max(lastHeight, img.width);
canvas.width = lastWidth + img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (lastImage) {
ctx.drawImage(lastImage, 0, canvas.height - lastImage.height);
}
ctx.rotate(270 * Math.PI / 180); // rotate the canvas to the specified degrees
ctx.drawImage(img, -canvas.height, lastWidth);
lastImage = new Image();
lastImage.src = canvas.toDataURL();
lastWidth += img.height;
lastHeight = canvas.height;
imagesLoaded += 1;
}
Based on this question/answer, I would take a look at node-canvas.
What I have done in the past is use a #print css file to only capture the divs needed. Very simple concept but works well.
After looking at your link, that is exactly the situations I use it in..online designers. It is a little more difficult keeping your layers responsively aligned, but in the end I feel your codes become cleaner and it works well across devices and OS'.
If you dont want PDF and a simple preview and download than html2image.js is perfect.
$(document).ready(function(){
var element = $("#html-content-holder"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
});
<script src="https://github.com/niklasvh/html2canvas/releases/download/0.4.1/html2canvas.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="html-content-holder" style="background-color: #F0F0F1; color: #00cc65; width: 500px;
padding-left: 25px; padding-top: 10px;">
Place any code here
</div>
<input id="btn-Preview-Image" type="button" value="Preview"/>
<a id="btn-Convert-Html2Image" href="#">Download</a>
<br/>
<h3>Preview :</h3>
<div id="previewImage">
</div>
For High quality you want to use rasterizeHTML.js
Found here:
https://github.com/cburgmer/rasterizeHTML.js/blob/master/examples/retina.html

Save canvas to image via toDataURL failed

I create a test code below and you can manipulate it on Jsfiddle:
http://jsfiddle.net/Stallman41/57hvX/31/
HTML:
<canvas id="test_canvas" style="background-color : #FFFF00" ; width="500px"
; height="340px"></canvas>
<br>
<button id="test_put_btn">Put an image</button>
<br>
<button id="save_dataURL">Save to dataURL</button>
<br>
<button id="draw_back">Final step: draw 3 images back.</button>
<br>
<img id="first_img"; width="100px" ; height="100px" ;></img>
<img id="second_img"; width="100px" ; height="100px" ></img>
<img id="third_img"; width="100px" ; height="100px" ;></img>
Javascript:
var drawing_plate;
var context;
var dataURL_arr = new Array();
$(document).ready(function () {
drawing_plate = document.getElementById("test_canvas");
context = drawing_plate.getContext('2d');
$("#test_canvas").bind("mousedown", Touch_Start);
$("#test_canvas").bind("mousemove", Touch_Move);
$("#test_canvas").bind("mouseup", Touch_End);
}); //document ready.
function Touch_Start(event) {
event.preventDefault();
touch = event;
touch_x = touch.pageX;
touch_y = touch.pageY;
line_start_x = touch.pageX - 0;
line_start_y = touch.pageY - 0;
context.beginPath();
context.moveTo(line_start_x, line_start_y);
}
function Touch_Move(event) {
event.preventDefault();
touch = event; //mouse
line_end_x = touch.pageX - 0;
line_end_y = touch.pageY - 0;
context.lineTo(line_end_x, line_end_y);
context.stroke();
}
$("#test_put_btn").click(function () {
var test_img = new Image();
test_img.src = "http://careerscdn.sstatic.net/careers/gethired/img/careers2- ad-header-so-crop.png";
context.drawImage(test_img, 0, 0);
});
$("#save_dataURL").click(function () {
dataURL_arr.push(drawing_plate.toDataURL("image/png"));
});
$("#draw_back").click(function () {
var f_image= $("#first_img")[0];
var s_image= $("#second_img")[0];
var t_image= $("#third_img")[0];
f_image.onload= function()
{
f_image.src= dataURL_arr[0];
}
f_image.src= dataURL_arr[0];
s_image.onload= function()
{
s_image.src= dataURL_arr[0];
}
s_image.src= dataURL_arr[0];
t_image.onload= function()
{
t_image.src= dataURL_arr[0];
}
t_image.src= dataURL_arr[0];
});
I develop a drawing plate on Android system, saving the drawings to a dataURL string. They can draw something on the canvas and put images on the canvas. And I need to let the users see their drawings on small icons.
I use canvas.toDataURL("image/png") to save the base64 string. And I choose <img> as the small icon container. However, what I got is only the drawings can be shown on the icon, and usually, when I write img.src= canvas.toDataURL("image/png"); the image shows nothing!
I investigate the issue for long time.
1. I think the problem might be the dataURL string is too long?
2. The support of the OS: Android?
The code in Jsfiddle here shows a similar procedure on my Android PhoneGap development.
First , you just draw something on the canvas, and press Press an image, and then Save to dataURL. But you should do the process three times. In this condition, the string array contains the base64 string generated by the drawings and the image.
In the final, you press Final step: draw 3 images back., nothing will be shown on the image icon.
In conclusion:
In my experience, as I write img.src= canvas.toDataURL("image/png"); (no matter the img is an dom element or var img = new Image();). It can't always work: sometimes it works... but sometimes not...(I work on Android 4.0.1, phonegap 1.7.0)
Second, especially if I store lots of base64 strings to an array, assigning them to lots of image DOM element, it definitely fails.
Third, if the user only draw something on the canvas, it can always work.( Except the example code in the Jsfiddle, but it works on my Android system...)
But if he draw an image context.drawImage(~) the image wouldn't show the pic.
Too much confusions...
I need to let the user can view their drawings in small icon, any alternative?
Some References:
1
2
3
I just stumbled across this question.
Click Put an image, then click Save to dataURL, then check your JavaScript console for something like:
SecurityError: DOM Exception 18
It's a browser security feature. Because you've inserted an image from a different domain, it counts as a cross-origin request.
If you eliminate the security error, you can export the canvas to a data URL.
Another thing in your code.
The image you try to draw onto the canvas into your test_put_btn onclick event handler, your image will never show up (or it will sometimes work accidentally) because you don't wait for your image to be loaded to draw it onto the canvas.
You have to handle the "onload" event of your image and draw it into the handler to permit the drawing of your image.
Before your test_img.src statement, you have to put :
test_img.onload = function()
{
context.drawImage(test_img, 0, 0);
};
Plus, the image you try to access is not accessible --> For me it does not work

Categories

Resources