Repository: tholman/texter
Branch: master
Commit: b03e4859fe35
Files: 4
Total size: 14.8 KB
Directory structure:
gitextract_j3q82qwt/
├── css/
│ └── style.css
├── index.html
└── js/
├── header.js
└── texter.js
================================================
FILE CONTENTS
================================================
================================================
FILE: css/style.css
================================================
html, body {
width: 100%;
height: 100%;
margin: 0px;
overflow: hidden;
}
canvas {
position: absolute;
cursor: crosshair;
-webkit-user-select: none;
}
/* ----- INFO & SHARING ----- */
#back {
font-family: Helvetica, Arial, "Lucida Grande";
position: fixed;
top: 7px;
width: 190px;
height: 36px;
box-shadow: 0px 0px 4px 0px #888;
line-height: 10px;
left: -153px;
background: #fff;
z-index: 1000;
-webkit-transition: left 250ms;
-moz-transition: left 250ms;
-o-transition: left 250ms;
-ms-trantion: left 250ms;
transition: left 250ms;
}
#back.open {
left: 0px;
}
#back a {
color: #1C86EE;
margin-left: 0px;
margin-right: 0px;
padding: 13px;
padding-right: 0px;
position: absolute;
}
#back a:hover {
color: hotpink;
}
#back span {
font-size: 50px;
line-height: 0px;
color: #444;
text-decoration: none;
font-family: Times;
position: absolute;
right: 10px;
top: 17px;
-webkit-margin-before: -3px;
}
#info-tab * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box
}
#info-tab {
font-family: Helvetica, Arial, "Lucida Grande";
-webkit-box-shadow: 0px 0px 4px 0px #888;
box-shadow: 0px 0px 4px 0px #888;
-webkit-transition: left 300ms, -webkit-box-shadow 500ms;
-moz-transition: left 300ms, -moz-box-shadow 500ms;
-o-transition: left 300ms, -o-box-shadow 500ms;
-ms-trantion: left 300ms, -ms-box-shadow 500ms;
transition: left 300ms, box-shadow 500ms;
background-color: #ffffff;
height: 150px;
position: fixed;
padding-left: 5px;
line-height: 36px;
width: 630px;
margin-top: 11px;
font-size: 17px;
color: #444;
left: -598px;
z-index: 1000;
top: 40px;
}
#info-tab.open {
left: 0px;
}
#info-tab.highlight {
-webkit-box-shadow: 0px 0px 12px 0px #222;
box-shadow: 0px 0px 12px 0px #222;
}
#info-tab.open #title {
opacity: 0;
}
#info-tab #title {
-webkit-transition: opacity 300ms;
-moz-transition: opacity 300ms;
-o-transition: opacity 300ms;
-ms-trantion: opacity 300ms;
transition: opacity 300ms;
-webkit-transform: rotate( 90deg ) translateZ(0px);
-moz-transform: rotate( 90deg ) translateZ(0px);
-ms-transform: rotate( 90deg ) translateZ(0px);
-o-transform: rotate( 90deg ) translateZ(0px);
transform: rotate( 90deg ) translateZ(0px);
-webkit-transform-origin: 100% 0%;
-moz-transform-origin: 100% 0%;
-ms-transform-origin: 100% 0%;
-o-transform-origin: 100% 0%;
transform-origin: 100% 0%;
float: right;
width: 150px;
height: 30px;
position: absolute;
text-align: center;
right: 0px;
bottom: -30px;
}
#info-tab .info {
margin-left: 18px;
font-size: 14px;
line-height: 16px;
height: 110px;
width: 282px;
float: left;
padding-right: 18px;
margin-top: 20px;
margin-bottom: 20px;
color: #111;
margin-right: 5px;
position: relative;
}
#info-tab .first {
border-right: 1px solid #ddd;
}
#info-tab p {
position: absolute;
bottom: 0px;
font-size: 12px;
margin: 0px;
}
#info-tab a {
color: #1C86EE;
}
#info-tab a:hover {
color: hotpink;
}
#info-tab iframe {
vertical-align: bottom;
}
================================================
FILE: index.html
================================================
Texter - Draw with Words
Texter is a little javascript experiment that lets you explore
your creativity by drawing with words. This app is an extension of a
demo from this
book
Made by: Tim Holman -
@twholman
This has been made using
Javascript and the HTML5
canvas element. You can find the source on
Github . If you feel like supporting me, you can always
buy me a coffee .
Texter
================================================
FILE: js/header.js
================================================
var headers = [
document.getElementById("back"),
document.getElementById("info-tab"),
];
var headerMouseDown = false;
var headerToggleTimeOut = [];
document.addEventListener(
"mousedown",
function () {
headerMouseDown = true;
},
false
);
document.addEventListener(
"mouseup",
function () {
headerMouseDown = false;
},
false
);
for (var i = 0; i < headers.length; i++) {
headerToggleTimeOut.push(-1);
headers[i].addEventListener(
"mouseover",
function () {
if (!headerMouseDown) {
interval = clearInterval(interval);
var _this = this;
clearTimeout(headerToggleTimeOut);
headerToggleTimeOut[i] = setTimeout(function () {
_this.setAttribute("class", "open");
}, 50);
}
},
false
);
headers[i].addEventListener(
"mouseout",
function () {
var _this = this;
clearTimeout(headerToggleTimeOut);
headerToggleTimeOut[i] = setTimeout(function () {
_this.setAttribute("class", "");
}, 50);
},
false
);
}
function pulseHeader() {
if (interval == undefined) {
return;
}
headers[1].setAttribute("class", "highlight");
setTimeout(function () {
if (interval == undefined) {
return;
}
headers[1].setAttribute("class", "");
setTimeout(function () {
if (interval == undefined) {
return;
}
headers[1].setAttribute("class", "highlight");
setTimeout(function () {
if (interval == undefined) {
return;
}
headers[1].setAttribute("class", "");
}, 400);
}, 400);
}, 400);
}
var interval = setInterval(function () {
pulseHeader();
}, 10000);
================================================
FILE: js/texter.js
================================================
/*
* Texter - Drawing with Text.
* - Ported from demo in Generative Design book - http://www.generative-gestaltung.de
* - generative-gestalung.de original licence: http://www.apache.org/licenses/LICENSE-2.0
*
* - Modified and maintained by Tim Holman - tholman.com - @twholman
*/
function Texter() {
var _this = this;
// Application variables
position = { x: 0, y: window.innerHeight / 2 };
textIndex = 0;
this.textColor = "#000000";
this.bgColor = "#ffffff";
this.minFontSize = 8;
this.maxFontSize = 300;
this.angleDistortion = 0.01;
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
var urlText = urlParams.get('text')
this.text = urlText ||
"There was a table set out under a tree in front of the house, and the March Hare and the Hatter were having tea at it: a Dormouse was sitting between them, fast asleep, and the other two were using it as a cushion, resting their elbows on it, and talking over its head. 'Very uncomfortable for the Dormouse,' thought Alice; 'only, as it's asleep, I suppose it doesn't mind.'";
// Drawing Variables
canvas = null;
context = null;
mouse = { x: 0, y: 0, down: false };
bgCanvas = null;
bgContext = null;
this.initialize = function () {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.addEventListener("mousemove", onMove, false);
canvas.addEventListener("mousedown", onDown, false);
canvas.addEventListener("mouseup", onUp, false);
canvas.addEventListener("mouseout", onUp, false);
canvas.addEventListener("touchstart", onDown, false);
canvas.addEventListener("touchmove", onMove, false);
canvas.addEventListener("touchend", onUp, false);
canvas.addEventListener("touchcancel", onUp, false);
bgCanvas = document.createElement("canvas");
bgContext = bgCanvas.getContext("2d");
bgCanvas.width = canvas.width;
bgCanvas.height = canvas.height;
_this.setBackground(_this.bgColor);
window.onresize = function (event) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
bgCanvas.width = window.innerWidth;
bgCanvas.height = window.innerHeight;
_this.setBackground(_this.bgColor);
_this.clear();
};
update();
};
var update = function () {
requestAnimationFrame(update);
draw();
};
var draw = function () {
if (mouse.down) {
var newDistance = distance(position, mouse);
var fontSize = _this.minFontSize + newDistance / 2;
if (fontSize > _this.maxFontSize) {
fontSize = _this.maxFontSize;
}
var letter = _this.text[textIndex];
var stepSize = textWidth(letter, fontSize);
if (newDistance > stepSize) {
var angle = Math.atan2(mouse.y - position.y, mouse.x - position.x);
context.font = fontSize + "px Georgia";
context.save();
context.translate(position.x, position.y);
context.rotate(
angle +
(Math.random() * (_this.angleDistortion * 2) -
_this.angleDistortion)
);
context.fillText(letter, 0, 0);
context.restore();
textIndex++;
if (textIndex > _this.text.length - 1) {
textIndex = 0;
}
position.x = position.x + Math.cos(angle) * stepSize;
position.y = position.y + Math.sin(angle) * stepSize;
}
}
};
var distance = function (pt, pt2) {
var xs = 0;
var ys = 0;
xs = pt2.x - pt.x;
xs = xs * xs;
ys = pt2.y - pt.y;
ys = ys * ys;
return Math.sqrt(xs + ys);
};
var onDown = function (event) {
const eventObject = event.touches && event.touches.item(0) || event
mouse.down = true;
position.x = eventObject.pageX;
position.y = eventObject.pageY;
mouse.x = eventObject.pageX;
mouse.y = eventObject.pageY;
};
var onUp = function () {
mouse.down = false;
};
var onMove = function (event) {
const eventObject = event.touches && event.touches.item(0) || event
mouse.x = eventObject.pageX;
mouse.y = eventObject.pageY;
draw();
};
var textWidth = function (string, size) {
context.font = size + "px Georgia";
if (context.fillText) {
return context.measureText(string).width;
} else if (context.mozDrawText) {
return context.mozMeasureText(string);
}
};
this.clear = function () {
canvas.width = canvas.width;
context.fillStyle = _this.textColor;
};
this.applyNewColor = function (value) {
_this.textColor = value;
context.fillStyle = _this.textColor;
};
this.setBackground = function (value) {
_this.bgColor = value;
canvas.style.backgroundColor = value;
};
this.onTextChange = function () {
textIndex = 0;
};
this.save = function () {
// Prepare the background canvas's color
bgContext.rect(0, 0, bgCanvas.width, bgCanvas.height);
bgContext.fillStyle = _this.bgColor;
bgContext.fill();
// Draw the front canvas onto the bg canvas
bgContext.drawImage(canvas, 0, 0);
// Open in a new window
window.open(bgCanvas.toDataURL("image/png"), "mywindow");
};
}