<commit_before>/*jslint browser:true, plusplus:true, vars:true */
/*jshint browser:true, jquery:true */
/*jshint -W040:false */ /* to don't alert on "this" in triggerLoadOrError */

(function ($, window, document, undefined) {
    'use strict';

    // options
    var lazyLoadXT = 'lazyLoadXT',
        dataLazied = 'lazied',
        load_error = 'load error',
        classLazyHidden = 'lazy-hidden',
        docElement = document.documentElement || document.body,
    //  force load all images in Opera Mini and some mobile browsers without scroll event or getBoundingClientRect()
        forceLoad = (window.onscroll === undefined || !!window.operamini || !docElement.getBoundingClientRect),
        options = {
            autoInit: true, // auto initialize in $.ready
            selector: 'img[data-src]', // selector for lazyloading elements
            blankImage: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
            throttle: 99, // interval (ms) for changes check
            forceLoad: forceLoad, // force auto load all images

            loadEvent: 'pageshow', // check AJAX-loaded content in jQueryMobile
            updateEvent: 'load orientationchange resize scroll touchmove focus', // page-modified events
            forceEvent: '', // force loading of all elements

            //onstart: null,
            oninit: {removeClass: 'lazy'}, // init handler
            onshow: {addClass: classLazyHidden}, // start loading handler
            onload: {removeClass: classLazyHidden, addClass: 'lazy-loaded'}, // load success handler
            onerror: {removeClass: classLazyHidden}, // error handler
            //oncomplete: null, // complete handler

            //scrollContainer: undefined,
            checkDuplicates: true
        },
        elementOptions = {
            srcAttr: 'data-src',
            edgeX: 0,
            edgeY: 0,
            visibleOnly: true
        },
        $window = $(window),
        $isFunction = $.isFunction,
        $extend = $.extend,
        $data = $.data || function (el, name) {
            return $(el).data(name);
        },
    // $.contains is not included into DOMtastic, so implement it there
        $contains = $.contains || function (parent, el) {
            while (el = el.parentNode) {
                if (el === parent) {
                    return true;
                }
            }
            return false;
        },
        elements = [],
        topLazy = 0,
    /*
     waitingMode=0 : no setTimeout
     waitingMode=1 : setTimeout, no deferred events
     waitingMode=2 : setTimeout, deferred events
     */
        waitingMode = 0;

    $[lazyLoadXT] = $extend(options, elementOptions, $[lazyLoadXT]);

    /**
     * Return options.prop if obj.prop is undefined, otherwise return obj.prop
     * @param {*} obj
     * @param {*} prop
     * @returns *
     */
    function getOrDef(obj, prop) {
        return obj[prop] === undefined ? options[prop] : obj[prop];
    }

    /**
     * @returns {number}
     */
    function scrollTop() {
        var scroll = window.pageYOffset;
        return (scroll === undefined) ? docElement.scrollTop : scroll;
    }

    /**
     * Add new elements to lazy-load list:
     * $(elements).lazyLoadXT() or $(window).lazyLoadXT()
     *
     * @param {object} [overrides] override global options
     */
    $.fn[lazyLoadXT] = function (overrides) {
        overrides = overrides || {};

        var blankImage = getOrDef(overrides, 'blankImage'),
            checkDuplicates = getOrDef(overrides, 'checkDuplicates'),
            scrollContainer = getOrDef(overrides, 'scrollContainer'),
            elementOptionsOverrides = {},
            prop;

        // empty overrides.scrollContainer is supported by both jQuery and Zepto
        $(scrollContainer).on('scroll', queueCheckLazyElements);

        for (prop in elementOptions) {
            elementOptionsOverrides[prop] = getOrDef(overrides, prop);
        }

        return this.each(function (index, el) {
            if (el === window) {
                $(options.selector).lazyLoadXT(overrides);
            } else {
                // prevent duplicates
                if (checkDuplicates && $data(el, dataLazied)) {
                    return;
                }

                var $el = $(el).data(dataLazied, 1);

                if (blankImage && el.tagName === 'IMG' && !el.src) {
                    el.src = blankImage;
                }

                // clone elementOptionsOverrides object
                $el[lazyLoadXT] = $extend({}, elementOptionsOverrides);

                triggerEvent('init', $el);

                elements.push($el);
                queueCheckLazyElements();
            }
        });
    };

    /**
     * Process function/object event handler
     * @param {string} event suffix
     * @param {jQuery} $el
     */
    function triggerEvent(event, $el) {
        var handler = options['on' + event];
        if (handler) {
            if ($isFunction(handler)) {
                handler.call($el[0]);
            } else {
                if (handler.addClass) {
                    $el.addClass(handler.addClass);
                }
                if (handler.removeClass) {
                    $el.removeClass(handler.removeClass);
                }
            }
        }

        $el.trigger('lazy' + event, [$el]);

        // queue next check as images may be resized after loading of actual file
        queueCheckLazyElements();
    }

    /**
     * Trigger onload/onerror handler
     * @param {Event} e
     */
    function triggerLoadOrError(e) {
        triggerEvent(e.type, $(this).off(load_error, triggerLoadOrError));
    }

    /**
     * Load visible elements
     * @param {bool} [force] loading of all elements
     */
    function checkLazyElements(force) {
        if (!elements.length) {
            return;
        }

        force = force || options.forceLoad;

        topLazy = Infinity;

        var viewportTop = scrollTop(),
            viewportHeight = window.innerHeight || docElement.clientHeight,
            viewportWidth = window.innerWidth || docElement.clientWidth,
            i,
            length;

        for (i = 0, length = elements.length; i < length; i++) {
            var $el = elements[i],
                el = $el[0],
                objData = $el[lazyLoadXT],
                removeNode = false,
                visible = force,
                topEdge;

            // remove items that are not in DOM
            if (!$contains(docElement, el)) {
                removeNode = true;
            } else if (force || !objData.visibleOnly || el.offsetWidth || el.offsetHeight) {

                if (!visible) {
                    var elPos = el.getBoundingClientRect(),
                        edgeX = objData.edgeX,
                        edgeY = objData.edgeY;

                    topEdge = (elPos.top + viewportTop - edgeY) - viewportHeight;

                    visible = (topEdge <= viewportTop && elPos.bottom > -edgeY &&
                        elPos.left <= viewportWidth + edgeX && elPos.right > -edgeX);
                }

                if (visible) {
                    triggerEvent('show', $el);

                    var srcAttr = objData.srcAttr,
                        src = $isFunction(srcAttr) ? srcAttr($el) : el.getAttribute(srcAttr);
                    if (src) {
                        $el.on(load_error, triggerLoadOrError);
                        el.src = src;
                    } else {
                        triggerEvent('load', $el);
                    }

                    removeNode = true;
                } else {
                    if (topEdge < topLazy) {
                        topLazy = topEdge;
                    }
                }
            }

            if (removeNode) {
                elements.splice(i--, 1);
                length--;
            }
        }

        if (!length) {
            triggerEvent('complete', $(docElement));
        }
    }

    /**
     * Run check of lazy elements after timeout
     */
    function timeoutLazyElements() {
        if (waitingMode > 1) {
            waitingMode = 1;
            checkLazyElements();
            setTimeout(timeoutLazyElements, options.throttle);
        } else {
            waitingMode = 0;
        }
    }

    /**
     * Queue check of lazy elements because of event e
     * @param {Event} [e]
     */
    function queueCheckLazyElements(e) {
        if (!elements.length) {
            return;
        }

        // fast check for scroll event without new visible elements
        if (e && e.type === 'scroll' && e.currentTarget === window) {
            if (topLazy >= scrollTop()) {
                return;
            }
        }

        if (!waitingMode) {
            setTimeout(timeoutLazyElements, 0);
        }
        waitingMode = 2;
    }

    /**
     * Initialize list of hidden elements
     */
    function initLazyElements() {
        $window.lazyLoadXT();
    }

    /**
     * Loading of all elements
     */
    function forceLoadAll() {
        checkLazyElements(true);
    }

    /**
     * Initialization
     */
    $(document).ready(function () {
        triggerEvent('start', $window);

        $window
            .on(options.loadEvent, initLazyElements)
            .on(options.updateEvent, queueCheckLazyElements)
            .on(options.forceEvent, forceLoadAll);

        $(document).on(options.updateEvent, queueCheckLazyElements);

        if (options.autoInit) {
            initLazyElements(); // standard initialization
        }
    });

})(window.jQuery || window.Zepto || window.$, window, document);<commit_msg>$.contains is included into DOMtastic since 0.7.3<commit_after>/*jslint browser:true, plusplus:true, vars:true */
/*jshint browser:true, jquery:true */
/*jshint -W040:false */ /* to don't alert on "this" in triggerLoadOrError */

(function ($, window, document, undefined) {
    'use strict';

    // options
    var lazyLoadXT = 'lazyLoadXT',
        dataLazied = 'lazied',
        load_error = 'load error',
        classLazyHidden = 'lazy-hidden',
        docElement = document.documentElement || document.body,
    //  force load all images in Opera Mini and some mobile browsers without scroll event or getBoundingClientRect()
        forceLoad = (window.onscroll === undefined || !!window.operamini || !docElement.getBoundingClientRect),
        options = {
            autoInit: true, // auto initialize in $.ready
            selector: 'img[data-src]', // selector for lazyloading elements
            blankImage: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
            throttle: 99, // interval (ms) for changes check
            forceLoad: forceLoad, // force auto load all images

            loadEvent: 'pageshow', // check AJAX-loaded content in jQueryMobile
            updateEvent: 'load orientationchange resize scroll touchmove focus', // page-modified events
            forceEvent: '', // force loading of all elements

            //onstart: null,
            oninit: {removeClass: 'lazy'}, // init handler
            onshow: {addClass: classLazyHidden}, // start loading handler
            onload: {removeClass: classLazyHidden, addClass: 'lazy-loaded'}, // load success handler
            onerror: {removeClass: classLazyHidden}, // error handler
            //oncomplete: null, // complete handler

            //scrollContainer: undefined,
            checkDuplicates: true
        },
        elementOptions = {
            srcAttr: 'data-src',
            edgeX: 0,
            edgeY: 0,
            visibleOnly: true
        },
        $window = $(window),
        $isFunction = $.isFunction,
        $extend = $.extend,
        $data = $.data || function (el, name) {
            return $(el).data(name);
        },
        elements = [],
        topLazy = 0,
    /*
     waitingMode=0 : no setTimeout
     waitingMode=1 : setTimeout, no deferred events
     waitingMode=2 : setTimeout, deferred events
     */
        waitingMode = 0;

    $[lazyLoadXT] = $extend(options, elementOptions, $[lazyLoadXT]);

    /**
     * Return options.prop if obj.prop is undefined, otherwise return obj.prop
     * @param {*} obj
     * @param {*} prop
     * @returns *
     */
    function getOrDef(obj, prop) {
        return obj[prop] === undefined ? options[prop] : obj[prop];
    }

    /**
     * @returns {number}
     */
    function scrollTop() {
        var scroll = window.pageYOffset;
        return (scroll === undefined) ? docElement.scrollTop : scroll;
    }

    /**
     * Add new elements to lazy-load list:
     * $(elements).lazyLoadXT() or $(window).lazyLoadXT()
     *
     * @param {object} [overrides] override global options
     */
    $.fn[lazyLoadXT] = function (overrides) {
        overrides = overrides || {};

        var blankImage = getOrDef(overrides, 'blankImage'),
            checkDuplicates = getOrDef(overrides, 'checkDuplicates'),
            scrollContainer = getOrDef(overrides, 'scrollContainer'),
            elementOptionsOverrides = {},
            prop;

        // empty overrides.scrollContainer is supported by both jQuery and Zepto
        $(scrollContainer).on('scroll', queueCheckLazyElements);

        for (prop in elementOptions) {
            elementOptionsOverrides[prop] = getOrDef(overrides, prop);
        }

        return this.each(function (index, el) {
            if (el === window) {
                $(options.selector).lazyLoadXT(overrides);
            } else {
                // prevent duplicates
                if (checkDuplicates && $data(el, dataLazied)) {
                    return;
                }

                var $el = $(el).data(dataLazied, 1);

                if (blankImage && el.tagName === 'IMG' && !el.src) {
                    el.src = blankImage;
                }

                // clone elementOptionsOverrides object
                $el[lazyLoadXT] = $extend({}, elementOptionsOverrides);

                triggerEvent('init', $el);

                elements.push($el);
                queueCheckLazyElements();
            }
        });
    };

    /**
     * Process function/object event handler
     * @param {string} event suffix
     * @param {jQuery} $el
     */
    function triggerEvent(event, $el) {
        var handler = options['on' + event];
        if (handler) {
            if ($isFunction(handler)) {
                handler.call($el[0]);
            } else {
                if (handler.addClass) {
                    $el.addClass(handler.addClass);
                }
                if (handler.removeClass) {
                    $el.removeClass(handler.removeClass);
                }
            }
        }

        $el.trigger('lazy' + event, [$el]);

        // queue next check as images may be resized after loading of actual file
        queueCheckLazyElements();
    }

    /**
     * Trigger onload/onerror handler
     * @param {Event} e
     */
    function triggerLoadOrError(e) {
        triggerEvent(e.type, $(this).off(load_error, triggerLoadOrError));
    }

    /**
     * Load visible elements
     * @param {bool} [force] loading of all elements
     */
    function checkLazyElements(force) {
        if (!elements.length) {
            return;
        }

        force = force || options.forceLoad;

        topLazy = Infinity;

        var viewportTop = scrollTop(),
            viewportHeight = window.innerHeight || docElement.clientHeight,
            viewportWidth = window.innerWidth || docElement.clientWidth,
            i,
            length;

        for (i = 0, length = elements.length; i < length; i++) {
            var $el = elements[i],
                el = $el[0],
                objData = $el[lazyLoadXT],
                removeNode = false,
                visible = force,
                topEdge;

            // remove items that are not in DOM
            if (!$.contains(docElement, el)) {
                removeNode = true;
            } else if (force || !objData.visibleOnly || el.offsetWidth || el.offsetHeight) {

                if (!visible) {
                    var elPos = el.getBoundingClientRect(),
                        edgeX = objData.edgeX,
                        edgeY = objData.edgeY;

                    topEdge = (elPos.top + viewportTop - edgeY) - viewportHeight;

                    visible = (topEdge <= viewportTop && elPos.bottom > -edgeY &&
                        elPos.left <= viewportWidth + edgeX && elPos.right > -edgeX);
                }

                if (visible) {
                    triggerEvent('show', $el);

                    var srcAttr = objData.srcAttr,
                        src = $isFunction(srcAttr) ? srcAttr($el) : el.getAttribute(srcAttr);
                    if (src) {
                        $el.on(load_error, triggerLoadOrError);
                        el.src = src;
                    } else {
                        triggerEvent('load', $el);
                    }

                    removeNode = true;
                } else {
                    if (topEdge < topLazy) {
                        topLazy = topEdge;
                    }
                }
            }

            if (removeNode) {
                elements.splice(i--, 1);
                length--;
            }
        }

        if (!length) {
            triggerEvent('complete', $(docElement));
        }
    }

    /**
     * Run check of lazy elements after timeout
     */
    function timeoutLazyElements() {
        if (waitingMode > 1) {
            waitingMode = 1;
            checkLazyElements();
            setTimeout(timeoutLazyElements, options.throttle);
        } else {
            waitingMode = 0;
        }
    }

    /**
     * Queue check of lazy elements because of event e
     * @param {Event} [e]
     */
    function queueCheckLazyElements(e) {
        if (!elements.length) {
            return;
        }

        // fast check for scroll event without new visible elements
        if (e && e.type === 'scroll' && e.currentTarget === window) {
            if (topLazy >= scrollTop()) {
                return;
            }
        }

        if (!waitingMode) {
            setTimeout(timeoutLazyElements, 0);
        }
        waitingMode = 2;
    }

    /**
     * Initialize list of hidden elements
     */
    function initLazyElements() {
        $window.lazyLoadXT();
    }

    /**
     * Loading of all elements
     */
    function forceLoadAll() {
        checkLazyElements(true);
    }

    /**
     * Initialization
     */
    $(document).ready(function () {
        triggerEvent('start', $window);

        $window
            .on(options.loadEvent, initLazyElements)
            .on(options.updateEvent, queueCheckLazyElements)
            .on(options.forceEvent, forceLoadAll);

        $(document).on(options.updateEvent, queueCheckLazyElements);

        if (options.autoInit) {
            initLazyElements(); // standard initialization
        }
    });

})(window.jQuery || window.Zepto || window.$, window, document);<|endoftext|>


<commit_before>(function($) {

//The timeout has to live in this scope
var timeout;

$.fn.livesearch = function(options) {
  options = options || {};
  return $(this).each(function() {
    var livesearch = $(this).data('livesearch');
		if (!livesearch) {
		  livesearch = new LiveSearch($(this), options);
			$(this).data('livesearch', livesearch);
		}
  });
};

function LiveSearch($elem, options) {
	this.$elem = $elem;
  this.$form = $elem.closest('form');
  this.options = $.extend({ delay: 400, minimum_characters: 3 }, options);
  this.last_search = false;
  this.search_xhr;
  this.cache = {};
  this.active = true;
  this._attach();
}

$.extend(LiveSearch.prototype, {
  _attach: function() {
    var _this = this;
    this.$elem.bind("keypress cut paste input", function() {
      if(!_this.active) return;

      clearTimeout(timeout);
      timeout = setTimeout(function() {_this.search_for_value();}, _this.options.delay);
    });
    this.$form.bind("submit", function(e) {
      if(!_this.active) return;

      clearTimeout(timeout);
      _this.search_for_value();
    });
    this.$elem.bind('livesearch:suspend', function() {
      _this.active = false;
    });
    this.$elem.bind('livesearch:activate', function() {
      _this.active = true;
    });
    this.$elem.bind('livesearch:cancel', function() {
      if(_this.search_xhr) _this.search_xhr.abort();
    });
  },

  search_for_value: function() {
    this.search(this.$elem.val());
  },

  suspend_while: function(func) {
    this.active = false;
    func();
    // TODO: this timeout is to to allow events to bubble before re-enabling, but I'm not sure
    // why bubbling doesn't occur synchronously.
    setTimeout(function() {
      this.active = true;
    }, 100);
  },

  search: function(value) {
    var _this = this;

    if(value == this.last_search) return;
    if(value.length < this.options.minimum_characters) return;

    if(this.search_xhr) this.search_xhr.abort();

    if(this.cache[value]) {
      this.$elem.trigger('livesearch:results', [this.cache[value]]);
    } else {
      _this.$elem.trigger('livesearch:searching');
      this.search_xhr = $.ajax({
        type: 'get',
        url: this.$form.attr('action'),
        dataType: 'json',
        data: this.$form.serialize(),
        global: false,
        success: function(data) {
            _this.$elem.trigger('livesearch:results', [data]);
            _this.cache[value] = data;
          },
        error: function() {
          _this.$elem.trigger('livesearch:ajax_error');
        }
        });
    }

    this.last_search = value;
  }

});

})(jQuery);
<commit_msg>Livesearch: a couple bug fixes.<commit_after>(function($) {

//The timeout has to live in this scope
var timeout;

$.fn.livesearch = function(options) {
  options = options || {};
  return $(this).each(function() {
    var livesearch = $(this).data('livesearch');
		if (!livesearch) {
		  livesearch = new LiveSearch($(this), options);
			$(this).data('livesearch', livesearch);
		}
  });
};

function LiveSearch($elem, options) {
	this.$elem = $elem;
  this.$form = $elem.closest('form');
  this.options = $.extend({ delay: 400, minimum_characters: 3 }, options);
  this.last_search = false;
  this.search_xhr;
  this.cache = {};
  this.active = true;
  this._attach();
}

$.extend(LiveSearch.prototype, {
  _attach: function() {
    var _this = this;
    this.$elem.bind("keypress cut paste input", function() {
      if(!_this.active) return;

      clearTimeout(timeout);
      timeout = setTimeout(function() {_this.search_for_value();}, _this.options.delay);
    });
    this.$form.bind("submit", function(e) {
      if(!_this.active) return;

      clearTimeout(timeout);
      _this.search_for_value();
    });
    this.$elem.bind('livesearch:suspend', function() {
      _this.active = false;
    });
    this.$elem.bind('livesearch:activate', function() {
      _this.active = true;
    });
    this.$elem.bind('livesearch:cancel', function() {
      if(_this.search_xhr) _this.search_xhr.abort();
      _this.last_search = false;
    });
  },

  search_for_value: function() {
    this.search(this.$elem.val());
  },

  suspend_while: function(func) {
    this.active = false;
    func();
    // TODO: this timeout is to to allow events to bubble before re-enabling, but I'm not sure
    // why bubbling doesn't occur synchronously.
    setTimeout(function() {
      this.active = true;
    }, 100);
  },

  search: function(value) {
    var _this = this;

    if(value == this.last_search) return;
    if(value.length < this.options.minimum_characters) return;

    if(this.search_xhr) this.search_xhr.abort();

    if(this.cache[value]) {
      this.$elem.trigger('livesearch:results', [this.cache[value]]);
    } else {
      _this.$elem.trigger('livesearch:searching');
      this.search_xhr = $.ajax({
        type: 'get',
        url: this.$form.attr('action'),
        dataType: 'json',
        data: this.$form.serialize(),
        global: false,
        success: function(data, textStatus, xhr) {
            // this is the best workaround I can think of for
            // http://dev.jquery.com/ticket/6173
            if (data === null) return;

            _this.$elem.trigger('livesearch:results', [data]);
            _this.cache[value] = data;
          },
        error: function() {
          _this.$elem.trigger('livesearch:ajax_error');
        }
        });
    }

    this.last_search = value;
  }

});

})(jQuery);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import classnames from 'classnames';

import { isPropEnabled, mergeClassNames } from '../utils';
import { TAB } from '../constants/keyCodes';
import Ink from '../Inks';

export default class Button extends Component {
  constructor(props) {
    super(props);

    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
    this.state = { focused: false };
  }

  static propTypes = {
    className: PropTypes.string,
    onClick: PropTypes.func,
    label: PropTypes.string,
    children: PropTypes.node,
    flat: PropTypes.bool,
    raised: PropTypes.bool,
    floating: PropTypes.bool,
    type: PropTypes.string,
    primary: PropTypes.bool,
    secondary: PropTypes.bool,
    disabled: PropTypes.bool,
    iconBefore: PropTypes.bool,
  };

  static defaultProps = {
    type: 'button',
    iconBefore: true,
  };

  handleKeyUp = (e) => {
    if((e.keyCode || e.which) === TAB) {
      this.setState({ focused: true });
    }
  };

  handleBlur = () => {
    this.setState({ focused: false });
  };

  renderChildren = () => {
    const { children, iconBefore, label } = this.props;
    if(isPropEnabled(this.props, 'floating')) {
      return children;
    } else if(!children) {
      return label;
    } else if(children) {
      return (

          {iconBefore && children}
          {label}
          {!iconBefore && children}

      );
    }
    return label;
  };

  render() {
    const { className, iconBefore, label, children, ...props } = this.props;
    const { focused } = this.state;
    const isDisabled = isPropEnabled(props, 'disabled');
    return (
      <button
        {...props}
        onKeyUp={this.handleKeyUp}
        onBlur={this.handleBlur}
        className={classnames(mergeClassNames(props, className, 'md-btn'), {
          'md-floating-btn': isPropEnabled(props, 'floating'),
          'md-flat-btn': !isDisabled && isPropEnabled(props, 'flat'),
          'md-raised-btn': !isDisabled && isPropEnabled(props, 'raised'),
        })}
        >
        <Ink key="ink" disabled={isPropEnabled(props, 'disabled')} focused={focused} />
        {this.renderChildren()}
      </button>
    );
  }
}
<commit_msg>Added blur and onKeyUp prop handler to button<commit_after>import React, { Component, PropTypes } from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import classnames from 'classnames';

import { isPropEnabled, mergeClassNames } from '../utils';
import { TAB } from '../constants/keyCodes';
import Ink from '../Inks';

export default class Button extends Component {
  constructor(props) {
    super(props);

    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
    this.state = { focused: false };
  }

  static propTypes = {
    className: PropTypes.string,
    onClick: PropTypes.func,
    label: PropTypes.string,
    children: PropTypes.node,
    flat: PropTypes.bool,
    raised: PropTypes.bool,
    floating: PropTypes.bool,
    type: PropTypes.string,
    primary: PropTypes.bool,
    secondary: PropTypes.bool,
    disabled: PropTypes.bool,
    iconBefore: PropTypes.bool,
    onKeyUp: PropTypes.func,
    onBlur: PropTypes.func,
  };

  static defaultProps = {
    type: 'button',
    iconBefore: true,
  };

  handleKeyUp = (e) => {
    if(this.props.onKeyUp) { this.props.onKeyUp(e); }
    if((e.keyCode || e.which) === TAB) {
      this.setState({ focused: true });
    }
  };

  handleBlur = (e) => {
    if(this.props.onBlur) { this.props.onBlur(e); }
    this.setState({ focused: false });
  };

  renderChildren = () => {
    const { children, iconBefore, label } = this.props;
    if(isPropEnabled(this.props, 'floating')) {
      return children;
    } else if(!children) {
      return label;
    } else if(children) {
      return (

          {iconBefore && children}
          {label}
          {!iconBefore && children}

      );
    }
    return label;
  };

  render() {
    const { className, iconBefore, label, children, ...props } = this.props;
    const { focused } = this.state;
    const isDisabled = isPropEnabled(props, 'disabled');
    return (
      <button
        {...props}
        onKeyUp={this.handleKeyUp}
        onBlur={this.handleBlur}
        className={classnames(mergeClassNames(props, className, 'md-btn'), {
          'md-floating-btn': isPropEnabled(props, 'floating'),
          'md-flat-btn': !isDisabled && isPropEnabled(props, 'flat'),
          'md-raised-btn': !isDisabled && isPropEnabled(props, 'raised'),
        })}
        >
        <Ink key="ink" disabled={isPropEnabled(props, 'disabled')} focused={focused} />
        {this.renderChildren()}
      </button>
    );
  }
}
<|endoftext|>


<commit_before>// --------------------------------------------------------------------------------
// Copyright (c) 2015 Ruggero Enrico Visintin
//
// 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.
// --------------------------------------------------------------------------------

console.log("SparkViewer.js included");

JRV.setBasePath("src/js/");

JRV.include("core/Renderer.js");
JRV.include("core/math/Matrix4.js");
JRV.include("core/RendererUtils.js");
JRV.include("core/RenderMaterial.js");
JRV.include("core/RenderMesh.js");
JRV.include("core/RenderModel.js");
JRV.include("core/math/Vector3.js");

SparkPreviewerMain();

if (JRV.isMobile.any() && JRV.supportTouch()) {
    JRV.include("core/input/MobileInputManager.js");
} else {
    if (JRV.supportMouse()) {
        JRV.include("core/input/PcInputManager.js");
    } else if(JRV.supportTouch()) {
        JRV.include("core/input/MobileInputManager.js");
    }
}

JRV.include("core/Camera.js");
JRV.include("core/utils/ShapeGenerator.js");

function Application(canvas, debugCanvas) {
	var mCanvas = canvas;
	var renderer;
	var debugRenderer;

	var inputManager;

    var backgroundColor;
    var renderModel;

    var litShaderProgram;
    var normalShaderProgram;
    var lightShaderProgram;

    var mCurrentShaderProgram;

	var mModelViewMatrix;
	var mArcballCamera;

	var running;
	var mFps;
	var mFrameTime;
	var load = false;

	var texture;

	this.init = function () {
        console.log("mobile: " + JRV.isMobile.any());

        renderer = new Renderer();
        renderer.initWebGL(mCanvas);

        debugRenderer = debugCanvas.getContext("2d");

        debugRenderer.fillStyle = "white";
        debugRenderer.font = "11px Lucida Console";

        mArcballCamera = new ArcballCamera();
        mArcballCamera.setViewport(45, mCanvas.clientWidth / mCanvas.clientHeight);

        initBackground();
        initShaderPrograms();
        initDefaultModel();
        initMatrices();

        renderer.program = litShaderProgram;
        renderer.init();

        if (JRV.isMobile.any() && JRV.supportTouch()) {
            inputManager = new MobileInputManager(mCanvas);
        } else {
            if (JRV.supportMouse()) {
                inputManager = new PcInputManager(mCanvas);
            } else if(supportTouch()){
                inputManager = new MobileInputManager(mCanvas);
            }
        }

        inputManager.init();
    };

    this.run = function () {
		running = true;
        runLoop();
    };

	this.stop = function () {
		running = false;
	};

	var initMatrices = function () {
	    mModelViewMatrix = Matrix4.create();
	};

	var initBackground = function() {
		backgroundColor = Vector3.create(1.0, 1.0, 1.0);
	};

	var initShaderPrograms = function () {
	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/diffuse_lit.fragment", renderer.getGfx(), function (result) {
	        litShaderProgram = result;
	        mCurrentShaderProgram = litShaderProgram;
	    });

	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/diffuse_lit_hair.fragment", renderer.getGfx(), function (result) {
	        lightShaderProgram = result;
	    });

	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/normals.fragment", renderer.getGfx(), function (result) {
	        normalShaderProgram = result;
	    });

	};

	var initDefaultModel = function() {
	    renderModel = new RenderModel();
	    renderModel.loadFromObj("Edward_Kenway/Edward_Kenway.obj", renderer.getGfx(), function () {
	    //renderModel.loadFromObj("modello_prova/Lara_Croft.obj", renderer.getGfx(), function () {
	        var vbo = renderer.getGfx().createBuffer();

	        renderer.getGfx().bindBuffer(renderer.getGfx().ARRAY_BUFFER, vbo);
	        renderer.getGfx().bufferData(renderer.getGfx().ARRAY_BUFFER, new Float32Array(renderModel.getRenderMesh().getVerticesSet()), renderer.getGfx().STATIC_DRAW);

	        renderModel.getRenderMesh().setVertexBufferHandle(vbo);
	        load = true;
	    });
	};

	lastLoop = new Date();

	var runLoop = function () {
	    var thisLoop = new Date;

	    mFrameTime = thisLoop - lastLoop;
	    mFps = Math.round(1000 / mFrameTime);

	    updateInput();
	    updateRendering();

        debugRenderer.clearRect(0, 0, 300, 70);
        debugRenderer.fillText("Fps: " + mFps, 10, 10);
        debugRenderer.fillText("Frame Time: " + mFrameTime, 10, 30);

        if (load == false) {
            debugRenderer.fillText("Loading", 10, 50);
        }

	    if (running) {
			window.requestAnimationFrame(runLoop);
		} else {
		    return;
		}

		lastLoop = thisLoop;
	};

	window.onresize = function () {
	    console.log("Resizing");
	    mArcballCamera.setViewport(45, mCanvas.clientWidth / mCanvas.clientHeight);
	};

	window.onkeydown = function (event) {
	    console.log("pressed: " + event.keyCode);

	    if (event.keyCode == 49) {
	        mCurrentShaderProgram = litShaderProgram;
	    } else if (event.keyCode == 50) {
	        mCurrentShaderProgram = normalShaderProgram;
	    }
	}

	var updateRendering = function()
	{
	    var mvp = Matrix4.create();
	    var camMatrices = mArcballCamera.updateMatrices();

	    Matrix4.multiply(camMatrices[0], camMatrices[1], mvp);
	    Matrix4.multiply(mvp, mModelViewMatrix, mvp);

	    if (load && mCurrentShaderProgram) {
            renderer.startFrame(mCurrentShaderProgram);

            renderer.getGfx().depthMask(true);
	        renderer.getGfx().depthFunc(renderer.getGfx().LESS);

	            for (var i = 0; i < renderModel.getOpaqueMaterials().length; i++) {

	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = mCurrentShaderProgram;

	                drawCall.verticesNumber = (renderModel.getOpaqueMaterials()[i].getEndIndex()) * 3;
	                drawCall.verticesStart = (renderModel.getOpaqueMaterials()[i].getStartIndex()) * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getOpaqueMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getOpaqueMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            //renderer.getGfx().enable(renderer.getGfx().BLEND);
	            //renderer.getGfx().blendFuncSeparate(renderer.getGfx().SRC_ALPHA, renderer.getGfx().ONE_MINUS_SRC_ALPHA, renderer.getGfx().ONE, renderer.getGfx().ONE_MINUS_SRC_ALPHA)

                for (var i = 0; i < renderModel.getTransparentMaterials().length; i++) {
	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = mCurrentShaderProgram;

	                drawCall.verticesNumber = renderModel.getTransparentMaterials()[i].getEndIndex() * 3;
	                drawCall.verticesStart = renderModel.getTransparentMaterials()[i].getStartIndex() * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getTransparentMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getTransparentMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            //renderer.endFrame();
	            //renderer.getGfx().disable(renderer.getGfx().BLEND);

	            renderer.getGfx().useProgram(lightShaderProgram);

	            renderer.getGfx().depthMask(false);

	            renderer.getGfx().enable(renderer.getGfx().BLEND);
	            renderer.getGfx().blendFunc(renderer.getGfx().SRC_ALPHA, renderer.getGfx().ONE_MINUS_SRC_ALPHA);

	            for (var i = 0; i < renderModel.getTransparentMaterials().length; i++) {
	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = lightShaderProgram;

	                drawCall.verticesNumber = renderModel.getTransparentMaterials()[i].getEndIndex() * 3;
	                drawCall.verticesStart = renderModel.getTransparentMaterials()[i].getStartIndex() * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getTransparentMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getTransparentMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            renderer.endFrame();
	            renderer.getGfx().disable(renderer.getGfx().BLEND);

            }

	    }

	var updateInput = function()
	{
	    if (inputManager.isLeftMouseDown()) {
	        var verticalDelta = inputManager.getMouseVerticalDelta();
	        var horizontalDelta = inputManager.getMouseHorizontalDelta();

            mArcballCamera.rotateY(verticalDelta * 0.02);
            mArcballCamera.rotateX(horizontalDelta * 0.02);
	    } else if (inputManager.isRightMouseDown()) {
	        var horizontalDelta = inputManager.getMouseHorizontalDelta();
	        var verticalDelta = inputManager.getMouseVerticalDelta();

	        mArcballCamera.translateX(horizontalDelta * 0.05);
	        mArcballCamera.translateY(-verticalDelta * 0.05);
	    }

	    if (inputManager.getWheelDelta() != 0) {
	        mArcballCamera.moveRadius(-inputManager.getWheelDelta());
	    }

	    inputManager.postUpdate();
	}

	return this;
}

var APPLICATION;

function SparkPreviewerMain() {
    window.onload = function () {
        var debugCanvas = document.getElementById("sparkViewer").cloneNode();

        debugCanvas.id = "sparkDebugger";
        debugCanvas.style.zIndex = "100";
        debugCanvas.style.position = "absolute";
        debugCanvas.style.left = "0";
        debugCanvas.style.top = "0";
        debugCanvas.style.pointerEvents = "none";

        document.body.appendChild(debugCanvas);

        APPLICATION = new Application(document.getElementById("sparkViewer"), debugCanvas);
        APPLICATION.init();
        APPLICATION.run();
    }

    return 0;
}
<commit_msg>Update SparkPreviewer.js<commit_after>// --------------------------------------------------------------------------------
// Copyright (c) 2015 Ruggero Enrico Visintin
//
// 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.
// --------------------------------------------------------------------------------

console.log("SparkViewer.js included");

JRV.setBasePath("src/js/");

JRV.include("core/Renderer.js");
JRV.include("core/math/Matrix4.js");
JRV.include("core/RendererUtils.js");
JRV.include("core/RenderMaterial.js");
JRV.include("core/RenderMesh.js");
JRV.include("core/RenderModel.js");
JRV.include("core/math/Vector3.js");

SparkPreviewerMain();

if (JRV.isMobile.any() && JRV.supportTouch()) {
    JRV.include("core/input/MobileInputManager.js");
} else {
    if (JRV.supportMouse()) {
        JRV.include("core/input/PcInputManager.js");
    } else if(JRV.supportTouch()) {
        JRV.include("core/input/MobileInputManager.js");
    }
}

JRV.include("core/Camera.js");
JRV.include("core/utils/ShapeGenerator.js");

function Application(canvas, debugCanvas) {
	var mCanvas = canvas;
	var renderer;
	var debugRenderer;

	var inputManager;

    var backgroundColor;
    var renderModel;

    var litShaderProgram;
    var normalShaderProgram;
    var lightShaderProgram;

    var mCurrentShaderProgram;

	var mModelViewMatrix;
	var mArcballCamera;

	var running;
	var mFps;
	var mFrameTime;
	var load = false;

	var texture;

	this.init = function () {
        console.log("mobile: " + JRV.isMobile.any());

        renderer = new Renderer();
        renderer.initWebGL(mCanvas);

        debugRenderer = debugCanvas.getContext("2d");

        debugRenderer.fillStyle = "white";
        debugRenderer.font = "11px Lucida Console";

        mArcballCamera = new ArcballCamera();
        mArcballCamera.setViewport(45, mCanvas.clientWidth / mCanvas.clientHeight);

        initBackground();
        initShaderPrograms();
        initDefaultModel();
        initMatrices();

        renderer.program = litShaderProgram;
        renderer.init();

        if (JRV.isMobile.any() && JRV.supportTouch()) {
            inputManager = new MobileInputManager(mCanvas);
        } else {
            if (JRV.supportMouse()) {
                inputManager = new PcInputManager(mCanvas);
            } else if(supportTouch()){
                inputManager = new MobileInputManager(mCanvas);
            }
        }

        inputManager.init();
    };

    this.run = function () {
		running = true;
        runLoop();
    };

	this.stop = function () {
		running = false;
	};

	var initMatrices = function () {
	    mModelViewMatrix = Matrix4.create();
	};

	var initBackground = function() {
		backgroundColor = Vector3.create(1.0, 1.0, 1.0);
	};

	var initShaderPrograms = function () {
	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/diffuse_lit.fragment", renderer.getGfx(), function (result) {
	        litShaderProgram = result;
	        mCurrentShaderProgram = litShaderProgram;
	    });

	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/diffuse_lit_hair.fragment", renderer.getGfx(), function (result) {
	        lightShaderProgram = result;
	    });

	    initShaderFromFile("src/glsl/global.vertex", "src/glsl/normals.fragment", renderer.getGfx(), function (result) {
	        normalShaderProgram = result;
	    });

	};

	var initDefaultModel = function() {
	    renderModel = new RenderModel();
	    //renderModel.loadFromObj("Edward_Kenway/Edward_Kenway.obj", renderer.getGfx(), function () {
	    renderModel.loadFromObj("modello_prova/Lara_Croft.obj", renderer.getGfx(), function () {
	        var vbo = renderer.getGfx().createBuffer();

	        renderer.getGfx().bindBuffer(renderer.getGfx().ARRAY_BUFFER, vbo);
	        renderer.getGfx().bufferData(renderer.getGfx().ARRAY_BUFFER, new Float32Array(renderModel.getRenderMesh().getVerticesSet()), renderer.getGfx().STATIC_DRAW);

	        renderModel.getRenderMesh().setVertexBufferHandle(vbo);
	        load = true;
	    });
	};

	lastLoop = new Date();

	var runLoop = function () {
	    var thisLoop = new Date;

	    mFrameTime = thisLoop - lastLoop;
	    mFps = Math.round(1000 / mFrameTime);

	    updateInput();
	    updateRendering();

        debugRenderer.clearRect(0, 0, 300, 70);
        debugRenderer.fillText("Fps: " + mFps, 10, 10);
        debugRenderer.fillText("Frame Time: " + mFrameTime, 10, 30);

        if (load == false) {
            debugRenderer.fillText("Loading", 10, 50);
        }

	    if (running) {
			window.requestAnimationFrame(runLoop);
		} else {
		    return;
		}

		lastLoop = thisLoop;
	};

	window.onresize = function () {
	    console.log("Resizing");
	    mArcballCamera.setViewport(45, mCanvas.clientWidth / mCanvas.clientHeight);
	};

	window.onkeydown = function (event) {
	    console.log("pressed: " + event.keyCode);

	    if (event.keyCode == 49) {
	        mCurrentShaderProgram = litShaderProgram;
	    } else if (event.keyCode == 50) {
	        mCurrentShaderProgram = normalShaderProgram;
	    }
	}

	var updateRendering = function()
	{
	    var mvp = Matrix4.create();
	    var camMatrices = mArcballCamera.updateMatrices();

	    Matrix4.multiply(camMatrices[0], camMatrices[1], mvp);
	    Matrix4.multiply(mvp, mModelViewMatrix, mvp);

	    if (load && mCurrentShaderProgram) {
            renderer.startFrame(mCurrentShaderProgram);

            renderer.getGfx().depthMask(true);
	        renderer.getGfx().depthFunc(renderer.getGfx().LESS);

	            for (var i = 0; i < renderModel.getOpaqueMaterials().length; i++) {

	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = mCurrentShaderProgram;

	                drawCall.verticesNumber = (renderModel.getOpaqueMaterials()[i].getEndIndex()) * 3;
	                drawCall.verticesStart = (renderModel.getOpaqueMaterials()[i].getStartIndex()) * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getOpaqueMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getOpaqueMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            //renderer.getGfx().enable(renderer.getGfx().BLEND);
	            //renderer.getGfx().blendFuncSeparate(renderer.getGfx().SRC_ALPHA, renderer.getGfx().ONE_MINUS_SRC_ALPHA, renderer.getGfx().ONE, renderer.getGfx().ONE_MINUS_SRC_ALPHA)

                for (var i = 0; i < renderModel.getTransparentMaterials().length; i++) {
	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = mCurrentShaderProgram;

	                drawCall.verticesNumber = renderModel.getTransparentMaterials()[i].getEndIndex() * 3;
	                drawCall.verticesStart = renderModel.getTransparentMaterials()[i].getStartIndex() * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getTransparentMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(mCurrentShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getTransparentMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            //renderer.endFrame();
	            //renderer.getGfx().disable(renderer.getGfx().BLEND);

	            renderer.getGfx().useProgram(lightShaderProgram);

	            renderer.getGfx().depthMask(false);

	            renderer.getGfx().enable(renderer.getGfx().BLEND);
	            renderer.getGfx().blendFunc(renderer.getGfx().SRC_ALPHA, renderer.getGfx().ONE_MINUS_SRC_ALPHA);

	            for (var i = 0; i < renderModel.getTransparentMaterials().length; i++) {
	                var drawCall = new DrawCall();
	                drawCall.vbo = renderModel.getRenderMesh().getVertexBufferHandle();
	                drawCall.shaderProgram = lightShaderProgram;

	                drawCall.verticesNumber = renderModel.getTransparentMaterials()[i].getEndIndex() * 3;
	                drawCall.verticesStart = renderModel.getTransparentMaterials()[i].getStartIndex() * 3;
	                drawCall.matrixMVP = mvp;

	                drawCall.mvpLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "modelViewProjectionMatrix");
	                drawCall.textureHandle = renderModel.getTransparentMaterials()[i].getDiffuseTextureHandle();
	                drawCall.textureLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "sampler");
	                drawCall.alphaLocation = renderer.getGfx().getUniformLocation(lightShaderProgram, "alpha");

	                drawCall.opacity = renderModel.getTransparentMaterials()[i].getOpacity();

	                renderer.render(0, drawCall);
	            }

	            renderer.endFrame();
	            renderer.getGfx().disable(renderer.getGfx().BLEND);

            }

	    }

	var updateInput = function()
	{
	    if (inputManager.isLeftMouseDown()) {
	        var verticalDelta = inputManager.getMouseVerticalDelta();
	        var horizontalDelta = inputManager.getMouseHorizontalDelta();

            mArcballCamera.rotateY(verticalDelta * 0.02);
            mArcballCamera.rotateX(horizontalDelta * 0.02);
	    } else if (inputManager.isRightMouseDown()) {
	        var horizontalDelta = inputManager.getMouseHorizontalDelta();
	        var verticalDelta = inputManager.getMouseVerticalDelta();

	        mArcballCamera.translateX(horizontalDelta * 0.05);
	        mArcballCamera.translateY(-verticalDelta * 0.05);
	    }

	    if (inputManager.getWheelDelta() != 0) {
	        mArcballCamera.moveRadius(-inputManager.getWheelDelta());
	    }

	    inputManager.postUpdate();
	}

	return this;
}

var APPLICATION;

function SparkPreviewerMain() {
    window.onload = function () {
        var debugCanvas = document.getElementById("sparkViewer").cloneNode();

        debugCanvas.id = "sparkDebugger";
        debugCanvas.style.zIndex = "100";
        debugCanvas.style.position = "absolute";
        debugCanvas.style.left = "0";
        debugCanvas.style.top = "0";
        debugCanvas.style.pointerEvents = "none";

        document.body.appendChild(debugCanvas);

        APPLICATION = new Application(document.getElementById("sparkViewer"), debugCanvas);
        APPLICATION.init();
        APPLICATION.run();
    }

    return 0;
}
<|endoftext|>


<commit_before>(function() { //IIFE

    var DJANGO_SERVER_URL = "https://cryptic-citadel-5628.herokuapp.com/api";
    var FIREBASE_SERVER_URL = "https://tanks-for-waiting.firebaseio.com";

    angular.module('tanks-for-waiting').controller('GameController', GameController);
    GameController.$inject = ['$scope', '$http', '$interval', '$firebaseObject'];

    function GameController($scope, $http, $interval, $firebaseObject) {

        var firebaseref = null;
        var playerID = null; //player_id stored here
        var gameID = null; //game_id stored here
        $scope.gameRunning = false;
        $scope.score = 0;
        /*
        *This begins the process of game selection.
        POST to /players/ for player_id
        Returns player_id
        Stores player_id
        POST to games/player_id
        Returns game_id
        Stores game_id
        Starts game
        */
        $scope.startGame = function() {
            $http.post(DJANGO_SERVER_URL + "/players/")
                .then(function(response) {
                    playerID = response.data.player_id;
                    //this is where I would display the tutorial
                    $http.post(DJANGO_SERVER_URL + "/games/", {
                            player_id: playerID
                        })
                        .then(function(response) {
                                gameID = response.data.game_id;
                                firebaseref = new Firebase(FIREBASE_SERVER_URL + "/games/" + gameID); //websocket to firebase api
                                var obj = $firebaseObject(firebaseref); //websocket to firebase api
                                obj.$bindTo($scope, "game").then(function() {
                                    console.log($scope.game); // { foo: "bar" }
                                    $scope.gameRunning = true;
                                    new Game("screen");
                                });
                            },
                            function(errobj) {
                                alert("Game request failed: " + JSON.stringify(errobj, null, 2));
                            });
                }, function(errobj) {
                    // $scope.gameRunning = true;
                    // new Game("screen");
                    alert("Player request failed: " + JSON.stringify(errobj));
                });
            console.log("click");
        };

        var Game = function(canvasId) { //holds all the main game code
            var canvas = document.getElementById(canvasId); //get the canvas into my game
            var screen = canvas.getContext('2d'); //var screen will allow me to draw to the canvas. "2d" leads to the creation of a CanvasRenderingContext2D object representing a two-dimensional rendering context.
            var gameSize = {
                x: canvas.width,
                y: canvas.height
            }; // stores the width and height of the canvas for later use for placing entities on the canvas

            var self = this;

            this.tanks = [new Player(this, $scope.game.tanks[playerID])]; //will hold all of the tanks in the game
            this.tanks.concat(self.refreshTanks(this));
            this.targets = self.refreshTargets(this);

            $interval(function() {
                if (self.isReady) {
                    self.update(); //updates the screen
                    self.draw(screen, gameSize); //based upon what's happening in the game
                }
            }, 16.7);
        };

        Game.prototype = { //gives Game a prototype

            isReady: true,

            update: function() { //updates the movement of all the on screen entities
                for (var i = 0; i < this.tanks.length; i++) {
                    this.tanks[i].update();
                }

                var thisPlayer = this.tanks[0];

                var deleteError = function(errobj) {
                    console.log('Error deleting target: ' + JSON.stringify(errobj));
                };

                var deleteSuccess = function(response) {
                    console.log(response);
                    if (response.nope) {
                        // Did not hit target.
                        //if no, return something (currently it returns the string “nope” but that can be changed)
                    } else {
                        // Was a hit.
                        // Update score from $scope.game.tanks[playID];
                    }
                };

                $scope.game.tanks[playerID].x = thisPlayer.location().x;
                $scope.game.tanks[playerID].y = thisPlayer.location().y;

                for (i = 0; i < this.targets.length; i++) {
                    if (colliding(thisPlayer, this.targets[i])) {
                        // this.isReady = false;
                        console.log(this.targets[i].target_id);
                        if ($scope.game.targets[this.targets[i].target_id].is_hit === 0) {
                            // console.log("HIT!");
                            console.log(playerID);
                            $scope.game.targets[this.targets[i].target_id].is_hit = 1;
                            $http.delete(DJANGO_SERVER_URL + "/games/" + gameID + "/targets/" + this.targets[i].target_id + "/", {
                                'player_id': playerID
                            }).then(deleteSuccess, deleteError);

                        }
                        // this.isReady = true;
                        // $scope.score += 1;
                        // this.targets.splice(i, 1);
                    }
                }
                this.tanks = this.tanks.slice(0, 1).concat(this.refreshTanks(this));
                this.targets = this.refreshTargets(this);
            },

            draw: function(screen, gameSize) {
                screen.clearRect(0, 0, gameSize.x, gameSize.y);
                for (var i = 0; i < this.tanks.length; i++) {
                    drawTank(screen, this.tanks[i]);
                    // drawTarget(screen, this.tanks[i]);
                    if (i === 0) {
                        if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.LEFT)) {
                            drawDrillHeadLeft(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.RIGHT)) {
                            drawDrillHeadRight(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.UP)) {
                            drawDrillHeadUp(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.DOWN)) {
                            drawDrillHeadDown(screen, this.tanks[i]);
                        }
                    }
                }
                for (i = 0; i < this.targets.length; i++) {
                    drawTarget(screen, this.targets[i]);
                    // drawTarget(screen, this.tanks[i]);

                }
            },

            refreshTanks: function(thisGame) {
                var tanks = [];
                for (var key in $scope.game.tanks) {
                    if (key !== playerID) {
                        tanks.push(new Player(this, $scope.game.tanks[key]));
                    }
                }
                return tanks;
            },

            refreshTargets: function(thisGame) {
                var targets = [];
                for (var key in $scope.game.targets) {
                    targets.push(new Target(thisGame, $scope.game.targets[key], key));
                }
                return targets;
            }
        };
        var Player = function(game, location) {
            this.game = game;
            this.size = {
                x: 16,
                y: 16
            }; //player size
            this.center = {
                x: location.x,
                y: location.y
            }; //tells the game where the player is at the start
            this.keyboarder = new Keyboarder();
        };

        Player.prototype = {

            location: function() {
                return this.center;
            },

            update: function() {
                if (this.keyboarder.isDown(this.keyboarder.KEYS.LEFT)) {
                    if (this.center.x <= 10) {
                        this.center.x = 8;
                    } else {
                        this.center.x -= 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.RIGHT)) {
                    if (this.center.x >= 490) {
                        this.center.x = 492;
                    } else {
                        this.center.x += 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.UP)) {
                    if (this.center.y <= 10) {
                        this.center.y = 8;
                    } else {
                        this.center.y -= 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.DOWN)) {
                    if (this.center.y >= 490) {
                        this.center.y = 492;
                    } else {
                        this.center.y += 2;
                    }
                }
            }
        };

        var Target = function(game, location, target_id) {
            this.game = game;
            this.size = {
                x: 10,
                y: 10
            }; //player size
            this.center = {
                x: location.x,
                y: location.y
            }; //tells the game where the targets are at the moment, starting at half way through the screen and just above the bottom
            this.target_id = target_id;
            this.is_hit = 0;
        };

        Target.prototype = {
            update: function() {
                console.log("helllo");
            }
        };

        var drawTank = function(screen, body) {
            //tank body
            screen.fillRect(body.center.x - body.size.x / 2, //x coordinate
                body.center.y - body.size.y / 2, // y coordinate
                body.size.x, body.size.y); //width and hieght
        };

        var drawDrillHeadLeft = function(screen, body) {
            screen.fillRect(body.center.x - body.size.x / 2 - 4, body.center.y - 2, 4, 4);
        };

        var drawDrillHeadRight = function(screen, body) {
            screen.fillRect(body.center.x + body.size.x / 2, body.center.y - 2, 4, 4);
        };

        var drawDrillHeadUp = function(screen, body) {
            screen.fillRect(body.center.x - 2, body.center.y - body.size.y / 2 - 4, 4, 4);
        };

        var drawDrillHeadDown = function(screen, body) {
            screen.fillRect(body.center.x - 2, body.center.y + body.size.y / 2, 4, 4);
        };

        var drawTarget = function(screen, target) {
            screen.fillRect(target.center.x - target.size.x / 2, //x coordinate
                target.center.y - target.size.y / 2, // y coordinate
                target.size.x, target.size.y);
        };

        var Keyboarder = function() { //handles keyboard input
            var keyState = {}; //records if any key that's been pressed is pressed or released

            window.onkeydown = function(e) {
                keyState[e.keyCode] = true;
            };

            window.onkeyup = function(e) {
                keyState[e.keyCode] = false;
            };

            this.isDown = function(keyCode) {
                return keyState[keyCode] === true;
            };

            this.KEYS = {
                LEFT: 37,
                UP: 38,
                RIGHT: 39,
                DOWN: 40,
                SPACE: 32
            };
        };

        var colliding = function(b1, b2) {
            return !(b1 === b2 ||
                b1.center.x + b1.size.x / 2 < b2.center.x - b2.size.x / 2 ||
                b1.center.y + b1.size.y / 2 < b2.center.y - b2.size.y / 2 ||
                b1.center.x - b1.size.x / 2 > b2.center.x + b2.size.x / 2 ||
                b1.center.y - b1.size.y / 2 > b2.center.y + b2.size.y / 2);
        };
    }
})(); // End of IIFE
<commit_msg>saving progress<commit_after>(function() { //IIFE

    var DJANGO_SERVER_URL = "https://cryptic-citadel-5628.herokuapp.com/api";
    var FIREBASE_SERVER_URL = "https://tanks-for-waiting.firebaseio.com";

    angular.module('tanks-for-waiting').controller('GameController', GameController);
    GameController.$inject = ['$scope', '$http', '$interval', '$firebaseObject'];

    function GameController($scope, $http, $interval, $firebaseObject) {

        var firebaseref = null;
        var playerID = null; //player_id stored here
        var gameID = null; //game_id stored here
        $scope.gameRunning = false;
        $scope.score = 0;
        /*
        *This begins the process of game selection.
        POST to /players/ for player_id
        Returns player_id
        Stores player_id
        POST to games/player_id
        Returns game_id
        Stores game_id
        Starts game
        */
        $scope.startGame = function() {
            $http.post(DJANGO_SERVER_URL + "/players/")
                .then(function(response) {
                    playerID = response.data.player_id;
                    //this is where I would display the tutorial
                    $http.post(DJANGO_SERVER_URL + "/games/", {
                            player_id: playerID
                        })
                        .then(function(response) {
                                gameID = response.data.game_id;
                                firebaseref = new Firebase(FIREBASE_SERVER_URL + "/games/" + gameID); //websocket to firebase api
                                var obj = $firebaseObject(firebaseref); //websocket to firebase api
                                obj.$bindTo($scope, "game").then(function() {
                                    console.log($scope.game); // { foo: "bar" }
                                    $scope.gameRunning = true;
                                    new Game("screen");
                                });
                            },
                            function(errobj) {
                                alert("Game request failed: " + JSON.stringify(errobj, null, 2));
                            });
                }, function(errobj) {
                    // $scope.gameRunning = true;
                    // new Game("screen");
                    alert("Player request failed: " + JSON.stringify(errobj));
                });
            console.log("click");
        };

        var Game = function(canvasId) { //holds all the main game code
            var canvas = document.getElementById(canvasId); //get the canvas into my game
            var screen = canvas.getContext('2d'); //var screen will allow me to draw to the canvas. "2d" leads to the creation of a CanvasRenderingContext2D object representing a two-dimensional rendering context.
            var gameSize = {
                x: canvas.width,
                y: canvas.height
            }; // stores the width and height of the canvas for later use for placing entities on the canvas

            var self = this;

            this.tanks = [new Player(this, $scope.game.tanks[playerID])]; //will hold all of the tanks in the game
            this.tanks.concat(self.refreshTanks(this));
            this.targets = self.refreshTargets(this);

            $interval(function() {
                if (self.isReady) {
                    self.update(); //updates the screen
                    self.draw(screen, gameSize); //based upon what's happening in the game
                }
            }, 16.7);
        };

        Game.prototype = { //gives Game a prototype

            isReady: true,

            update: function() { //updates the movement of all the on screen entities
                for (var i = 0; i < this.tanks.length; i++) {
                    this.tanks[i].update();
                }

                var thisPlayer = this.tanks[0];

                var deleteError = function(errobj) {
                    console.log('Error deleting target: ' + JSON.stringify(errobj));
                };

                var deleteSuccess = function(response) {
                    console.log(response);
                    if (response.nope) {
                        // Did not hit target.
                        //if no, return something (currently it returns the string “nope” but that can be changed)
                    } else {
                        // Was a hit.
                        // Update score from $scope.game.tanks[playID];
                    }
                };
                $scope.game.tanks[playerID].x = thisPlayer.location().x;
                $scope.game.tanks[playerID].y = thisPlayer.location().y;

                for (i = 0; i < this.targets.length; i++) {
                    if (colliding(thisPlayer, this.targets[i])) {
                        // this.isReady = false;
                        console.log(this.targets[i].target_id);
                        if ($scope.game.targets[this.targets[i].target_id].is_hit === 0) {
                            // console.log("HIT!");
                            console.log(playerID);
                            $scope.game.targets[this.targets[i].target_id].is_hit = 1;
                            $http.delete(DJANGO_SERVER_URL + "/games/" + gameID + "/targets/" + this.targets[i].target_id + "/", {
                                data:{player_id: playerID}
                            }).then(deleteSuccess, deleteError);

                        }
                        // this.isReady = true;
                        // $scope.score += 1;
                        // this.targets.splice(i, 1);
                    }
                }
                this.tanks = this.tanks.slice(0, 1).concat(this.refreshTanks(this));
                this.targets = this.refreshTargets(this);
            },

            draw: function(screen, gameSize) {
                screen.clearRect(0, 0, gameSize.x, gameSize.y);
                for (var i = 0; i < this.tanks.length; i++) {
                    drawTank(screen, this.tanks[i]);
                    // drawTarget(screen, this.tanks[i]);
                    if (i === 0) {
                        if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.LEFT)) {
                            drawDrillHeadLeft(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.RIGHT)) {
                            drawDrillHeadRight(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.UP)) {
                            drawDrillHeadUp(screen, this.tanks[i]);
                        } else if (this.tanks[i].keyboarder.isDown(this.tanks[i].keyboarder.KEYS.DOWN)) {
                            drawDrillHeadDown(screen, this.tanks[i]);
                        }
                    }
                }
                for (i = 0; i < this.targets.length; i++) {
                    drawTarget(screen, this.targets[i]);
                    // drawTarget(screen, this.tanks[i]);

                }
            },

            refreshTanks: function(thisGame) {
                var tanks = [];
                for (var key in $scope.game.tanks) {
                    if (key !== playerID) {
                        tanks.push(new Player(this, $scope.game.tanks[key]));
                    }
                }
                return tanks;
            },

            refreshTargets: function(thisGame) {
                var targets = [];
                for (var key in $scope.game.targets) {
                    targets.push(new Target(thisGame, $scope.game.targets[key], key));
                }
                return targets;
            }
        };
        var Player = function(game, location) {
            this.game = game;
            this.size = {
                x: 16,
                y: 16
            }; //player size
            this.center = {
                x: location.x,
                y: location.y
            }; //tells the game where the player is at the start
            this.keyboarder = new Keyboarder();
        };

        Player.prototype = {

            location: function() {
                return this.center;
            },

            update: function() {
                if (this.keyboarder.isDown(this.keyboarder.KEYS.LEFT)) {
                    if (this.center.x <= 10) {
                        this.center.x = 8;
                    } else {
                        this.center.x -= 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.RIGHT)) {
                    if (this.center.x >= 490) {
                        this.center.x = 492;
                    } else {
                        this.center.x += 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.UP)) {
                    if (this.center.y <= 10) {
                        this.center.y = 8;
                    } else {
                        this.center.y -= 2;
                    }
                }
                if (this.keyboarder.isDown(this.keyboarder.KEYS.DOWN)) {
                    if (this.center.y >= 490) {
                        this.center.y = 492;
                    } else {
                        this.center.y += 2;
                    }
                }
            }
        };

        var Target = function(game, location, target_id) {
            this.game = game;
            this.size = {
                x: 10,
                y: 10
            }; //player size
            this.center = {
                x: location.x,
                y: location.y
            }; //tells the game where the targets are at the moment, starting at half way through the screen and just above the bottom
            this.target_id = target_id;
            this.is_hit = 0;
        };

        Target.prototype = {
            update: function() {
                console.log("helllo");
            }
        };

        var drawTank = function(screen, body) {
            //tank body
            screen.fillRect(body.center.x - body.size.x / 2, //x coordinate
                body.center.y - body.size.y / 2, // y coordinate
                body.size.x, body.size.y); //width and hieght
        };

        var drawDrillHeadLeft = function(screen, body) {
            screen.fillRect(body.center.x - body.size.x / 2 - 4, body.center.y - 2, 4, 4);
        };

        var drawDrillHeadRight = function(screen, body) {
            screen.fillRect(body.center.x + body.size.x / 2, body.center.y - 2, 4, 4);
        };

        var drawDrillHeadUp = function(screen, body) {
            screen.fillRect(body.center.x - 2, body.center.y - body.size.y / 2 - 4, 4, 4);
        };

        var drawDrillHeadDown = function(screen, body) {
            screen.fillRect(body.center.x - 2, body.center.y + body.size.y / 2, 4, 4);
        };

        var drawTarget = function(screen, target) {
            screen.fillRect(target.center.x - target.size.x / 2, //x coordinate
                target.center.y - target.size.y / 2, // y coordinate
                target.size.x, target.size.y);
        };

        var Keyboarder = function() { //handles keyboard input
            var keyState = {}; //records if any key that's been pressed is pressed or released

            window.onkeydown = function(e) {
                keyState[e.keyCode] = true;
            };

            window.onkeyup = function(e) {
                keyState[e.keyCode] = false;
            };

            this.isDown = function(keyCode) {
                return keyState[keyCode] === true;
            };

            this.KEYS = {
                LEFT: 37,
                UP: 38,
                RIGHT: 39,
                DOWN: 40,
                SPACE: 32
            };
        };

        var colliding = function(b1, b2) {
            return !(b1 === b2 ||
                b1.center.x + b1.size.x / 2 < b2.center.x - b2.size.x / 2 ||
                b1.center.y + b1.size.y / 2 < b2.center.y - b2.size.y / 2 ||
                b1.center.x - b1.size.x / 2 > b2.center.x + b2.size.x / 2 ||
                b1.center.y - b1.size.y / 2 > b2.center.y + b2.size.y / 2);
        };
    }
})(); // End of IIFE
<|endoftext|>


<commit_before>/* Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 * Copyright (c) 2010 Mr.doob, rhyolight, bebraw
 */
function brushes() {
    this.init();
}
brushes.prototype = {
    brushOptions: {'size': {'min': 1, 'max': 30, 'value': 1, 'pressure': false},
        'opacity': {'min': 0, 'max': 100, 'value': 50, 'pressure': true},
        'location': {}},
    init: function () {
        this.wacom = document.embeds["wacomPlugin"];

        if(!this.wacom.isWacom) {
            this.wacom = {'pressure': 1.0}; // proxy
        }

        this.selected = BRUSHES[0];
    },
    initUI: function () {
        setUpPod("Brushes");

        $('#brushesPod').click(function() {
            $(this).css('visibility', 'hidden'); //hide();
            $('#brushesCheckbox').attr('checked', false);
            $('#brushesPanel').dialog('open');
        });

        // set up brushes panel
        $("body").append(
            '
 \

 \

 \

'
        );

        var panelWidth = 250, panelHeight = 480;
        $("#brushesPanel").dialog({
            closeOnEscape: false, resizable: false,
            width: panelWidth, minWidth: panelWidth, maxWidth: panelWidth,
            height: panelHeight, minHeight: panelHeight, maxHeight: panelHeight,
            autoOpen: false
        });

        $("#brushesPanel").dialog("option", "position", "left");
        $("#brushesPanel").bind("dialogclose", function(event, ui) {
            $("#brushesPod").css("visibility", "visible");}
        );

        $("#brushOptions").append('
 \
                <input type="radio" id="lightenMode" name="brushMode" value="lighter" />Lighten \
                <input type="radio" id="normalMode" name="brushMode" value="source-over" checked="checked" />Normal \
                <input type="radio" id="darkenMode" name="brushMode" value="darker" />Darken \

 \
        ');

        $("#brushMode").buttonset();

        // TODO: figure out a neat way to visualize different modes
        //$("#brushMode").buttonset().click( function() {
        //    panels['brushes'].renderBrushPreviews();
        //});

        $("#brushOptions").append('
 \
                <input type="radio" id="currentShading" name="brushShading" value="current" checked="checked" />Current \
                <input type="radio" id="sameShading" name="brushShading" value="same" />Same \
                <input type="radio" id="allShading" name="brushShading" value="all" />All \

 \
        ');

        $("#brushShading").buttonset();

        for (var brushOptionName in this.brushOptions) {
            brushOptionValue = this.brushOptions[brushOptionName];

            $("#brushOptions").append('
');

            optionTitle = capitalizeFirstLetter(brushOptionName);
            optionId = 'brush' + brushOptionName;
            if('pressure' in brushOptionValue) {
                pressureId = optionId + 'pressure';

                $("#brushOptions").append('<input type="checkbox" id="' +
                    pressureId + '" />' + optionTitle + '');

                pressureValue = brushOptionValue.pressure;

                if(pressureValue) {
                    $('#' + pressureId).attr('checked', 'checked');
                }

                $('#' + pressureId).button().click(
                    function () {
                        // XXX: hack! figure out a nicer way to pass option name!
                        option = $(this).attr('id').replace('JitterToggle', '').replace('brush', '').replace('pressure', '');
                        pressure = panels['brushes'].brushOptions[option].pressure;
                        panels['brushes'].brushOptions[option].pressure = !pressure;
                    }
                );
            }
            else {
                $("#brushOptions").append('
' +
                    optionTitle + ':
');
            }

            if('value' in brushOptionValue) {
                $("#brushOptions").append('

');

                $("#" + optionId).slider({
                    range: "max",
                    min: brushOptionValue.min,
                    max: brushOptionValue.max,
                    value: brushOptionValue.value,
                    slide: function(event, ui) {
                        // XXX: hack! figure out a nicer way to pass option name!
                        option = $(this).attr('id').replace('brush', '');
                        panels['brushes'].brushOptions[option].value = ui.value;
                        panels['brushes'].renderBrushPreviews();
                    }
                });
            }

            $("#brushOptions").append('

');

            jitterToggleId = optionId + 'JitterToggle';
            jitterAmountId = optionId + 'JitterAmount';
            $("#brushOptions").append(
                '
 \
                    <input type="checkbox" style="float:left;" id="' +
                        jitterToggleId + '" />Jitter \

 \

 \

 \
                '
            );

            this.brushOptions[brushOptionName]['jitter'] = {'enabled': false,
                'value': 0};

            $("#brushOptions").append('
');

            this.setUpJitter(jitterToggleId, jitterAmountId);
        }

        // XXX: figure out the width in a nicer way
        this.createBrushes(panelWidth / 3 + 10);
    },
    destroy: function () {},
    setUpJitter: function ( jitterToggleId, jitterAmountId ) {
        $("#" + jitterToggleId).button().toggle(
            function () {
                $(this).parent('.jitter').children('div').css('visibility',
                    'visible');
                // XXX: hack! figure out a nicer way to pass option name!
                option = $(this).attr('id').replace('JitterToggle', '').replace('brush', '');
                panels['brushes'].brushOptions[option].jitter.enabled = true;
                panels['brushes'].renderBrushPreviews();
            },
            function () {
                $(this).parent('.jitter').children('div').css('visibility',
                    'hidden');
                // XXX: hack! figure out a nicer way to pass option name!
                option = $(this).attr('id').replace('JitterToggle', '').replace('brush', '');
                panels['brushes'].brushOptions[option].jitter.enabled = false;
                panels['brushes'].renderBrushPreviews();
            }
        );

        $("#" + jitterAmountId).slider({
            range: "max",
            min: 0,
            max: 50, // XXX: 100 for totally random, not really useful though
            value: 0,
            slide: function(event, ui) {
                // XXX: hack! figure out a nicer way to pass option name!
                option = $(this).attr('id').replace('JitterAmount', '').replace('brush', '');
                panels['brushes'].brushOptions[option].jitter.value = ui.value;
                panels['brushes'].renderBrushPreviews();
            }
        }).css('visibility', 'hidden');
    },
    createBrushes: function ( brushWidth ) {
        for (i = 0; i < BRUSHES.length; i++) {
            brushName = BRUSHES[i];
            brushId = brushName; //XXX: use + 'Brush'; to avoid id clashes!
            brushHeight = 40;

            $("#brushes").append('<canvas class="brush" id="' + brushId + '"' +
                ' style="height:' + brushHeight + 'px;width:' + brushWidth +
                'px"' +  '></canvas>');
            $('.brush:first').css('border', '1px dashed');

            $('#' + brushId).click(function() {
                panels['brushes'].selected = $(this).attr('id');

                // XXX: render bg as gray instead?
                $('.brush').css('border', '');
                $(this).css('border', '1px dashed');
                // XXX: render border in the canvas itself!
            });
        }

        this.renderBrushPreviews();
    },
    renderBrushPreviews: function () {
        for (i = 0; i < BRUSHES.length; i++) {
            brushName = BRUSHES[i];
            brushId = brushName; //XXX: use + 'Brush'; to avoid id clashes!

            this.renderBrushPreview(brushId);
        }
    },
    renderBrushPreview: function (brushId) {
        brushCanvas = new ProxyCanvas(brushId);
        brushCanvas.fill([255, 255, 255]);

        if( SHOWPREVIEWIMAGES ) {
            brush = eval("new " + brushName + "()");

            brushPainter = new Painter(brushCanvas, brush, getColor());

            canvasWidth = brushCanvas.width;
            pad = 10;

            for (x = pad; x < canvasWidth - pad; x += 5) {
                y = Math.sin(5 * (x - pad) / (canvasWidth - pad) * 2 * Math.PI) *
                    (brushCanvas.height / 2 - pad * 2) + (brushCanvas.height / 2);

                point = new Point(x, y);
                point = this.applyJitter(point);
                brushPainter.paint(point, this.getSize(), this.getOpacity(),
                    this.getMode());
            }
        }

        brushCanvas.text(brushId, 'black', '48px Segoe UI, Arial, sans-serif',
            10, brushCanvas.height / 2);
    },
    applyJitter: function ( point ) {
        if(this.brushOptions.location.jitter.enabled) {
            randomDirection = getRandomDirection(this.brushOptions.location.jitter.value);

            return point.add(randomDirection);
        }

        return point;
    },
    getSelected: function () {
        return eval("new " + this.selected + '()');
    },
    getSize: function () {
        return this.getValueTemplate('size');
    },
    getOpacity: function () {
        return this.getValueTemplate('opacity') / 100;
    },
    getValueTemplate: function (valueName) {
        value = this.brushOptions[valueName].value;

        if(this.brushOptions[valueName].jitter.enabled) {
            jitterValue = this.brushOptions[valueName].jitter.value / 100;
            valueMax = this.brushOptions[valueName].max;
            valueMin = this.brushOptions[valueName].min;
            randomValue = Math.random() * ((value - valueMin) / (valueMax - valueMin));
            jitterNeg = value * jitterValue * randomValue;

            value = value - jitterNeg;
        }

        if(this.brushOptions[valueName].pressure) {
            return value * this.wacom.pressure;
        }

        return value;
    },
    getMode: function () {
        return $('#brushMode input:checked').val();
    },
    getShadingType: function () {
        return $('#brushShading input:checked').val();
    }
}
<commit_msg>Got rid of jitter toggles.<commit_after>/* Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 * Copyright (c) 2010 Mr.doob, rhyolight, bebraw
 */
function brushes() {
    this.init();
}
brushes.prototype = {
    brushOptions: {'size': {'min': 1, 'max': 30, 'value': 1, 'pressure': false},
        'opacity': {'min': 0, 'max': 100, 'value': 50, 'pressure': true},
        'location': {}},
    init: function () {
        this.wacom = document.embeds["wacomPlugin"];

        if(!this.wacom.isWacom) {
            this.wacom = {'pressure': 1.0}; // proxy
        }

        this.selected = BRUSHES[0];
    },
    initUI: function () {
        setUpPod("Brushes");

        $('#brushesPod').click(function() {
            $(this).css('visibility', 'hidden'); //hide();
            $('#brushesCheckbox').attr('checked', false);
            $('#brushesPanel').dialog('open');
        });

        // set up brushes panel
        $("body").append(
            '
 \

 \

 \

'
        );

        var panelWidth = 250, panelHeight = 480;
        $("#brushesPanel").dialog({
            closeOnEscape: false, resizable: false,
            width: panelWidth, minWidth: panelWidth, maxWidth: panelWidth,
            height: panelHeight, minHeight: panelHeight, maxHeight: panelHeight,
            autoOpen: false
        });

        $("#brushesPanel").dialog("option", "position", "left");
        $("#brushesPanel").bind("dialogclose", function(event, ui) {
            $("#brushesPod").css("visibility", "visible");}
        );

        $("#brushOptions").append('
 \
                <input type="radio" id="lightenMode" name="brushMode" value="lighter" />Lighten \
                <input type="radio" id="normalMode" name="brushMode" value="source-over" checked="checked" />Normal \
                <input type="radio" id="darkenMode" name="brushMode" value="darker" />Darken \

 \
        ');

        $("#brushMode").buttonset();

        // TODO: figure out a neat way to visualize different modes
        //$("#brushMode").buttonset().click( function() {
        //    panels['brushes'].renderBrushPreviews();
        //});

        $("#brushOptions").append('
 \
                <input type="radio" id="currentShading" name="brushShading" value="current" checked="checked" />Current \
                <input type="radio" id="sameShading" name="brushShading" value="same" />Same \
                <input type="radio" id="allShading" name="brushShading" value="all" />All \

 \
        ');

        $("#brushShading").buttonset();

        for (var brushOptionName in this.brushOptions) {
            brushOptionValue = this.brushOptions[brushOptionName];

            $("#brushOptions").append('
');

            optionTitle = capitalizeFirstLetter(brushOptionName);
            optionId = 'brush' + brushOptionName;
            if('pressure' in brushOptionValue) {
                pressureId = optionId + 'pressure';

                $("#brushOptions").append('<input type="checkbox" id="' +
                    pressureId + '" />' + optionTitle + '');

                pressureValue = brushOptionValue.pressure;

                if(pressureValue) {
                    $('#' + pressureId).attr('checked', 'checked');
                }

                $('#' + pressureId).button().click(
                    function () {
                        // XXX: hack! figure out a nicer way to pass option name!
                        option = $(this).attr('id').replace('JitterToggle', '').replace('brush', '').replace('pressure', '');
                        pressure = panels['brushes'].brushOptions[option].pressure;
                        panels['brushes'].brushOptions[option].pressure = !pressure;
                    }
                );
            }
            else {
                $("#brushOptions").append('
' +
                    optionTitle + '
');
            }

            if('value' in brushOptionValue) {
                $("#brushOptions").append('

');

                $("#" + optionId).slider({
                    range: "max",
                    min: brushOptionValue.min,
                    max: brushOptionValue.max,
                    value: brushOptionValue.value,
                    slide: function(event, ui) {
                        // XXX: hack! figure out a nicer way to pass option name!
                        option = $(this).attr('id').replace('brush', '');
                        panels['brushes'].brushOptions[option].value = ui.value;
                        panels['brushes'].renderBrushPreviews();
                    }
                });
            }

            $("#brushOptions").append('

');

            jitterAmountId = optionId + 'JitterAmount';
            $("#brushOptions").append(
                '
 \

Jitter:
 \

 \

 \

 \
                '
            );

            this.brushOptions[brushOptionName]['jitter'] = {'enabled': false,
                'value': 0};

            $("#brushOptions").append('
');

            this.setUpJitter(jitterAmountId);
        }

        // XXX: figure out the width in a nicer way
        this.createBrushes(panelWidth / 3 + 10);
    },
    destroy: function () {},
    setUpJitter: function ( jitterAmountId ) {
        $("#" + jitterAmountId).slider({
            range: "max",
            min: 0,
            max: 50, // XXX: 100 for totally random, not really useful though
            value: 0,
            slide: function(event, ui) {
                // XXX: hack! figure out a nicer way to pass option name!
                option = $(this).attr('id').replace('JitterAmount', '').replace('brush', '');
                panels['brushes'].brushOptions[option].jitter.value = ui.value;
                panels['brushes'].renderBrushPreviews();
            }
        });
    },
    createBrushes: function ( brushWidth ) {
        for (i = 0; i < BRUSHES.length; i++) {
            brushName = BRUSHES[i];
            brushId = brushName; //XXX: use + 'Brush'; to avoid id clashes!
            brushHeight = 40;

            $("#brushes").append('<canvas class="brush" id="' + brushId + '"' +
                ' style="height:' + brushHeight + 'px;width:' + brushWidth +
                'px"' +  '></canvas>');
            $('.brush:first').css('border', '1px dashed');

            $('#' + brushId).click(function() {
                panels['brushes'].selected = $(this).attr('id');

                // XXX: render bg as gray instead?
                $('.brush').css('border', '');
                $(this).css('border', '1px dashed');
                // XXX: render border in the canvas itself!
            });
        }

        this.renderBrushPreviews();
    },
    renderBrushPreviews: function () {
        for (i = 0; i < BRUSHES.length; i++) {
            brushName = BRUSHES[i];
            brushId = brushName; //XXX: use + 'Brush'; to avoid id clashes!

            this.renderBrushPreview(brushId);
        }
    },
    renderBrushPreview: function (brushId) {
        brushCanvas = new ProxyCanvas(brushId);
        brushCanvas.fill([255, 255, 255]);

        if( SHOWPREVIEWIMAGES ) {
            brush = eval("new " + brushName + "()");

            brushPainter = new Painter(brushCanvas, brush, getColor());

            canvasWidth = brushCanvas.width;
            pad = 10;

            for (x = pad; x < canvasWidth - pad; x += 5) {
                y = Math.sin(5 * (x - pad) / (canvasWidth - pad) * 2 * Math.PI) *
                    (brushCanvas.height / 2 - pad * 2) + (brushCanvas.height / 2);

                point = new Point(x, y);
                point = this.applyJitter(point);
                brushPainter.paint(point, this.getSize(), this.getOpacity(),
                    this.getMode());
            }
        }

        brushCanvas.text(brushId, 'black', '48px Segoe UI, Arial, sans-serif',
            10, brushCanvas.height / 2);
    },
    applyJitter: function ( point ) {
        if(this.brushOptions.location.jitter.enabled) {
            randomDirection = getRandomDirection(this.brushOptions.location.jitter.value);

            return point.add(randomDirection);
        }

        return point;
    },
    getSelected: function () {
        return eval("new " + this.selected + '()');
    },
    getSize: function () {
        return this.getValueTemplate('size');
    },
    getOpacity: function () {
        return this.getValueTemplate('opacity') / 100;
    },
    getValueTemplate: function (valueName) {
        value = this.brushOptions[valueName].value;

        jitterValue = this.brushOptions[valueName].jitter.value / 100;
        valueMax = this.brushOptions[valueName].max;
        valueMin = this.brushOptions[valueName].min;
        randomValue = Math.random() * ((value - valueMin) / (valueMax - valueMin));
        jitterNeg = value * jitterValue * randomValue;

        value = value - jitterNeg;

        if(this.brushOptions[valueName].pressure) {
            return value * this.wacom.pressure;
        }

        return value;
    },
    getMode: function () {
        return $('#brushMode input:checked').val();
    },
    getShadingType: function () {
        return $('#brushShading input:checked').val();
    }
}
<|endoftext|>