Creating Greeting Card Maker WebApp with Phaser

Phaser.js is a good library for creating HTML5 games.

However, this time I tried to use Phaser to make a greeting card maker web app.

Visit CardU a webapp that I’ve made recently. You can test it and see how it works.

Here I will share the source code of index.html and main.js files used in this web app:

index.html codes:

<html>
	<head>
		<title>CardU</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
		<meta name="description" content="CardU is an online web application to create greeting cards based on HTML5, JavaScript and Phaser library.">
        <meta name="keywords" content="HTML, Canvas, Phaser, Image Editing, Greeting Card">
		<link rel="stylesheet" type="text/css" href="css/font-awesome.css">
		<script src="phaser.js"></script>
		<script src="jquery.js"></script>

		<style>
			@font-face {
				font-family: gameFont;
				src: url(assets/Actor-Regular.ttf);
			}
			body{
				font-family: gameFont;
				margin: 0px;
				user-select: none;
				background-color: #535353;
				font-size: 12px;
			}
			h1, h2, h3, h4, h5, p{
				margin: 0;
				margin-bottom: 10px;
			}
			#ui{
				position: fixed;
				top: 0;
				left: 0;
				bottom: 0;
				width: 70%;
				background-color: black;
				padding-top: 70px;
				padding-bottom: 70px;
				color: white;
				display: none;
				overflow: auto;
				border-right: 1px solid white;
				font-size: 16px;
			}
			#ui div{
				margin-bottom: 10px;
			}
			#menubar{
				position: fixed;
				top: 0;
				left: 0;
				margin: 10px;
				background-color: rgba(0, 0, 0, .5);
				padding: 10px;
				color: white;
				display: none;
			}
			.imglist{
				display: inline;
				margin: 5px;
				vertical-align: top;
			}
			#controller-left{
				display: none;
				position: fixed;
				left: 0;
				bottom: 0;
			}
			#controller-right{
				display: none;
				position: fixed;
				right: 0;
				bottom: 0;
			}
			textarea, button{
				box-sizing: border-box;
				width: 100%;
				outline: none;
				margin-bottom: 10px;
			}
			button{
				color: black;
				background-color: white;
				border: none;
				padding: 10px;
			}
		</style>
	</head>
	<body>
		<div id="pgame"></div>
		<a style="background-color: rgba(0, 0, 0, .5); color: white; padding: 10px; margin: 10px; position: fixed; top: 0; right: 0; display: none;" id="btnsaveimage"><i class="fa fa-download"></i></a>
		<div id="controller-right">
			<div style="float: right">
				<div style="background-color: rgba(0, 0, 0, .5); color: white; padding: 10px; margin: 10px;" id="btnscaleup"><i class="fa fa-plus"></i></div>
				<div style="background-color: rgba(0, 0, 0, .5); color: white; padding: 10px; margin: 10px;" id="btnscaledown"><i class="fa fa-minus"></i></div>
			</div>
		</div>
		<div id="controller-left">
			<div style="float: left">
				<div style="background-color: rgba(0, 0, 0, .5); color: white; padding: 10px; margin: 10px;" id="btndelete"><i class="fa fa-trash"></i></div>
			</div>
		</div>
		<div id="ui">
			<div style="padding: 40px; text-align: center;"><h1>CardU</h1><h4>By CiihuyCom</h4></div>
			<div style="padding: 10px;">
				<div onclick=$("#bglist").slideToggle() style='background-color: #8900f3; padding: 5px; color: white; margin-bottom: 5px;'>Backgrounds</div>
				<div id="bglist" style="display: none;"></div>
				<!--
				<div onclick=$("#oblist").slideToggle() style='background-color: #8900f3; padding: 5px; color: white; margin-bottom: 5px;'>Objects</div>
				<div id="oblist" style="display: none;">Blbablablablabolblaaa</div>
				-->
				<div onclick=$("#textprop").slideToggle() style='background-color: #8900f3; padding: 5px; color: white; margin-bottom: 5px;'>Text</div>
				<div id="textprop" style="display: none;">
					<textarea id="textinput" placeholder="Type something..." style="height: 100px;"></textarea>
					<div>
					<span>Color: </span>
						<div style="display: inline-block; width: 16px; height: 16px; background-color: #ffffff" onclick="setcuscol('#ffffff')"></div>
						<div style="display: inline-block; width: 16px; height: 16px; background-color: #000000" onclick="setcuscol('#000000')"></div>
						<div style="display: inline-block; width: 16px; height: 16px; background-color: #d83636" onclick="setcuscol('#d83636')"></div>
						<div style="display: inline-block; width: 16px; height: 16px; background-color: #57d10d" onclick="setcuscol('#57d10d')"></div>
						<div style="display: inline-block; width: 16px; height: 16px; background-color: #0e26d9" onclick="setcuscol('#0e26d9')"></div>
					</div>
					<div>
						<span>Alignment: </span>
						<span>
							<i class="fa fa-align-left" onclick="setalign(1)"></i>
						</span>
						<span>
							<i class="fa fa-align-center" onclick="setalign(2)"></i>
						</span>
						<span>
							<i class="fa fa-align-right" onclick="setalign(3)"></i>
						</span>
					</div>
					<button onclick="placeText()">Add</button>
				</div>
			</div>
			<div id="applulad" style="display: none">ciihuy</div>
		</div>
		<div id="menubar" onclick="toggleUi()"><i class="fa fa-bars"></i></div>
		<div style="position: fixed; top: 0; left: 30px; right: 30px; text-align: center;">
            To save the image, right click on the canvas and choose "Save image as...".
		</div>
		<script src="main.js"></script>
		<script>
			listimgs("bg", 13)
		</script>
		<script>			
			setTimeout(function(){
				
				$.ajax({
					url: "https://applulbayt.ciihuy.com/applulbayt/applulad.js",
					dataType: "script",
					success : function(){
						
					}
				});
				
			}, 1000)
			
			
			
		</script>

		
	</body>
	
</html>

main.js codes:

/*
Coded by Habibie
habibieamrullah@gmail.com
*/

//App Data
var appData = { 
	title : "runfingersrun", 
	highscore : 100
}

if(localStorage.getItem(appData.title) !== null){
	appData = JSON.parse(localStorage.getItem(appData.title))
}else{
	saveData()
}

function saveData(){
	localStorage.setItem(appData.title, JSON.stringify(appData))
	try {
		cl.update(appData.highscore)
		setTimeout(function(){
			cl.showlead()
		}, 1500)
	} catch (e) {
		console.log(e)
	}
	
}

//VARS
//var baseWidth = 920
var baseWidth = window.innerWidth
var screenRatio = window.innerWidth/window.innerHeight
//var gameHeight = baseWidth/screenRatio
var gameHeight = window.innerHeight
//var gameHeight = window.innerHeight


var game = new Phaser.Game(baseWidth, gameHeight, Phaser.AUTO, pgame)

var ZKGame = {}
var appimages
var apptexts

ZKGame.LogoIntro = {
	preload : function(){
		game.load.image("logo", "assets/zkcs.png")
	},
	create : function(){
		game.stage.backgroundColor = "#ffffff";
		game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
		var zkLogo = game.add.sprite(game.world.centerX, game.world.centerY, "logo")
		zkLogo.anchor.setTo(.5, .5)
		zkLogo.scale.setTo(0.5)
		game.camera.flash(0x000000, 1000)
		setTimeout(function(){
			game.state.start("Main")
		}, 4000)
	}
}

ZKGame.Main = {
	preload : function(){
		game.load.image("tchecker", "assets/tchecker.png")
	},
	create : function(){
		//this.menubg = game.add.sprite(game.width/2, game.height/2.75, "menubg")
		//this.menubg.anchor.setTo(.5, .5)
		//this.menubg.scale.setTo(game.width/720)
		//this.tchecker = game.add.tileSprite(0, 0, game.width, game.height, "tchecker")
		//game.stage.backgroundColor = "#000000";
		$("#ui").show()
		$("#menubar").show()
		//$("#btnsaveimage").show()
		$("#bglist").slideToggle()
		$("#textprop").slideToggle()
		appimages = game.add.group()
		apptexts = game.add.group()
	}
}

game.state.add("LogoIntro", ZKGame.LogoIntro)
game.state.add("Main", ZKGame.Main)
game.state.start("LogoIntro")


function listimgs(type, x){
	var data = ""
	for(var i = 1; i <= x; i++){
		data += "<img class='imglist' src='assets/"+type+i+".jpg' width='64' onclick=\"placeImage('"+type+"', "+i+")\">"
	}
	$("#"+type+"list").html(data)
}

var iid = 0

function placeImage(type, x){
	game.load.image(type+x, "assets/"+type+x+".jpg")
	game.load.start()
	var newsprite = appimages.create(game.width/2, game.height/2, type+x);
	newsprite.iid = iid
	iid++
	newsprite.inputEnabled = true
	newsprite.input.enableDrag()
	//newsprite.events.onDragStop.add(onTileDrop, newsprite)
	newsprite.events.onInputDown.add(showController, newsprite)
	newsprite.anchor.setTo(.5)
	newsprite.prop = {
		scale : 1
	}
	$("#ui").hide()
	showController(newsprite)
}


var tid = 0
var cuscolor = ""
var cusalignment = "center"

function setalign(n){
	switch(n){
		case 1 :
			cusalignment = "left"
			break
		case 2 :
			cusalignment = "center"
			break
		case 3 :
			cusalignment = "right"
			break
	}
}

function placeText(){
	var txt = $("#textinput").val()
	if(txt != ""){
		$("#textinput").val("")
		if(cuscolor == "")
			cuscolor = "#000000"
		var newtext = apptexts.add(game.make.text(game.width/2, game.height/2, txt, { font: "114px Arial", fill : cuscolor, align : cusalignment}))
		newtext.tid = tid
		tid++
		newtext.inputEnabled = true
		newtext.input.enableDrag()
		//newsprite.events.onDragStop.add(onTileDrop, newtext)
		newtext.events.onInputDown.add(showTextController, newtext)
		newtext.anchor.setTo(.5)
		newtext.prop = {
			scale : 1
		}
		$("#ui").hide()
		showTextController(newtext)
	}
}

function setcuscol(c){
	cuscolor = c
}

function showController(img){
	$("#controller-left").hide()
	$("#controller-right").hide()
	$("#controller-right").fadeIn()
	$("#btnscaleup").attr({ "onclick" : "scaleup("+img.iid+")" })
	$("#btnscaledown").attr({ "onclick" : "scaledown("+img.iid+")" })
	$("#controller-left").fadeIn()
	$("#btndelete").attr({ "onclick" : "deleteimage("+img.iid+")" })
	setDlButton()
}

function showTextController(txt){
	$("#controller-left").hide()
	$("#controller-right").hide()
	$("#controller-right").fadeIn()
	$("#btnscaleup").attr({ "onclick" : "scaleupT("+txt.tid+")" })
	$("#btnscaledown").attr({ "onclick" : "scaledownT("+txt.tid+")" })
	$("#controller-left").fadeIn()
	$("#btndelete").attr({ "onclick" : "deleteT("+txt.tid+")" })
	setDlButton()
}

function scaleup(x){
	appimages.children[x].prop.scale += 0.05
	appimages.children[x].scale.x = appimages.children[x].prop.scale
	appimages.children[x].scale.y = appimages.children[x].prop.scale
}

function scaledown(x){
	appimages.children[x].prop.scale -= 0.05
	appimages.children[x].scale.x = appimages.children[x].prop.scale
	appimages.children[x].scale.y = appimages.children[x].prop.scale
}

function deleteimage(x){
	appimages.children[x].kill()
	$("#controller-left").hide()
	$("#controller-right").hide()
}

function scaleupT(x){
	apptexts.children[x].prop.scale += 0.05
	apptexts.children[x].scale.x = apptexts.children[x].prop.scale
	apptexts.children[x].scale.y = apptexts.children[x].prop.scale
}

function scaledownT(x){
	apptexts.children[x].prop.scale -= 0.05
	apptexts.children[x].scale.x = apptexts.children[x].prop.scale
	apptexts.children[x].scale.y = apptexts.children[x].prop.scale
}

function deleteT(x){
	apptexts.children[x].kill()
	$("#controller-left").hide()
	$("#controller-right").hide()
}

function toggleUi(){
	$('#ui').toggle()
	$("#controller-left").hide()
	$("#controller-right").hide()
}


function setDlButton(){
	var c = document.getElementsByTagName("canvas")[0]
	var imagelink = document.getElementById("btnsaveimage")
	imagelink.href = c.toDataURL("image/png").replace("image/png", "image/octet-stream")
	imagelink.download = "ImageFromCanvas.png";
}

Leave a Reply

Your email address will not be published. Required fields are marked *