ImageGenerator/public/index.php

323 lines
9.4 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// Yay! Welcome to the wonderful world of Ugly PHP In Headers!
// Build the stamp images list
$stampsSelect="<option>soulless feelings</option>";
$stampsImgList=scandir("../stamps");
foreach( $stampsImgList as $file ){
if( strpos( "$file", ".") != 0 ){
$name = ucwords(str_replace("_", " ",substr($file,0,-4)));
$stampsSelect .= "<option value='../stamps/".urlencode($file)."'>$name</option>";
}
}
// Build the background images list
$bgdImgList = scandir("../synthesis");
$randomKeys = array_rand( $bgdImgList , 13 );
$bgdSelect="<option value=''>the beauty is in your eyes</option>";
foreach( $randomKeys as $key ){
$file = $bgdImgList[ $key ];
if( strpos( "$file", ".") != 0 ){
$key = substr( $file, 11, -4 );
$bgdArr[$key] ="../synthesis/".urlencode($file);
}
}
uksort( $bgdArr, "strnatcasecmp");
$init_key = array_keys($bgdArr)[count($bgdArr)-1];
$first = array( $init_key => $bgdArr [ $init_key ] );
foreach( $bgdArr as $key => $val ){
$bgdSelect .= "<option value='$val'>$key</option>";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Make your own flyer</title>
<style>
/* YUI 3.5.0 reset.css (http://developer.yahoo.com/yui/3/cssreset/) - https://cssreset.com/ */
html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{*font-size:100%}legend{color:#000}#yui3-css-stamp.cssreset{display:none}
body {
font-size: 32px;
font-family: monospace;
}
* {
font-size: 32px;
color: #222;
}
#container{
display:grid;
position: relative;
grid-template-areas:
"title"
"drawingArea" "menu" ;
}
#menu{
grid-area: menu;
}
#canvas{
grid-area: drawingArea;
}
#title{
font-size: 1.6em;
grid-area: title;
color:red;
}
dd{
margin:32px;
}
#canvas{
user-select: none;
cursor: default;
}
.btn{
text-decoration: none;
border: 1px solid #eee;
padding: 8px 16px;
border-radius: 24px;
color: inherit;
background: #ddd;
}
@media (min-width: 1200px) {
#container{
grid-template-areas:
"title"
"drawingArea"
"menu";
}
#canvas{
position: absolute;
right: 10px;
top: 0px;
}
#menu {
position: absolute;
left: 10px;
top: 48px;
}
}
</style>
</head>
<body>
<div id="container">
<h1 id="title">Your #HSF2020 flyer </h1>
<div id="canvas">
<div id="drawingArea" class="drawing-area">
<div class="canvas-container">
<canvas id="composition-canvas" width="200" height="400"></canvas>
</div>
</div>
</div>
<div id="menu">
<dl>
<dt>
<label for="background-image">pick a word</label>
</dt>
<dd>
<select class=btn id="background-image">
<?= $bgdSelect ?>
</select>
</dd>
<dt>
<label for="stamps">stamp it</label>
</dt>
<dd>
<select class=btn id="stamps">
<?= $stampsSelect ?>
</select>
</dd>
<!--
<dt>
<label>now shine</label>
</dt>
<dd>
<a id="lnkDownload" class=btn href="#">Save image</a>
</dd>
-->
<dt>get it on A4</dt>
<dd>
<form id="montage" action="montage.php" method="POST">
<select class=btn name="horizontal">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<select class=btn name="vertical">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<br>
<select class=btn name="landscape">
<option value="0">portrait</option>
<option value="1">paysage</option>
</select>
<br>
<button class=btn type="submit">build</button>
</form>
</dd>
<dt>
<label>a stamp of your own?</label>
</dt>
<dd>
<input class=btn type="file" id="custompicture" />
</dd>
</dl>
</div>
</div>
<script src="./jquery.js"></script>
<script src="./jq-ajax-progress.js"></script>
<script src="./fabric.js"></script>
<script>
let canvas = new fabric.Canvas('composition-canvas');
function updateCanvas(imageURL){
fabric.Image.fromURL(imageURL, function(img) {
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
});
}
bgImage="";
function updateCanvasBg( imageURL){
var img=fabric.Image.fromURL( imageURL, function(img){
canvas.setWidth(img.getScaledWidth())
canvas.setHeight(img.getScaledHeight())
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
// Optionally add an opacity lvl to the image
// backgroundImageOpacity: 0.5,
// should the image be resized to fit the container?
backgroundImageStretch: false
});
bgImage=imageURL.split(/(\\|\/)/g).pop()
})
}
updateCanvasBg( '<?= current( $first ) ?>');
// Update the background according to the select
document.getElementById("background-image").addEventListener("change", function(){
if( "" === this.value ) return
updateCanvasBg( this.value)
}, false);
// Add stamps according to the select
document.getElementById("stamps").addEventListener("change", function(){
updateCanvas(this.value);
}, false);
// When the user clicks on upload a custom picture
document.getElementById('custompicture').addEventListener("change", function(e){
var reader = new FileReader();
reader.onload = function (event){
var imgObj = new Image();
imgObj.src = event.target.result;
// When the picture loads, create the image in Fabric.js
imgObj.onload = function () {
var img = new fabric.Image(imgObj);
img.scaleToHeight(300);
img.scaleToWidth(300);
canvas.centerObject(img);
canvas.add(img);
canvas.renderAll();
};
};
// If the user selected a picture, load it
if(e.target.files[0]){
reader.readAsDataURL(e.target.files[0]);
}
}, false);
// When the user selects a picture that has been added and press the DEL key
// The object will be removed !
document.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;
if(keyCode == 46){
console.log("Removing selected element on Fabric.js on DELETE key !");
canvas.remove(canvas.getActiveObject());
}
}, false);
/*
// Export the image
function saveImage(e) {
this.href = canvas.toDataURL({
format: 'jpeg',
quality: 0.8
});
this.download = bgImage+'.png'
}
var imageSaver = document.getElementById('lnkDownload');
imageSaver.addEventListener('click', saveImage, false);
*/
// Handles AJAX queries to A4 production process
$( "#montage" ).on("submit",function(e){
var dataURL = canvas.toDataURL();
var div = $("<div class=progress>Upload: <span id=counter></span>%</div>")
$(this).append(div)
var data = {}
$.each( $(this).serializeArray(), function( k,v ){
data[v["name"]] = v["value"]
})
data["img"] = dataURL
data["bgImage"] = bgImage
e.preventDefault()
// Call the montage URL to build the PDF
  $.ajax({
   type: "POST",
uploadProgress: function(e) {
// track uploading
if (e.lengthComputable) {
var completedPercentage = Math.round((e.loaded * 100) / e.total);
if( completedPercentage != 100 ){
div.find("#counter").text( completedPercentage)
}else{
div.text("Building...");
}
}
},
success : function(url,msg,xhr){
div.html( "<a href="+url+" target=_blank>Download "+data["horizontal"]+"x"+data["vertical"]+"</a>")       
},
error: function( data, msg, xhr){
console.log( data)
div.html( "<span class=error>Oops... An error occured.")
},
    url: "montage.php",
    data: data     
  });
})
</script>
</body>
</html>