324 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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>a stamp of your own?</label>
 | ||
|             </dt>
 | ||
|             <dd>
 | ||
|             <input class=btn type="file" id="custompicture" />
 | ||
|             </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>
 | ||
|           </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>
 |