Last active
May 23, 2023 21:56
-
-
Save denilsonsa/a518a7825e727e55b6fb to your computer and use it in GitHub Desktop.
Nosy Facetype demo http://rrry.me/nosy/ - http://www.reddit.com/r/gamedev/comments/2f9p7k/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Live demo of Nosy Facetype by Rory Harnden</title> | |
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Mono:400,400italic' rel='stylesheet' type='text/css'> | |
<style type="text/css"> | |
@font-face { | |
font-family: "Nosy"; | |
src: url(NOSY_Facetype_by_Rory_Harnden.otf) format("opentype"); | |
} | |
html { | |
background: white; | |
color: black; | |
font-family: "Ubuntu Mono", "Courier New", Courier, monospace; | |
} | |
h1 { | |
margin: 0 0 0.5em 0; | |
} | |
p { | |
margin: 1ex 0; | |
} | |
a { | |
text-decoration: none; | |
color:#f2047b; | |
} | |
a:visited { | |
color:#3bceba | |
} | |
section { | |
display: flex; | |
flex-direction: row; | |
margin-top: 1em; | |
} | |
@media (max-width: 700px) { | |
section { | |
flex-wrap: wrap; | |
} | |
} | |
.formcontrol:hover { | |
background: #EEE; | |
} | |
.formcontrol, | |
.formcontrol label, | |
.formcontrol input { | |
vertical-align: middle; | |
} | |
.formcontrol * { | |
margin-top: 0; | |
margin-bottom: 0; | |
} | |
.formcontrol label { | |
width: 8em; | |
} | |
.formcontrol label, .formcontrol input { | |
display: inline-block; | |
height: 1.5em; | |
} | |
.formcontrol .draghandle { | |
display: inline-block; | |
width: 1.5em; | |
text-align: left; | |
text-indent: 0.33em; | |
cursor: move; | |
color: black; | |
text-shadow: | |
black 0 -0.25em 0, | |
black 0 -0.50em 0, | |
black 0.25em 0 0, | |
black 0.25em -0.25em 0, | |
black 0.25em -0.50em 0; | |
} | |
.drag-moving { | |
opacity: 0.25; | |
} | |
.drag-over { | |
background: #FFC; | |
} | |
.column:first-child { | |
flex-grow: 0; | |
flex-shrink: 0; | |
margin-right:25px; | |
} | |
.column:last-child { | |
flex-grow: 1; | |
flex-shrink: 1; | |
} | |
/* | |
http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings | |
http://dev.w3.org/csswg/css-fonts/#propdef-font-variant-ligatures | |
https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings | |
https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-ligatures | |
*/ | |
#text { | |
font-family: "Nosy"; | |
word-wrap: break-word; | |
overflow-wrap: break-word; | |
-o-font-feature-settings: "liga" off; | |
-o-font-variant-ligatures: none; | |
-moz-font-feature-settings: "liga" off; | |
-moz-font-variant-ligatures: none; | |
-webkit-font-feature-settings: "liga" off; | |
-webkit-font-variant-ligatures: none; | |
font-feature-settings: "liga" off; | |
font-variant-ligatures: none; | |
} | |
#output { | |
font-family: "Nosy"; | |
font-size: 50vh; | |
line-height: 1.75em; | |
letter-spacing: 0; | |
margin-left: 0.5ex; | |
-o-font-feature-settings: "liga" on; | |
-o-font-variant-ligatures: common-ligatures; | |
-moz-font-feature-settings: "liga" on; | |
-moz-font-variant-ligatures: common-ligatures; | |
-webkit-font-feature-settings: "liga" on; | |
-webkit-font-variant-ligatures: common-ligatures; | |
font-feature-settings: "liga" on; | |
font-variant-ligatures: common-ligatures; | |
} | |
</style> | |
</head> | |
<body> | |
<h1><a href="http://rrry.me/nosy/">NOSY Facetype by Rory Harnden</a></h1> | |
<p>All the faces you're seeing on this page are being created live by the NOSY <s>typeface</s> facetype and some slightly sneaky OpenType ligatures.</p> | |
<p>Find out more and download free at <a href="http://rrry.me/nosy/" >rrry.me/nosy</a> (<a href="http://www.reddit.com/r/gamedev/comments/2f9p7k/nosy_free_typeface_that_creates_characters_just/" >thread on reddit.com/r/gamedev</a>). Font by <a href="http://rrry.me/">Rory Harnden</a>, demo by <a href="http://denilson.sa.nom.br/">Denilson Sá</a> (also on <a href="https://gist.github.com/denilsonsa/a518a7825e727e55b6fb">GitHub Gist</a>).</p> | |
<section> | |
<div class="column"> | |
<form id="form_with_controls"> | |
<div class="column"> | |
</div> | |
</form> | |
</div> | |
<div class="column"> | |
<div> | |
<input type="button" id="randomize_button" value="Randomize!"> | |
<input type="button" id="disable_all_button" value="Remove all!"> | |
</div> | |
<div id="text"></div> | |
<div id="output"></div> | |
</div> | |
</section> | |
<script> | |
var parts = [ | |
// name, min, max, color, probability of being enabled. | |
['face' , 1, 1, '#f1dabf', 1.0], | |
['ears' , 1, 9, '#f1dabf', 0.5], | |
['mask' , 1, 9, '#f40e3f', 0.2], | |
['glassesalt', 1, 5, '#e6db94', 0.2], | |
['eyes' , 1, 9, '#392d2f', 1.0], | |
['mouth' , 1, 9, '#39d59b', 0.9], | |
['mouthalt' , 1, 9, '#00c9ef', 0.5], | |
['cheeks' , 1, 9, '#ef3527', 0.3], | |
['eyebrows' , 1, 9, '#422f28', 0.4], | |
['glasses' , 1, 5, '#b31e43', 0.2], | |
['hair' , 1, 9, '#422f28', 0.4], | |
['hat' , 1, 9, '#b31e43', 0.1], | |
['skin' , 1, 5, '#302238', 0.3], | |
['beard' , 1, 5, '#00c9ef', 0.3], | |
['moustache' , 1, 5, '#4ec500', 0.4], | |
['nose' , 1, 9, '#25b68f', 0.4] | |
]; | |
function createFormControl(name, value, min, max, color) { | |
var container = document.createElement('div'); | |
container.setAttribute('class', 'formcontrol feature'); | |
container.dataset.name = name; | |
container.innerHTML = '<span class="draghandle" draggable="true">.</span><label><input type="checkbox" name="' + name + '_enabled" checked>' + name + '</label><input type="range" name="' + name + '_number" value="' + value + '" min="' + min + '" max="' + max + '" step="1"><input type="color" name="' + name + '_color" value="' + color + '"></div>'; | |
return container; | |
} | |
function createAllControls() { | |
var form = document.getElementById('form_with_controls'); | |
form.addEventListener('submit', function(ev) { ev.preventDefault(); }); | |
form.addEventListener('input', update_face); | |
form.addEventListener('change', update_face); | |
var randomize_button = document.getElementById('randomize_button'); | |
randomize_button.addEventListener('click', randomize); | |
var disable_all_button = document.getElementById('disable_all_button'); | |
disable_all_button.addEventListener('click', disable_all); | |
parts.forEach(function(currentValue, index, arr) { | |
var control = createFormControl(currentValue[0], 1, currentValue[1], currentValue[2], currentValue[3]); | |
form.appendChild(control); | |
new Dragster(control); | |
control.addEventListener('dragover', handle_drag_over); | |
control.addEventListener('dragster:enter', handle_dragster_enter); | |
control.addEventListener('dragster:leave', handle_dragster_leave); | |
control.addEventListener('dragend', handle_drag_end); | |
control.addEventListener('drop', handle_drop); | |
var draghandle = control.querySelector('.draghandle'); | |
draghandle.addEventListener('dragstart', handle_drag_start); | |
}); | |
} | |
function randomize() { | |
var form = document.getElementById('form_with_controls'); | |
parts.forEach(function(currentValue, index, arr) { | |
var name = currentValue[0]; | |
form[name + '_enabled'].checked = Math.random() < currentValue[4] ? true : false; | |
form[name + '_number'].value = Math.floor(Math.random() * currentValue[2]) + 1; | |
}); | |
update_face(); | |
} | |
function disable_all() { | |
var form = document.getElementById('form_with_controls'); | |
parts.forEach(function(currentValue, index, arr) { | |
var name = currentValue[0]; | |
if (name == 'face') { | |
form[name + '_enabled'].checked = true; | |
} else { | |
form[name + '_enabled'].checked = false; | |
} | |
}); | |
update_face(); | |
} | |
function update_face() { | |
var form = document.getElementById('form_with_controls'); | |
var output = document.getElementById('output'); | |
var text = document.getElementById('text'); | |
var controls = form.querySelectorAll('.feature'); | |
var features = []; | |
[].forEach.call(controls, function(elem, index, arr) { | |
features.push(elem.dataset.name); | |
}); | |
var output_html = ''; | |
features.forEach(function(name, index, arr) { | |
if (form[name + '_enabled'].checked) { | |
output_html += '<span style="color: ' + form[name + '_color'].value + '">' + name.toUpperCase() + form[name + '_number'].value + '</span>'; | |
} | |
}); | |
text.innerHTML = output_html; | |
output.innerHTML = output_html; | |
} | |
// https://bensmithett.github.io/dragster/ | |
// https://github.com/bensmithett/dragster | |
(function() { | |
var Dragster, | |
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | |
Dragster = (function() { | |
function Dragster(el) { | |
this.el = el; | |
this.dragleave = __bind(this.dragleave, this); | |
this.dragenter = __bind(this.dragenter, this); | |
if (this.supportsEventConstructors()) { | |
this.first = false; | |
this.second = false; | |
this.el.addEventListener("dragenter", this.dragenter, false); | |
this.el.addEventListener("dragleave", this.dragleave, false); | |
} | |
} | |
Dragster.prototype.dragenter = function(event) { | |
if (this.first) { | |
return this.second = true; | |
} else { | |
this.first = true; | |
return this.el.dispatchEvent(new CustomEvent('dragster:enter', { | |
bubbles: true, | |
cancelable: true, | |
detail: { | |
dataTransfer: event.dataTransfer | |
} | |
})); | |
} | |
}; | |
Dragster.prototype.dragleave = function(event) { | |
if (this.second) { | |
this.second = false; | |
} else if (this.first) { | |
this.first = false; | |
} | |
if (!this.first && !this.second) { | |
return this.el.dispatchEvent(new CustomEvent('dragster:leave', { | |
bubbles: true, | |
cancelable: true, | |
detail: { | |
dataTransfer: event.dataTransfer | |
} | |
})); | |
} | |
}; | |
Dragster.prototype.removeListeners = function() { | |
this.el.removeEventListener("dragenter", this.dragenter, false); | |
return this.el.removeEventListener("dragleave", this.dragleave, false); | |
}; | |
Dragster.prototype.supportsEventConstructors = function() { | |
try { | |
new CustomEvent("z"); | |
} catch (_error) { | |
return false; | |
} | |
return true; | |
}; | |
Dragster.prototype.reset = function() { | |
this.first = false; | |
return this.second = false; | |
}; | |
return Dragster; | |
})(); | |
window.Dragster = Dragster; | |
}).call(this); | |
// Based on: http://jsfiddle.net/james2doyle/UEx7U/ | |
// See also: http://www.html5rocks.com/en/tutorials/dnd/basics/ | |
// See also: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations | |
function handle_drag_start(ev) { | |
var formcontrol = ev.currentTarget; | |
while (formcontrol && formcontrol.classList && !formcontrol.classList.contains('formcontrol')) { | |
formcontrol = formcontrol.parentNode; | |
} | |
if (!formcontrol.classList || !formcontrol.classList.contains('formcontrol')) { | |
return; | |
} | |
formcontrol.classList.add('drag-moving'); | |
ev.dataTransfer.effectAllowed = 'move'; | |
ev.dataTransfer.setData('text/plain', 'moving:' + formcontrol.dataset.name); | |
} | |
function handle_drag_over(ev) { | |
var formcontrol = ev.currentTarget; | |
if (!formcontrol.classList.contains('formcontrol')) { | |
return; | |
} | |
ev.preventDefault(); | |
} | |
function handle_dragster_enter(ev) { | |
var formcontrol = this; | |
if (!formcontrol.classList.contains('formcontrol')) { | |
return; | |
} | |
var data = ev.detail.dataTransfer.getData('text/plain'); | |
if (data.substr(0, 7) != 'moving:') { | |
return; | |
} | |
formcontrol.classList.add('drag-over'); | |
ev.preventDefault(); | |
} | |
function handle_dragster_leave(ev) { | |
var formcontrol = this; | |
if (!formcontrol.classList.contains('formcontrol')) { | |
return; | |
} | |
var data = ev.detail.dataTransfer.getData('text/plain'); | |
if (data.substr(0, 7) != 'moving:') { | |
return; | |
} | |
formcontrol.classList.remove('drag-over'); | |
ev.preventDefault(); | |
} | |
function handle_drag_end(ev) { | |
var formcontrol = ev.currentTarget.classList.remove('drag-moving'); | |
var elements = document.getElementsByClassName('drag-over'); | |
[].forEach.call(elements, function(elem, index, arr) { | |
elem.classList.remove('drag-over'); | |
}); | |
} | |
function handle_drop(ev) { | |
var formcontrol = ev.currentTarget; | |
if (!formcontrol.classList.contains('formcontrol')) { | |
return; | |
} | |
var data = ev.dataTransfer.getData('text/plain'); | |
if (data.substr(0, 7) != 'moving:') { | |
return; | |
} | |
var form = document.getElementById('form_with_controls'); | |
var from_element = form.getElementsByClassName('drag-moving')[0]; | |
var to_element = formcontrol; | |
if (from_element == to_element) { | |
ev.preventDefault(); | |
return; | |
} | |
var from_index = [].indexOf.call(form.childNodes, from_element); | |
var to_index = [].indexOf.call(form.childNodes, to_element); | |
var before_this = to_element; | |
if (from_index < to_index) { | |
before_this = to_element.nextSibling; | |
} | |
form.insertBefore(from_element, before_this); | |
ev.preventDefault(); | |
update_face(); | |
} | |
createAllControls(); | |
randomize(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment