Commit bc25efc1 by christian

initial commit

parents
html,button,input,select,textarea{color:#222}
hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}
img{vertical-align:middle}
fieldset{border:0;margin:0;padding:0}
textarea{resize:none}
.chromeframe{background:#ccc;color:#000;margin:.2em 0;padding:.2em 0}
::-moz-selection,::selection{background:#b3d4fc;text-shadow:none}
a, a:hover, a:active, a:focus{outline: 0}
/*HELPER*/
.ir{background-color:transparent;border:0;overflow:hidden;text-indent:-9999px}
.ir:before{content:"";display:block;width:0;height:100%}
.hidden{display:none!important;visibility:hidden}
.visuallyhidden{border:0;clip:rect(0000);height:1px;overflow:hidden;position:absolute;width:1px;margin:-1px;padding:0}
.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;overflow:visible;position:static;width:auto;margin:0}
.invisible{visibility:hidden}
.clearfix:before,.clearfix:after{content:" ";display:table}
.clearfix{clear:both;*zoom:1}
@import "normalize.min.css";
@import "helper.css";
/*MAIN STYLE*/
html, body {
width: 100%;
height: 100%;
min-width: 1020px;
}
body {
background: #f9f9f9;
}
.wrapper {
width: 1020px;
margin: 0 auto;
}
header {
}
header hgroup h1, header hgroup h2 {
margin: 0;
text-align: center;
color: #e9e9e9;
text-shadow: 1px 1px 1px #808080;
}
header hgroup {
}
header {
padding: 1%;
}
nav {
padding: 1% 0;
}
nav ul {
margin: 0;
padding: 1%;
display: -webkit-flex;
-webkit-flex-flow: row;
-webkit-justify-content: flex-start;
-webkit-align-items: flex-start;
}
nav ul li {
border: 1px dashed #ddd;
padding: 1%;
height: auto;
-webkit-flex: 1 1 1 1;
}
nav ul li:nth-child(even) {
margin: 0 10px;
}
nav ul li:nth-last-child() {
margin: 0;
}
nav ul li h3 {
background: #eee;
margin: 0;
font-weight: 400;
text-align: center;
line-height: 1.4em;
}
#outer-canvas {
-webkit-flex: 3;
}
#outer-layer {
width: 250px;
background: #eee;
border: 1px solid #cdcdcd;
-webkit-flex: 1;
padding: 1%;
display: -webkit-flex;
-webkit-flex-direction: column;
-webkit-flex-flow: column;
-webkit-align-items: center;
-webkit-align-content: center;
}
section#main-canvas-section {
display: -webkit-flex;
-webkit-flex-direction: row;
}
#outer-layer > .layerRowItem, #outer-layer > .selected {
border: 1px solid orange;
display: -webkit-flex;
-webkit-flex-direction: row;
width: 220px;
-webkit-align-items: center;
height: 40px;
padding: 1%;
margin-bottom: 1%;
}
#outer-layer > .selected {
background: #fff;
}
.layerRowItem > .infoIcon, .selected > .infoIcon {
background-size: contain;
margin-right: 10px;
}
.layerRowItem > .infoContainer, .selected > .infoContainer {
display: -webkit-flex;
-webkit-flex-direction: column;
-webkit-align-content: center;
}
.layerRowItem > .infoContainer > p, .selected > .infoContainer > p {
-webkit-flex: auto;
width: 140px;
margin: 0;
padding: 0;
font-size: .8em;
-webkit-justify-content: center;
}
.layerRowItem > .infoVisible, .selected > .infoVisible {
-webkit-flex: 1;
-webkit-align-content: flex-end;
-webkit-align-items: flex-end;
-webkit-justify-content: flex-end;
}
/*.size-fader{display: none;}*/
/*BUTTONS*/
button {
outline: none;
}
button:active {
position: relative;
top: 10px;
}
#landscape {
width: 48px;
height: 28px;
background-color: rgba(205,205,205,.3);
border: solid 1px #cdcdcd;
position: absolute;
top: 50%;
left: 50%;
margin: -14px 0 0 -24px;
}
#portrait {
width: 28px;
height: 48px;
background-color: rgba(205,205,205,.3);
border: solid 1px #cdcdcd;
position: absolute;
top: 50%;
left: 50%;
margin: -24px 0 0 -14px;
}
#circle {
width: 48px;
height: 48px;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
background-color: rgba(205,205,205,.3);
border: solid 1px #cdcdcd;
position: absolute;
top: 50%;
left: 50%;
margin: -24px 0 0 -24px;
}
.format {
width: 60px;
height: 60px;
background: #fff;
float: left;
position: relative;
}
.format:nth-child(even) {
margin: 0 10px;
}
input[type="color"] {
border: 0 none;
background-color: rgba(205,205,205,.3);
border: solid 1px #cdcdcd;
display: block;
padding: 3px 10px;
cursor: pointer;
outline: none;
}
/*CANVAS*/
#backlayer {
display: block;
position: relative;
z-index: 100;
}
#outer-canvas {
}
#outer-canvas h3 {
margin: 0;
font-weight: 400;
text-align: center;
padding: 0;
text-align: center;
display: block;
width: 200px;
margin: 1% 1% 1% 2%;
}
#inner-canvas {
margin-left: 1%;
}
#drop-target {
width: 100px;
height: 100px;
background-color: #eee;
border: 1px solid #ccc;
text-align: center;
padding: 12px;
line-height: 100px;
font-size: .8em;
}
/*! normalize.css v1.1.1 | MIT License | git.io/normalize */
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline;zoom:1}
audio:not([controls]){display:none;height:0}
[hidden]{display:none}
html{background:#fff;color:#000;font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}
html,button,input,select,textarea{font-family:sans-serif}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
h2{font-size:1.5em;margin:.83em 0}
h3{font-size:1.17em;margin:1em 0}
h4{font-size:1em;margin:1.33em 0}
h5{font-size:.83em;margin:1.67em 0}
h6{font-size:.67em;margin:2.33em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:700}
blockquote{margin:1em 40px}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace, serif;_font-family:'courier new', monospace;font-size:1em}
pre{white-space:pre-wrap;word-wrap:break-word}
q{quotes:none}
q:before,q:after{content:none}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
dd{margin:0 0 0 40px}
menu,ol,ul{padding:0 0 0 40px}
nav ul,nav ol{list-style:none;list-style-image:none}
img{border:0;-ms-interpolation-mode:bicubic}
svg:not(:root){overflow:hidden}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;white-space:normal;margin-left:-7px;padding:0}
button,input,select,textarea{font-size:100%;vertical-align:middle;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],/* 1 */
input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;overflow:visible}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{box-sizing:border-box;height:13px;width:13px;padding:0}
input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
body,figure,form{margin:0}
p,pre,dl,menu,ol,ul{margin:1em 0}
\ No newline at end of file
img/hidden.png

197 Bytes

img/resize.png

140 Bytes

img/rotate.png

438 Bytes

<!DOCTYPE html>
<html lang="de" class="no-js">
<head>
<meta charset="utf-8">
<title>Quicker sticker</title>
<meta name="description" content="create your own sticker - NOW!">
<link rel="stylesheet" href="css/main.css">
<script src="js/lib/modernizr-2.6.2.min.js"></script>
<script src="js/lib/jquery-1.10.2.min.js"></script>
<script src="js/bind.js"></script>
<script src="js/plugins.js"></script>
<script src="js/event-manager.js"></script>
<script src="js/image-manager.js"></script>
<script src="js/error-manager.js"></script>
<script src="js/canvas-manager.js"></script>
<script src="js/info-manager.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<div class="wrapper">
<header>
<hgroup>
<h1>Quicker Sticker</h1>
<h2>create your own sticker - NOW!</h2>
</hgroup>
</header>
<nav>
<ul>
<li><h3>Choose format</h3><br>
<span class="format"><button class="format-button" id="portrait"></button></span>
<span class="format"><button class="format-button" id="landscape"></button></span>
<span class="format"><button class="format-button" id="circle"></button></span><br class="clearfix"><br>
<h3>Border <input type="checkbox" name="border-check" id="border-check" value="border"></h3>
</li>
<li><h3>Size</h3><br>
<input class="size-fader" id="size-slider" type="range" min="300" max="400" value="300" step="25"><br><br>
<h3>Size - <output for="size-fader" id="size-width">1</output></h3>
</li>
<li><h3>Background color</h3><br>
<input id="bg-color" type="color" value="#efefef"></input><br>
<div class="hidden" id="show-border-color">
<h3>Border color</h3><br>
<input id="border-color" type="color"></input>
</div>
</li>
<li class="hidden"><h3>Image File</h3><br>
<div id="drop-target">Drop image here</div>
<output for="drop-target" id="target-src"></output>
</li>
<li class="hidden"><button id="reset">reset</button></li>
</ul>
</nav>
<section id="main-canvas-section">
<div id="outer-canvas">
<div id="inner-canvas">
<canvas id="backlayer" width="0" height="0"></canvas>
</div>
<h3>&#8593; Drop image here &#8593;</h3>
</div>
<div id="outer-layer"></div>
</section>
</div>
</body>
</html>
Function.prototype.bind = Function.prototype.bind || function (target) {
var self = this;
return function (args) {
if (!(args instanceof Array)) {
args = [args];
}
self.apply(target, args);
};
};
\ No newline at end of file
function ErrorManager(){
if (typeof ErrorManager.instance === 'object') { return ErrorManager.instance; }
ErrorManager.instance = this;
this.ERR_Types = {
ERR_IMAGE_TYPE : 'Invalid file extension - Allowed MIME types: image/*',
ERR_INVALID_URL : 'Image file contains invalid or corrupt data',
ERR_FILE_SIZE : 'Image file size is too big to handle - Please reduce the image height, width or resolution'
}
}
ErrorManager.prototype.errorHandler = function (src, ERR_Type) {
this.src = src;
this.errorMessage = this.ERR_Types[ERR_Type];
var errorList = document.createElement('ul');
this.createErrorMessage = function (src) {
var newLi = document.createElement('li');
var text = document.createTextNode(ERR_Type + ': ' + '' + this.errorMessage + ' [ ' + this.src.name + ' ]');
newLi.appendChild(text);
errorList.appendChild(newLi);
// document.getElementsByTagName('body')[0].appendChild(errorList);
console.log(text);
};
this.createErrorMessage(this.src);
}
function EventManager() {
if (typeof EventManager.instance === 'object'){return EventManager.instance;}
EventManager.instance = this;
this.events = {};
this.listen();
}
EventManager.prototype.on = function (event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
};
EventManager.prototype.emit = function (event, data) {
var callbacks = this.events[event];
if (callbacks) {
callbacks.forEach(function (callback) {
callback(data);
});
}
};
EventManager.prototype.listen = function () {
// var self = this;
this.bindButton('#portrait', this.getShape);
this.bindButton('#landscape', this.getShape);
this.bindButton('#circle', this.getShape);
this.bindButton('#reset', this.resetAll);
this.bindInputFormatSizeChange('#size-slider', this.getFormatSize);
this.bindInputChangeColor('#bg-color', this.getColor);
this.bindInputChangeColor('#border-color', this.getColor);
this.bindInputCheckBorder('#border-check', this.checkShapeBorder);
this.bindDragOverTarget('#inner-canvas', this.dragOverTarget);
this.bindDropTarget('#inner-canvas', this.dropTarget);
this.bindDragOverTargetStart('#inner-canvas', this.dragOverTargetStart);
this.bindMouseMove('canvas', this.mouseMove);
this.bindMouseOut('canvas', this.mouseOut);
this.bindMouseUp('canvas', this.mouseUp);
this.bindMouseLeave('canvas', this.mouseLeave);
this.bindMouseDown('canvas', this.mouseDown);
}
EventManager.prototype.getFormatSize = function (event) {
event.preventDefault();
var sizeMap = {
300: 1,
325: 2,
350: 3,
375: 4,
400: 5
};
var output = document.getElementById('size-width'),
outputValue = document.getElementById('size-slider').value,
mapped = sizeMap[outputValue];
if (mapped !== 'undefined')
output.value = mapped;
this.emit('getFormatSize');
}
EventManager.prototype.getColor = function (event) {
event.preventDefault();
this.emit('getColor');
return document.getElementById('bg-color').value;
}
EventManager.prototype.getShape = function (event) {
event.preventDefault();
this.emit('getShape');
}
EventManager.prototype.resetAll = function (event) {
event.preventDefault();
this.emit('resetAll');
}
EventManager.prototype.checkShapeBorder = function (event) {
event.preventDefault();
this.emit('checkShapeBorder');
}
EventManager.prototype.dragOverTarget = function (event) {
event.stopPropagation();
event.preventDefault();
this.emit('dragOverTarget');
}
EventManager.prototype.dragOverTargetStart = function (event) {
event.preventDefault();
this.emit('dragOverTargetStart');
return;
}
EventManager.prototype.dropTarget = function (event) {
event.dataTransfer.dropEffect = 'copy';
event.stopPropagation()
event.preventDefault();
this.emit('dropTarget');
}
EventManager.prototype.mouseMove = function (event) {
event.stopPropagation();
this.emit('mouseMove');
}
EventManager.prototype.mouseDown = function (event) {
event.stopPropagation();
this.emit('mouseDown');
}
EventManager.prototype.mouseOut = function (event) {
event.stopPropagation();
this.emit('mouseOut');
}
EventManager.prototype.mouseUp = function (event) {
event.stopPropagation();
this.emit('mouseUp');
}
EventManager.prototype.mouseLeave = function (event) {
event.stopPropagation();
this.emit('mouseLeave');
}
// LAYER HANDLER
//EventManager.prototype.mouseOver = function (event) {
// event.stopPropagation();
// this.emit('mouseOver');
//}
//EventManager.prototype.layerRowItemClick = function (event) {
// event.stopPropagation()
// event.preventDefault();
// console.log(event.currentTarget.id)
// this.emit('layerRowItemClick');
// return event;
//}
//EventManager.prototype.bindLayerRowItemClick = function (selector, fn) {
// var item = document.querySelector(selector);
// console.log(item)
// item.addEventListener('click', fn.bind(this));
//}
//binding
EventManager.prototype.bindMouseMove = function (selector, fn) {
var cvs = document.querySelector(selector);
cvs.addEventListener('mousemove', fn.bind(this));
}
EventManager.prototype.bindMouseDown = function(selector,fn){
var cvs = document.querySelector(selector);
cvs.addEventListener('mousedown', fn.bind(this));
}
EventManager.prototype.bindMouseOut = function(selector,fn){
var cvs = document.querySelector(selector);
cvs.addEventListener('mouseout', fn.bind(this),false);
}
EventManager.prototype.bindMouseUp = function(selector,fn){
var cvs = document.querySelector(selector);
cvs.addEventListener('mouseup', fn.bind(this),false);
}
EventManager.prototype.bindMouseLeave = function(selector,fn){
var cvs = document.querySelector(selector);
cvs.addEventListener('mouseleave', fn.bind(this),false);
}
//EventManager.prototype.bindMouseOver = function(selector,fn){
// var cvs = document.querySelector(selector);
// cvs.addEventListener('mouseover', fn.bind(this),false);
//}
EventManager.prototype.bindButton = function (selector, fn) {
var button = document.querySelector(selector);
button.addEventListener('click', fn.bind(this));
}
EventManager.prototype.bindInputFormatSizeChange = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('change', fn.bind(this));
}
EventManager.prototype.bindInputCheckBorder = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('change', fn.bind(this));
}
EventManager.prototype.bindInputChangeColor = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('change', fn.bind(this));
}
EventManager.prototype.bindDragOverTarget = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('dragover', fn.bind(this), false);
}
EventManager.prototype.bindDropTarget = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('drop', fn.bind(this), false);
}
EventManager.prototype.bindDragOverTargetStart = function (selector, fn) {
var input = document.querySelector(selector);
input.addEventListener('dragstart', fn.bind(this));
}
\ No newline at end of file
function ImageManager(canvasId) {
if (typeof ImageManager.instance === 'object') { return ImageManager.instance; }
ImageManager.instance = this;
NONE = 0, MOVING = 1, SCALING = 2, ROTATING = 3;
this.mouseDown = false;
this.mousePrevX = 0;
this.mousePrevY = 0;
this.selectedLayer = null;
this.layerState = NONE;
this.canvasOffsetX = 0;
this.canvasOffsetY = 0;
this.scaleImg = new Image();
this.rotateImg = new Image();
this.scaleImg.src = 'img/resize.png';
this.rotateImg.src = 'img/resize.png';
var canvas = canvasId;
var canvasOffsetX = canvas.offsetLeft;
var canvasOffsetY = canvas.offsetTop;
var context = canvas.getContext('2d');
var layers = new Array();
this.addLayer = function (img,src) {
var layer = new Layer(img,src);
layers.push(layer);
return layer;
}
this.redraw = function() {
//this.canvasManager.changeShape(false);
}
this.getCanvas = function() {
return canvas;
}
this.getLayers = function() {
return layers;
}
this.getLayer = function(i) {
return layers[i];
}
this.isScalingArea = function (mX, mY, layer) {
//if (layer instanceof TextLayer) {
// return false;
//}
var scaleOffsetX = layer.offsetX + layer.width;
var scaleOffsetY = layer.offsetY + layer.height;
var square = new Square(
new Vector(scaleOffsetX - this.scaleImg.width, scaleOffsetY - this.scaleImg.height),
new Vector(scaleOffsetX, scaleOffsetY - this.scaleImg.height),
new Vector(scaleOffsetX, scaleOffsetY),
new Vector(scaleOffsetX - this.scaleImg.width, scaleOffsetY));
square.rotate(layer.angle);
square.alignBottomRight(layer.getSquare().c);
return square.intersect(new Vector(mX, mY));
}
}
function Layer(img,src) {
this.src = src;
this.img = img;
this.offsetX =0;
this.offsetY = 0;
this.imgNaturalWidth = this.img.width;
this.imgNaturalHeight = this.img.height;
this.imgDimension = this.imgNaturalHeight < this.imgNaturalWidth ? 'imgLandscape' : 'imgPortrait';
this.width = this.imgNaturalWidth;
this.height = this.imgNaturalHeight;
this.canvas = document.createElement('canvas');
this.canvas.width = this.width;
this.canvas.height = this.height;
this.context = this.canvas.getContext('2d');
this.context.save();
this.context.translate(this.width / 2, this.height / 2);
this.opacity = 1;
this.visible = true;
this.angle = 0;
this.title = this.src.name;
this.compositeOperation = "source-over";
this.getTitle = function() {
return this.title;
}
this.getFileData = function () {
return this.src;
}
this.getImage = function () {
return this.img;