Add files via upload
27
apps/Paint/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
HTML5Paint
|
||||
==========
|
||||
|
||||
A simple paint application created using HTML5, JavaScript, NodeJS as the backend and runs on Cloud Foundry.
|
||||
|
||||
The application is currently deployed at [SimplePaint.cloudfoundry.com](http://simplepaint.cloudfoundry.com/).
|
||||
|
||||
Description
|
||||
-------
|
||||
|
||||
This simple paint application allows a user to draw images or colour in images. The user can clear the canvas to start over and they can also save the image. Below is a screenshot of the application.
|
||||
|
||||

|
||||
|
||||
|
||||
Technologies
|
||||
-------
|
||||
|
||||
The application was developed using Bootstrap, HTML5, ExpressJS, NodeJS, Jade, JavaScript and jQuery.
|
||||
|
||||
Author
|
||||
-------
|
||||
|
||||
**Shane Doyle**
|
||||
|
||||
+ http://twitter.com/elwexicano
|
||||
+ http://github.com/ElWexicano
|
14
apps/Paint/app.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
Application File
|
||||
Author : Shane Doyle
|
||||
Date : 31/10/2012
|
||||
This file is used to run the application.
|
||||
*/
|
||||
var express = require("express");
|
||||
var app = module.exports = express();
|
||||
|
||||
var config = require("./config.js")(app, express);
|
||||
|
||||
require("./routes/routes")(app);
|
||||
|
||||
app.listen(3000);
|
50
apps/Paint/config.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Configuration File
|
||||
Author : Shane Doyle
|
||||
Date : 31/10/2012
|
||||
This file is used to store the configuration
|
||||
settings for the application.
|
||||
*/
|
||||
module.exports = function(app, express){
|
||||
var config = this;
|
||||
|
||||
app.configure(function(){
|
||||
app.set("views", __dirname + "/views");
|
||||
app.set("view engine", "jade");
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(app.router);
|
||||
app.use(express.static(__dirname + "/public"));
|
||||
});
|
||||
|
||||
app.use(NotFoundErrorHandler);
|
||||
app.use(ErrorHandler);
|
||||
|
||||
// Error Handling - Not Found
|
||||
function NotFound(msg) {
|
||||
this.name = "NotFound";
|
||||
Error.call(this, msg);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
}
|
||||
|
||||
// Error Handling - 404 Error
|
||||
function NotFoundErrorHandler(err, req, res, next) {
|
||||
if (error instanceof NotFound) {
|
||||
res.render("404.jade", {
|
||||
status: 400
|
||||
});
|
||||
} else {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Error Handling - 500 Error
|
||||
function ErrorHandler(err, req, res, next) {
|
||||
res.render("500.jade", {
|
||||
status: 500,
|
||||
locals: {error: err}
|
||||
});
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
BIN
apps/Paint/img/batman-thumbnail.gif
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/Paint/img/batman.gif
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
apps/Paint/img/blank-thumbnail.gif
Normal file
After Width: | Height: | Size: 916 B |
BIN
apps/Paint/img/chrome.gif
Normal file
After Width: | Height: | Size: 687 B |
BIN
apps/Paint/img/firefox.gif
Normal file
After Width: | Height: | Size: 820 B |
BIN
apps/Paint/img/glyphicons-halflings-white.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/Paint/img/glyphicons-halflings.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
apps/Paint/img/ie.gif
Normal file
After Width: | Height: | Size: 748 B |
BIN
apps/Paint/img/opera.gif
Normal file
After Width: | Height: | Size: 664 B |
BIN
apps/Paint/img/safari.gif
Normal file
After Width: | Height: | Size: 825 B |
BIN
apps/Paint/img/spiderman-thumbnail.gif
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
apps/Paint/img/spiderman.gif
Normal file
After Width: | Height: | Size: 172 KiB |
100
apps/Paint/index.html
Normal file
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Paint</title>
|
||||
<script src="scripts/modernizr.js"></script>
|
||||
<link href="stylesheets/normalize.css" rel="stylesheet">
|
||||
<link href="stylesheets/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="stylesheets/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid span14 well">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a href="#" class="brand">Simple Paint App</a>
|
||||
|
||||
<ul class="nav">
|
||||
<li><a id="newCanvasBtn" href="#newPaintModal" data-toggle="modal"><i class="icon-file"></i> New</a></li>
|
||||
<li><a id="saveCanvasBtn" href="#"><i class="icon-download"></i> Save</a></li>
|
||||
<li><a id="clearCanvasBtn" href="#"><i class="icon-remove"></i> Clear</a></li>
|
||||
</ul>
|
||||
<form class="navbar-form pull-left">
|
||||
<div id="colorPalette" class="btn-group btn-small">
|
||||
<a name="000000" class="btn btn-small btn-inverse active" href="#"> </a>
|
||||
<a name="E0534E" class="btn btn-small btn-danger" href="#"> </a>
|
||||
<a name="FAA630" class="btn btn-small btn-warning" href="#"> </a>
|
||||
<a name="5CB55C" class="btn btn-small btn-success" href="#"> </a>
|
||||
<a name="48AECC" class="btn btn-small btn-info" href="#"> </a>
|
||||
<a name="0B8BCC" class="btn btn-small btn-primary" href="#"> </a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<canvas id="myCanvas" width="1024" height="768"></canvas>
|
||||
|
||||
<div id="newPaintModal" class="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<h3>Simple Paint App</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Select from one of the following canvases to use:</p>
|
||||
|
||||
<div class="row-fluid">
|
||||
<ul class="thumbnails">
|
||||
<li id="blankCanvas" class="span4 canvasIcon">
|
||||
<div class="thumbnail">
|
||||
<img src="img/blank-thumbnail.gif" alt="Blank Canvas">
|
||||
<div class="caption">
|
||||
<h4>Blank</h4>
|
||||
<p>A blank canvas with a width size of 1024 and height size of 768.</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li id="spidermanCanvas" class="span4 canvasIcon">
|
||||
<div class="thumbnail">
|
||||
<img width="300" height="200" src="img/spiderman-thumbnail.gif" alt="Spiderman Thumbnail">
|
||||
<div class="caption">
|
||||
<h4>Spiderman</h4>
|
||||
<p>A canvas with a Spiderman image on it, brilliant for colouring in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li id="batmanCanvas" class="span4 canvasIcon">
|
||||
<div class="thumbnail">
|
||||
<img width="300" height="200" src="img/batman-thumbnail.gif" alt="Batman Thumbnail">
|
||||
<div class="caption">
|
||||
<h4>Batman</h4>
|
||||
<p>A canvas with a Batman image on it, brilliant for colouring in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<p>
|
||||
Compatible with modern browsers:
|
||||
<image class="compatibleBrowsersIcon" src="img/chrome.gif" title="Google Chrome 4.0+"/>
|
||||
<image class="compatibleBrowsersIcon" src="img/firefox.gif" title="Mozilla Firefox 2.0+"/>
|
||||
<image class="compatibleBrowsersIcon" src="img/ie.gif" title="Internet Explorer 9.0+"/>
|
||||
<image class="compatibleBrowsersIcon" src="img/opera.gif" title="Opera 9.0+"/>
|
||||
<image class="compatibleBrowsersIcon" src="img/safari.gif" title="Safari 3.1+"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>Created by <a href="https://www.twitter.com/iamshanedoyle">iamshanedoyle</a> for fun!</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="scripts/jquery-1.8.2.min.js"></script>
|
||||
<script src="scripts/bootstrap.js"></script>
|
||||
<script src="scripts/paint.js"></script>
|
||||
<script src="scripts/index.js"></script>
|
||||
</body>
|
||||
</html>
|
BIN
apps/Paint/out.png
Normal file
After Width: | Height: | Size: 328 KiB |
14
apps/Paint/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "simple-paint",
|
||||
"version": "0.0.1",
|
||||
"private": "true",
|
||||
"author": "Shane Doyle",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/iamshanedoyle/html5paint"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "",
|
||||
"jade": ""
|
||||
}
|
||||
}
|
BIN
apps/Paint/public/img/batman-thumbnail.gif
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/Paint/public/img/batman.gif
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
apps/Paint/public/img/blank-thumbnail.gif
Normal file
After Width: | Height: | Size: 916 B |
BIN
apps/Paint/public/img/chrome.gif
Normal file
After Width: | Height: | Size: 687 B |
BIN
apps/Paint/public/img/firefox.gif
Normal file
After Width: | Height: | Size: 820 B |
BIN
apps/Paint/public/img/glyphicons-halflings-white.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/Paint/public/img/glyphicons-halflings.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
apps/Paint/public/img/ie.gif
Normal file
After Width: | Height: | Size: 748 B |
BIN
apps/Paint/public/img/opera.gif
Normal file
After Width: | Height: | Size: 664 B |
BIN
apps/Paint/public/img/safari.gif
Normal file
After Width: | Height: | Size: 825 B |
BIN
apps/Paint/public/img/spiderman-thumbnail.gif
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
apps/Paint/public/img/spiderman.gif
Normal file
After Width: | Height: | Size: 172 KiB |
2038
apps/Paint/public/javascripts/bootstrap.js
vendored
Normal file
7
apps/Paint/public/javascripts/bootstrap.min.js
vendored
Normal file
1416
apps/Paint/public/javascripts/excanvas.js
Normal file
85
apps/Paint/public/javascripts/index.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
$( function() {
|
||||
var canvas = $("#myCanvas");
|
||||
var paint = new Paint(canvas[0].getContext("2d"));
|
||||
|
||||
function getMousePosition(event, canvas) {
|
||||
var x, y;
|
||||
|
||||
if (event.offsetX) {
|
||||
x = event.offsetX;
|
||||
y = event.offsetY;
|
||||
} else {
|
||||
x = event.pageX - canvas.offsetLeft;
|
||||
y = event.pageY - canvas.offsetTop;
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y
|
||||
};
|
||||
}
|
||||
|
||||
canvas.mousedown(function(e) {
|
||||
var pos = getMousePosition(e, this);
|
||||
paint.isPainting = true;
|
||||
paint.addClick(pos.x, pos.y, false);
|
||||
paint.draw();
|
||||
});
|
||||
|
||||
canvas.mousemove(function(e) {
|
||||
if (paint.isPainting) {
|
||||
var pos = getMousePosition(e, this);
|
||||
paint.addClick(pos.x, pos.y, true);
|
||||
paint.draw();
|
||||
}
|
||||
});
|
||||
|
||||
canvas.mouseup(function(e) {
|
||||
paint.stop();
|
||||
});
|
||||
|
||||
canvas.mouseleave(function(e) {
|
||||
paint.stop();
|
||||
});
|
||||
|
||||
$("#clearButton").click(function() {
|
||||
paint.clear();
|
||||
});
|
||||
|
||||
$("#colorPalette a").click(function() {
|
||||
$("#colorPalette a").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
paint.options.brushColour = "#"+this.name;
|
||||
});
|
||||
|
||||
$("#newPaintModal").modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$("#clearCanvasBtn").click(function() {
|
||||
paint.clear();
|
||||
});
|
||||
|
||||
$("#saveCanvasBtn").click(function() {
|
||||
var dataURL = canvas[0].toDataURL().replace('data:image/png', 'data:application/octet-stream');
|
||||
window.open(dataURL);
|
||||
});
|
||||
|
||||
$("#blankCanvas").click(function() {
|
||||
paint.clear();
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
|
||||
$("#batmanCanvas").click(function() {
|
||||
paint.clear();
|
||||
paint.drawImage("img/batman.gif");
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
|
||||
$("#spidermanCanvas").click(function() {
|
||||
paint.clear();
|
||||
paint.drawImage("img/spiderman.gif");
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
});
|
2
apps/Paint/public/javascripts/jquery-1.8.2.min.js
vendored
Normal file
4
apps/Paint/public/javascripts/modernizr.js
Normal file
67
apps/Paint/public/javascripts/paint.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
function Paint(context, options) {
|
||||
if (context !== undefined && context !== null) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
if (options !== undefined && options !== null) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Paint.prototype = {
|
||||
context: undefined,
|
||||
options: {
|
||||
brushColour: "#000000",
|
||||
brushWidth: 3
|
||||
},
|
||||
self: this,
|
||||
pos: 0,
|
||||
isPainting: false,
|
||||
clickX: [],
|
||||
clickY: [],
|
||||
clickDrag: [],
|
||||
addClick: function (x, y, dragging) {
|
||||
this.clickX.push(x);
|
||||
this.clickY.push(y);
|
||||
this.clickDrag.push(dragging);
|
||||
},
|
||||
clear: function () {
|
||||
this.clickX = [];
|
||||
this.clickY = [];
|
||||
this.clickDrag = [];
|
||||
this.pos = 0;
|
||||
this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height);
|
||||
},
|
||||
draw: function () {
|
||||
this.context.strokeStyle = this.options.brushColour;
|
||||
this.context.lineJoin = "round";
|
||||
this.context.lineWidth = this.options.brushWidth;
|
||||
|
||||
while (this.pos < this.clickX.length) {
|
||||
this.context.beginPath();
|
||||
if (this.clickDrag[this.pos] && this.pos) {
|
||||
this.context.moveTo(this.clickX[this.pos - 1], this.clickY[this.pos - 1]);
|
||||
} else {
|
||||
this.context.moveTo(this.clickX[this.pos] - 1, this.clickY[this.pos]);
|
||||
}
|
||||
|
||||
this.context.lineTo(this.clickX[this.pos], this.clickY[this.pos]);
|
||||
this.context.closePath();
|
||||
this.context.stroke();
|
||||
this.pos++;
|
||||
}
|
||||
},
|
||||
drawImage: function (imageUrl) {
|
||||
var imageObj = new Image();
|
||||
var context = this.context;
|
||||
imageObj.onload = function() {
|
||||
context.drawImage(imageObj, 0, 0, 1024, 768);
|
||||
};
|
||||
imageObj.src = imageUrl;
|
||||
},
|
||||
stop: function () {
|
||||
this.isPainting = false;
|
||||
}
|
||||
}
|
5775
apps/Paint/public/stylesheets/bootstrap.css
vendored
Normal file
9
apps/Paint/public/stylesheets/bootstrap.min.css
vendored
Normal file
375
apps/Paint/public/stylesheets/normalize.css
vendored
Normal file
|
@ -0,0 +1,375 @@
|
|||
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
/* ==========================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Corrects `block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects `inline-block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling for `hidden` attribute not present in IE 8/9.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* 1. Sets default font family to sans-serif.
|
||||
* 2. Prevents iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `outline` inconsistency between Chrome and other browsers.
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
|
||||
* Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Corrects font family set oddly in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability of pre-formatted text in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets consistent quote types.
|
||||
*/
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Removes border when inside `a` element in IE 8/9.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects overflow displayed oddly in IE 9.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses margin not present in IE 8/9 and Safari 5.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects color not being inherited in IE 8/9.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects font family not being inherited in all browsers.
|
||||
* 2. Corrects font size not being inherited in all browsers.
|
||||
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Corrects inability to style clickable `input` types in iOS.
|
||||
* 3. Improves usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses box sizing set to `content-box` in IE 8/9.
|
||||
* 2. Removes excess padding in IE 8/9.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Removes default vertical scrollbar in IE 8/9.
|
||||
* 2. Improves readability and alignment in all browsers.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
29
apps/Paint/public/stylesheets/styles.css
Normal file
|
@ -0,0 +1,29 @@
|
|||
body {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 1024px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
canvas:hover, canvas:active {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.compatibleBrowsersIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.canvasIcon:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.centered-header {
|
||||
text-align: center;
|
||||
}
|
17
apps/Paint/routes/routes.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Application Routes
|
||||
Author : Shane Doyle
|
||||
Date : 31/10/2012
|
||||
This file is used to store the routes
|
||||
for the application.
|
||||
*/
|
||||
module.exports = function(app) {
|
||||
var title = "Simple Paint App";
|
||||
|
||||
// Default Route
|
||||
app.get("/", function(req, res) {
|
||||
res.render("index.jade", {
|
||||
title: title
|
||||
});
|
||||
});
|
||||
};
|
2038
apps/Paint/scripts/bootstrap.js
vendored
Normal file
7
apps/Paint/scripts/bootstrap.min.js
vendored
Normal file
1416
apps/Paint/scripts/excanvas.js
Normal file
84
apps/Paint/scripts/index.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
$( function() {
|
||||
var canvas = $("#myCanvas");
|
||||
var paint = new Paint(canvas[0].getContext("2d"));
|
||||
|
||||
function getMousePosition(event, canvas) {
|
||||
var x, y;
|
||||
|
||||
if (event.offsetX) {
|
||||
x = event.offsetX;
|
||||
y = event.offsetY;
|
||||
} else {
|
||||
x = event.pageX - canvas.offsetLeft;
|
||||
y = event.pageY - canvas.offsetTop;
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y
|
||||
};
|
||||
}
|
||||
|
||||
canvas.mousedown(function(e) {
|
||||
var pos = getMousePosition(e, this);
|
||||
paint.isPainting = true;
|
||||
paint.addClick(pos.x, pos.y, false);
|
||||
paint.draw();
|
||||
});
|
||||
|
||||
canvas.mousemove(function(e) {
|
||||
if (paint.isPainting) {
|
||||
var pos = getMousePosition(e, this);
|
||||
paint.addClick(pos.x, pos.y, true);
|
||||
paint.draw();
|
||||
}
|
||||
});
|
||||
|
||||
canvas.mouseup(function(e) {
|
||||
paint.stop();
|
||||
});
|
||||
|
||||
canvas.mouseleave(function(e) {
|
||||
paint.stop();
|
||||
});
|
||||
|
||||
$("#clearButton").click(function() {
|
||||
paint.clear();
|
||||
});
|
||||
|
||||
$("#colorPalette a").click(function() {
|
||||
$("#colorPalette a").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
paint.options.brushColour = "#"+this.name;
|
||||
});
|
||||
|
||||
$("#newPaintModal").modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$("#clearCanvasBtn").click(function() {
|
||||
paint.clear();
|
||||
});
|
||||
|
||||
$("#saveCanvasBtn").click(function() {
|
||||
var dataURL = canvas[0].toDataURL();
|
||||
});
|
||||
|
||||
$("#blankCanvas").click(function() {
|
||||
paint.clear();
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
|
||||
$("#batmanCanvas").click(function() {
|
||||
paint.clear();
|
||||
paint.drawImage("img/batman.gif");
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
|
||||
$("#spidermanCanvas").click(function() {
|
||||
paint.clear();
|
||||
paint.drawImage("img/spiderman.gif");
|
||||
$("#newPaintModal").modal("hide");
|
||||
});
|
||||
});
|
2
apps/Paint/scripts/jquery-1.8.2.min.js
vendored
Normal file
1384
apps/Paint/scripts/modernizr.js
Normal file
68
apps/Paint/scripts/paint.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
function Paint(context, options) {
|
||||
if (context !== undefined && context !== null) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
if (options !== undefined && options !== null) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Paint.prototype = {
|
||||
context: undefined,
|
||||
options: {
|
||||
brushColour: "#000000",
|
||||
brushWidth: 3
|
||||
},
|
||||
self: this,
|
||||
pos: 0,
|
||||
isPainting: false,
|
||||
clickX: [],
|
||||
clickY: [],
|
||||
clickDrag: [],
|
||||
addClick: function (x, y, dragging) {
|
||||
this.clickX.push(x);
|
||||
this.clickY.push(y);
|
||||
this.clickDrag.push(dragging);
|
||||
},
|
||||
clear: function () {
|
||||
this.clickX = [];
|
||||
this.clickY = [];
|
||||
this.clickDrag = [];
|
||||
this.pos = 0;
|
||||
this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height);
|
||||
},
|
||||
draw: function () {
|
||||
this.context.strokeStyle = this.options.brushColour;
|
||||
this.context.lineJoin = "round";
|
||||
this.context.lineWidth = this.options.brushWidth;
|
||||
|
||||
while (this.pos < this.clickX.length) {
|
||||
this.context.beginPath();
|
||||
if (this.clickDrag[this.pos] && this.pos) {
|
||||
this.context.moveTo(this.clickX[this.pos - 1], this.clickY[this.pos - 1]);
|
||||
} else {
|
||||
this.context.moveTo(this.clickX[this.pos] - 1, this.clickY[this.pos]);
|
||||
}
|
||||
|
||||
this.context.lineTo(this.clickX[this.pos], this.clickY[this.pos]);
|
||||
this.context.closePath();
|
||||
this.context.stroke();
|
||||
this.pos++;
|
||||
}
|
||||
},
|
||||
drawImage: function (imageUrl) {
|
||||
var imageObj = new Image();
|
||||
var context = this.context;
|
||||
imageObj.onload = function() {
|
||||
console.log(this.context);
|
||||
context.drawImage(imageObj, 0, 0, 1024, 768);
|
||||
};
|
||||
imageObj.src = imageUrl;
|
||||
},
|
||||
stop: function () {
|
||||
this.isPainting = false;
|
||||
}
|
||||
}
|
5775
apps/Paint/stylesheets/bootstrap.css
vendored
Normal file
841
apps/Paint/stylesheets/bootstrap.min.css
vendored
Normal file
375
apps/Paint/stylesheets/normalize.css
vendored
Normal file
|
@ -0,0 +1,375 @@
|
|||
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
/* ==========================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Corrects `block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects `inline-block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling for `hidden` attribute not present in IE 8/9.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* 1. Sets default font family to sans-serif.
|
||||
* 2. Prevents iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `outline` inconsistency between Chrome and other browsers.
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
|
||||
* Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Corrects font family set oddly in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability of pre-formatted text in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets consistent quote types.
|
||||
*/
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Removes border when inside `a` element in IE 8/9.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects overflow displayed oddly in IE 9.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses margin not present in IE 8/9 and Safari 5.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects color not being inherited in IE 8/9.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects font family not being inherited in all browsers.
|
||||
* 2. Corrects font size not being inherited in all browsers.
|
||||
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Corrects inability to style clickable `input` types in iOS.
|
||||
* 3. Improves usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses box sizing set to `content-box` in IE 8/9.
|
||||
* 2. Removes excess padding in IE 8/9.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Removes default vertical scrollbar in IE 8/9.
|
||||
* 2. Improves readability and alignment in all browsers.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
21
apps/Paint/stylesheets/style.css
Normal file
|
@ -0,0 +1,21 @@
|
|||
body {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
canvas:hover, canvas:active {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.compatibleBrowsersIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.canvasIcon:hover {
|
||||
cursor: pointer;
|
||||
}
|
83
apps/Paint/views/index.jade
Normal file
|
@ -0,0 +1,83 @@
|
|||
!!! 5
|
||||
html
|
||||
head
|
||||
meta(charset='UTF-8')
|
||||
title Paint
|
||||
script(src='javascripts/modernizr.js')
|
||||
script(type='text/javascript')
|
||||
Modernizr.load({
|
||||
test: Modernizr.canvas,
|
||||
nope: 'javascripts/excanvas.js'
|
||||
});
|
||||
link(href='stylesheets/normalize.css', rel='stylesheet')
|
||||
link(href='stylesheets/bootstrap.min.css', rel='stylesheet')
|
||||
link(href='stylesheets/styles.css', rel='stylesheet')
|
||||
body
|
||||
div.container.well
|
||||
div.navbar
|
||||
div.navbar-inner
|
||||
a.brand(href='#') Simple Paint App
|
||||
ul.nav
|
||||
li
|
||||
a#newCanvasBtn(href='#newPaintModal', data-toggle='modal')
|
||||
i.icon-file
|
||||
| New
|
||||
li
|
||||
a#saveCanvasBtn(href='#')
|
||||
i.icon-download
|
||||
| Save
|
||||
li
|
||||
a#clearCanvasBtn(href='#')
|
||||
i.icon-remove
|
||||
| Clear
|
||||
form.navbar-form.pull-left
|
||||
#colorPalette.btn-group.btn-small
|
||||
a.btn.btn-small.btn-inverse.active(name='000000', href='#')
|
||||
a.btn.btn-small.btn-danger(name='E0534E', href='#')
|
||||
a.btn.btn-small.btn-warning(name='FAA630', href='#')
|
||||
a.btn.btn-small.btn-success(name='5CB55C', href='#')
|
||||
a.btn.btn-small.btn-info(name='48AECC', href='#')
|
||||
a.btn.btn-small.btn-primary(name='0B8BCC', href='#')
|
||||
canvas#myCanvas(width='1024', height='768')
|
||||
#newPaintModal.modal(tabindex='-1', role='dialog', aria-labelledby='myModalLabel', aria-hidden='true')
|
||||
div.modal-header
|
||||
h3 Simple Paint App
|
||||
div.modal-body
|
||||
p Select from one of the following canvases to use:
|
||||
div.row-fluid
|
||||
ul.thumbnails
|
||||
li#blankCanvas.span4.canvasIcon
|
||||
.thumbnail
|
||||
img(src='img/blank-thumbnail.gif', alt='Blank Canvas')
|
||||
.caption
|
||||
h4 Blank
|
||||
p A blank canvas with a width size of 1024 and height size of 768.
|
||||
li#spidermanCanvas.span4.canvasIcon
|
||||
.thumbnail
|
||||
img(width='300', height='200', src='img/spiderman-thumbnail.gif', alt='Spiderman Thumbnail')
|
||||
.caption
|
||||
h4 Spiderman
|
||||
p A canvas with a Spiderman image on it, brilliant for colouring in.
|
||||
li#batmanCanvas.span4.canvasIcon
|
||||
.thumbnail
|
||||
img(width='300', height='200', src='img/batman-thumbnail.gif', alt='Batman Thumbnail')
|
||||
.caption
|
||||
h4 Batman
|
||||
p A canvas with a Batman image on it, brilliant for colouring in.
|
||||
div.modal-footer
|
||||
p
|
||||
| Compatible with modern browsers:
|
||||
image.compatibleBrowsersIcon(src='img/chrome.gif', title='Google Chrome 4.0+')
|
||||
image.compatibleBrowsersIcon(src='img/firefox.gif', title='Mozilla Firefox 2.0+')
|
||||
image.compatibleBrowsersIcon(src='img/ie.gif', title='Internet Explorer 9.0+')
|
||||
image.compatibleBrowsersIcon(src='img/opera.gif', title='Opera 9.0+')
|
||||
image.compatibleBrowsersIcon(src='img/safari.gif', title='Safari 3.1+')
|
||||
footer
|
||||
p.centered-header
|
||||
| Created by
|
||||
a(href='https://www.twitter.com/iamshanedoyle') iamshanedoyle
|
||||
| for fun!
|
||||
script(src='javascripts/jquery-1.8.2.min.js')
|
||||
script(src='javascripts/bootstrap.js')
|
||||
script(src='javascripts/paint.js')
|
||||
script(src='javascripts/index.js')
|
22
apps/Paint/views/index.jade~
Normal file
|
@ -0,0 +1,22 @@
|
|||
!!! 5
|
||||
html
|
||||
head
|
||||
title= title
|
||||
link(rel='stylesheet', href='/stylesheets/bootstrap.min.css')
|
||||
body
|
||||
div.topbar.navbar.navbar-fixed-top
|
||||
div.fill
|
||||
div.container
|
||||
a(href='/').brand #{title}
|
||||
div.hero-unit
|
||||
h1 Heading
|
||||
div.content
|
||||
div.row
|
||||
div.span12
|
||||
h2 Sub-Heading
|
||||
ul.unstyled.indent
|
||||
|
||||
div#footer.footer
|
||||
p © nodeblox 2011
|
||||
script(type='text/javascript', src='/javascripts/bootstrap.min.js')
|
||||
script(type='text/javascript', src='/javascripts/index.js');
|