diff --git a/README.md b/README.md
index a8011cd..097be2f 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,6 @@ to build, run ```grunt production``` from within the ```build/``` folder. the op
third party code used in this experiment
---
-* [html5slider](http://frankyan.com/labs/html5slider/) by [fryn](https://github.com/fryn), MIT license
* [js signals](http://millermedeiros.github.io/js-signals/) by [millermedeiros](https://github.com/millermedeiros), MIT license
* [require js](http://requirejs.org/), by [jrburke](jrburke), BSD & MIT license
* [almond js](https://github.com/jrburke/almond), by [jrburke](jrburke), BSD & MIT license
diff --git a/index.html b/index.html
index 5bcdbc4..029854b 100644
--- a/index.html
+++ b/index.html
@@ -6,27 +6,31 @@
-
+
glitch images
drag an image into the browser window to modify it. this script corrupts some bytes in a jpg image. because of the way jpg encoding works, the corrupted file still shows something. inspired by soulwire s experiment in flash. this experiment was created by georg . you can follow him on twitter or explore the source code on github .
if you like this one, you can check out some of his other javascript experiments .
diff --git a/scripts/lib/html5slider.js b/scripts/lib/html5slider.js
deleted file mode 100644
index ec96c69..0000000
--- a/scripts/lib/html5slider.js
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
-html5slider - a JS implementation of for Firefox 16 and up
-https://github.com/fryn/html5slider
-
-Copyright (c) 2010-2013 Frank Yan,
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-(function() {
-
-// test for native support
-var test = document.createElement('input');
-try {
- test.type = 'range';
- if (test.type == 'range')
- return;
-} catch (e) {
- return;
-}
-
-// test for required property support
-test.style.background = 'linear-gradient(red, red)';
-if (!test.style.backgroundImage || !('MozAppearance' in test.style) ||
- !document.mozSetImageElement || !this.MutationObserver)
- return;
-
-var scale;
-var isMac = navigator.platform == 'MacIntel';
-var thumb = {
- radius: isMac ? 9 : 6,
- width: isMac ? 22 : 12,
- height: isMac ? 16 : 20
-};
-var track = 'linear-gradient(transparent ' + (isMac ?
- '6px, #999 6px, #999 7px, #ccc 8px, #bbb 9px, #bbb 10px, transparent 10px' :
- '9px, #999 9px, #bbb 10px, #fff 11px, transparent 11px') +
- ', transparent)';
-var styles = {
- 'min-width': thumb.width + 'px',
- 'min-height': thumb.height + 'px',
- 'max-height': thumb.height + 'px',
- padding: '0 0 ' + (isMac ? '2px' : '1px'),
- border: 0,
- 'border-radius': 0,
- cursor: 'default',
- 'text-indent': '-999999px' // -moz-user-select: none; breaks mouse capture
-};
-var options = {
- attributes: true,
- attributeFilter: ['min', 'max', 'step', 'value']
-};
-var forEach = Array.prototype.forEach;
-var onInput = document.createEvent('HTMLEvents');
-onInput.initEvent('input', true, false);
-var onChange = document.createEvent('HTMLEvents');
-onChange.initEvent('change', true, false);
-
-if (document.readyState == 'loading')
- document.addEventListener('DOMContentLoaded', initialize, true);
-else
- initialize();
-
-function initialize() {
- // create initial sliders
- forEach.call(document.querySelectorAll('input[type=range]'), transform);
- // create sliders on-the-fly
- new MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- if (mutation.addedNodes)
- forEach.call(mutation.addedNodes, function(node) {
- check(node);
- if (node.childElementCount)
- forEach.call(node.querySelectorAll('input'), check);
- });
- });
- }).observe(document, { childList: true, subtree: true });
-}
-
-function check(input) {
- if (input.localName == 'input' && input.type != 'range' &&
- input.getAttribute('type') == 'range')
- transform(input);
-}
-
-function transform(slider) {
-
- var isValueSet, areAttrsSet, isChanged, isClick, prevValue, rawValue, prevX;
- var min, max, step, range, value = slider.value;
-
- // lazily create shared slider affordance
- if (!scale) {
- scale = document.body.appendChild(document.createElement('hr'));
- style(scale, {
- '-moz-appearance': isMac ? 'scale-horizontal' : 'scalethumb-horizontal',
- display: 'block',
- visibility: 'visible',
- opacity: 1,
- position: 'fixed',
- top: '-999999px'
- });
- document.mozSetImageElement('__sliderthumb__', scale);
- }
-
- // reimplement value and type properties
- var getValue = function() { return '' + value; };
- var setValue = function setValue(val) {
- value = '' + val;
- isValueSet = true;
- draw();
- delete slider.value;
- slider.value = value;
- Object.defineProperty(slider, 'value', {
- get: getValue,
- set: setValue
- });
- };
- Object.defineProperty(slider, 'value', {
- get: getValue,
- set: setValue
- });
- Object.defineProperty(slider, 'type', {
- get: function() { return 'range'; }
- });
-
- // sync properties with attributes
- ['min', 'max', 'step'].forEach(function(prop) {
- if (slider.hasAttribute(prop))
- areAttrsSet = true;
- Object.defineProperty(slider, prop, {
- get: function() { return this.hasAttribute(prop) ? this.getAttribute(prop) : ''; },
- set: function(val) { val === null ? this.removeAttribute(prop) : this.setAttribute(prop, val); }
- });
- });
-
- // initialize slider
- slider.readOnly = true;
- style(slider, styles);
- update();
-
- new MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- if (mutation.attributeName != 'value') {
- update();
- areAttrsSet = true;
- }
- // note that value attribute only sets initial value
- else if (!isValueSet) {
- value = slider.getAttribute('value');
- draw();
- }
- });
- }).observe(slider, options);
-
- slider.addEventListener('mousedown', onDragStart, true);
- slider.addEventListener('keydown', onKeyDown, true);
- slider.addEventListener('focus', onFocus, true);
- slider.addEventListener('blur', onBlur, true);
-
- function onDragStart(e) {
- isClick = true;
- setTimeout(function() { isClick = false; }, 0);
- if (e.button || !range)
- return;
- var width = parseFloat(getComputedStyle(this, 0).width);
- var multiplier = (width - thumb.width) / range;
- if (!multiplier)
- return;
- // distance between click and center of thumb
- var dev = e.clientX - this.getBoundingClientRect().left - thumb.width / 2 -
- (value - min) * multiplier;
- // if click was not on thumb, move thumb to click location
- if (Math.abs(dev) > thumb.radius) {
- isChanged = true;
- this.value -= -dev / multiplier;
- }
- rawValue = value;
- prevX = e.clientX;
- this.addEventListener('mousemove', onDrag, true);
- this.addEventListener('mouseup', onDragEnd, true);
- }
-
- function onDrag(e) {
- var width = parseFloat(getComputedStyle(this, 0).width);
- var multiplier = (width - thumb.width) / range;
- if (!multiplier)
- return;
- rawValue += (e.clientX - prevX) / multiplier;
- prevX = e.clientX;
- isChanged = true;
- this.value = rawValue;
- }
-
- function onDragEnd() {
- this.removeEventListener('mousemove', onDrag, true);
- this.removeEventListener('mouseup', onDragEnd, true);
- slider.dispatchEvent(onChange);
- }
-
- function onKeyDown(e) {
- if (e.keyCode > 36 && e.keyCode < 41) { // 37-40: left, up, right, down
- onFocus.call(this);
- isChanged = true;
- this.value = value + (e.keyCode == 38 || e.keyCode == 39 ? step : -step);
- }
- }
-
- function onFocus() {
- if (!isClick)
- this.style.boxShadow = !isMac ? '0 0 0 2px #fb0' :
- 'inset 0 0 20px rgba(0,127,255,.1), 0 0 1px rgba(0,127,255,.4)';
- }
-
- function onBlur() {
- this.style.boxShadow = '';
- }
-
- // determines whether value is valid number in attribute form
- function isAttrNum(value) {
- return !isNaN(value) && +value == parseFloat(value);
- }
-
- // validates min, max, and step attributes and redraws
- function update() {
- min = isAttrNum(slider.min) ? +slider.min : 0;
- max = isAttrNum(slider.max) ? +slider.max : 100;
- if (max < min)
- max = min > 100 ? min : 100;
- step = isAttrNum(slider.step) && slider.step > 0 ? +slider.step : 1;
- range = max - min;
- draw(true);
- }
-
- // recalculates value property
- function calc() {
- if (!isValueSet && !areAttrsSet)
- value = slider.getAttribute('value');
- if (!isAttrNum(value))
- value = (min + max) / 2;;
- // snap to step intervals (WebKit sometimes does not - bug?)
- value = Math.round((value - min) / step) * step + min;
- if (value < min)
- value = min;
- else if (value > max)
- value = min + ~~(range / step) * step;
- }
-
- // renders slider using CSS background ;)
- function draw(attrsModified) {
- calc();
- if (isChanged && value != prevValue)
- slider.dispatchEvent(onInput);
- isChanged = false;
- if (!attrsModified && value == prevValue)
- return;
- prevValue = value;
- var position = range ? (value - min) / range * 100 : 0;
- var bg = '-moz-element(#__sliderthumb__) ' + position + '% no-repeat, ';
- style(slider, { background: bg + track });
- }
-
-}
-
-function style(element, styles) {
- for (var prop in styles)
- element.style.setProperty(prop, styles[prop], 'important');
-}
-
-})();
diff --git a/scripts/main.js b/scripts/main.js
index 906cee6..c637a5b 100644
--- a/scripts/main.js
+++ b/scripts/main.js
@@ -23,8 +23,7 @@ require(
'src/import-button',
'src/random-button',
'util/feature-test',
- 'lib/signals-1.0.0',
- 'lib/html5slider'
+ 'lib/signals-1.0.0'
],
function(
process,
diff --git a/scripts/src/controls.js b/scripts/src/controls.js
index 33ab075..fc7c297 100644
--- a/scripts/src/controls.js
+++ b/scripts/src/controls.js
@@ -5,6 +5,7 @@ define(
var values = { };
var is_initialized = false;
var signals;
+ var controls;
function init( shared )
{
@@ -13,7 +14,7 @@ define(
if ( shared.feature['query-selector-all'] )
{
var wrapper = document.getElementById( 'controls' );
- var controls = document.querySelectorAll( '.control-input' );
+ controls = wrapper.querySelectorAll( '.control-input' );
wrapper.className += ' is-active';
@@ -21,9 +22,10 @@ define(
{
var control = controls[i];
- control.addEventListener( 'change', controlUpdated, false );
- updateValue( control.id, control.value );
- updateValueInUI( control.id, control.value );
+ control.addEventListener( 'input', controlUpdated, false );
+
+ updateValue( getInputKey( control.id ), control.value );
+ updateInput( getCorrespondingInput( control.id ), control.value );
}
is_initialized = true;
@@ -40,22 +42,24 @@ define(
element = element.target;
}
- updateValue( element.id, element.value );
- updateValueInUI( element.id, element.value );
+ updateValue( getInputKey( element.id ), element.value );
+ updateInput( getCorrespondingInput( element.id ), element.value );
}
function setControlValues( new_values )
{
var control;
+ var updated_values = { };
for ( var id in new_values )
{
- control = document.getElementById( id );
+ control = getCorrespondingInput( id );
control.value = new_values[id];
controlUpdated( control );
+ updated_values[ getInputKey( id ) ] = new_values[id];
}
- values = new_values;
+ values = updated_values;
signals['control-updated'].dispatch( values );
}
@@ -69,10 +73,40 @@ define(
}
}
- function updateValueInUI( key, value )
+ function updateInput( input, value )
{
- var el = document.querySelectorAll( 'label[for="' + key + '"] .control-slider-value' )[0];
- el.innerHTML = value;
+ if ( input.value !== value )
+ {
+ input.value = value;
+ }
+ }
+
+ function getCorrespondingInput( id )
+ {
+ var result;
+ var key = getInputKey( id );
+ var element_id;
+
+ for ( var i = 0, len = controls.length; i < len; i++ )
+ {
+ element_id = controls[i].id;
+
+ if (
+ element_id !== id &&
+ element_id.indexOf( key ) !== -1
+ )
+ {
+ result = controls[i];
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ function getInputKey( id )
+ {
+ return id.replace( '-slider', '' ).replace( '-number', '' );
}
return { init: init };
diff --git a/scripts/src/random-button.js b/scripts/src/random-button.js
index 4d3bb5e..f14cb8a 100644
--- a/scripts/src/random-button.js
+++ b/scripts/src/random-button.js
@@ -13,14 +13,13 @@ define(
if ( shared.feature['query-selector-all'] )
{
- controls = document.querySelectorAll( '.control-input' );
+ controls = document.querySelectorAll( '.control-slider' );
constraints = getConstraints( controls );
random_button = document.getElementById( 'random-button' );
random_button.addEventListener( 'click', buttonClicked, false );
random_button.classList.remove( 'is-hidden' );
}
-
}
function buttonClicked( event )
diff --git a/styles/main.css b/styles/main.css
index 26d1ab6..d71da37 100644
--- a/styles/main.css
+++ b/styles/main.css
@@ -63,8 +63,7 @@ a:hover
margin-bottom: 10px;
}
-.content,
-.missing-feature
+.intro
{
max-width: 650px;
}
@@ -84,7 +83,7 @@ a:hover
.control-wrapper
{
float: left;
- width: 100px;
+ width: 200px;
margin-right: 20px;
}
@@ -94,19 +93,29 @@ a:hover
color: #666;
}
- .control-slider-value
- {
- display: inline-block;
- color: #333;
- float: right;
- }
-
- .control-input
+ .control-slider
{
display: block;
- width: 100px;
+ float: left;
+ border: none;
+ width: 160px;
+ height: 1px;
+ margin-top: 6px;
+ background: #ddd;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
}
+ .control-number
+ {
+ display: block;
+ color: #333;
+ float: right;
+ border: none;
+ max-width: 30px;
+ font-family: sans-serif;
+ }
#import-input
{