creepyface
Advanced tools
Comparing version 1.0.3 to 2.0.0
@@ -5,12 +5,79 @@ 'use strict'; | ||
var getElementCenter = _interopDefault(require('get-element-center')); | ||
var loadImages = _interopDefault(require('image-promise')); | ||
var isFirefox = _interopDefault(require('is-firefox')); | ||
var parseDataAttributes = _interopDefault(require('data-attrs-to-js')); | ||
var WindRose = _interopDefault(require('windrose')); | ||
var defaults = _interopDefault(require('object.defaults')); | ||
var getElementCenter = _interopDefault(require('get-element-center')); | ||
var debounce = _interopDefault(require('debounce')); | ||
var $ = _interopDefault(require('queryselectorall')); | ||
var throttle = _interopDefault(require('throttleit')); | ||
var debounce = _interopDefault(require('debounce')); | ||
/* global HTMLImageElement */ | ||
function showAndHideImages(imgs) { | ||
imgs.forEach(function (img) { | ||
img.style.position = 'fixed'; | ||
img.style.height = '0px'; | ||
var body = document.body; | ||
if (body) { | ||
body.appendChild(img); | ||
setTimeout(function () { | ||
return body.removeChild(img); | ||
}, 1000); | ||
} | ||
}); | ||
} | ||
var getSrcs = function getSrcs(options) { | ||
var srcs = options.looks.map(function (_ref) { | ||
var src = _ref.src; | ||
return src; | ||
}); | ||
if (options.default) srcs.push(options.default); | ||
if (options.hover) srcs.push(options.hover); | ||
return srcs; | ||
}; | ||
function preload(img, options) { | ||
return loadImages(getSrcs(options)).then(function (imgs) { | ||
img.creepyFaceReachableImages = imgs; | ||
if (isFirefox) showAndHideImages(imgs); | ||
}); | ||
} | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var Observable = function () { | ||
function Observable(subscriber) { | ||
_classCallCheck(this, Observable); | ||
this.subscriber = function (observer) { | ||
return function () {}; | ||
}; | ||
this.subscriber = subscriber; | ||
} | ||
_createClass(Observable, [{ | ||
key: 'subscribe', | ||
value: function subscribe(consumer) { | ||
var observer = { next: consumer }; | ||
var result = this.subscriber(observer); | ||
return typeof result === 'function' ? { unsubscribe: result } : result; | ||
} | ||
}]); | ||
return Observable; | ||
}(); | ||
/* global MouseEvent */ | ||
var mousePoints = new Observable(function (observer) { | ||
var next = function next(event) { | ||
return observer.next([event.clientX, event.clientY]); | ||
}; | ||
document.addEventListener('mousemove', next, true); | ||
return function () { | ||
return document.removeEventListener('mousemove', next, true); | ||
}; | ||
}); | ||
var diff = function diff(v1, v2) { | ||
@@ -33,2 +100,5 @@ return v1.map(function (x, i) { | ||
}; | ||
var deg = function deg(rad) { | ||
return rad * 180 / Math.PI; | ||
}; | ||
var mod = function mod(n, m) { | ||
@@ -38,10 +108,134 @@ return (m + n % m) % m; | ||
var getAngle = function getAngle(v) { | ||
return mod(Math.atan2(v[1], v[0]), 2 * Math.PI); | ||
return deg(mod(Math.atan2(v[1], v[0]), 2 * Math.PI)); | ||
}; | ||
var rotate = function rotate(v, rad) { | ||
return [v[0] * Math.cos(rad) - v[1] * Math.sin(rad), v[0] * Math.sin(rad) + v[1] * Math.cos(rad)]; | ||
var rotate = function rotate(v, deg) { | ||
return [v[0] * Math.cos(rad(deg)) - v[1] * Math.sin(rad(deg)), v[0] * Math.sin(rad(deg)) + v[1] * Math.cos(rad(deg))]; | ||
}; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
/* global TouchEvent */ | ||
var fingerPoints = new Observable(function (observer) { | ||
var next = function next(event) { | ||
var point = [0, 0]; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = event.touches[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var touch = _step.value; | ||
point = add(point, [touch.clientX, touch.clientY]); | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
observer.next(point); | ||
}; | ||
document.addEventListener('touchmove', next, true); | ||
return function () { | ||
return document.removeEventListener('touchmove', next, true); | ||
}; | ||
}); | ||
var combined = (function (observables) { | ||
return new Observable(function (observer) { | ||
var next = observer.next.bind(observer); | ||
var subscriptions = observables.map(function (o) { | ||
return o.subscribe(next); | ||
}); | ||
return function () { | ||
return subscriptions.forEach(function (s) { | ||
return s.unsubscribe(); | ||
}); | ||
}; | ||
}); | ||
}); | ||
/* eslint-disable no-use-before-define */ | ||
/* eslint-enable no-use-before-define */ | ||
var getLooks = function getLooks(look) { | ||
var looks = []; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = Object.keys(look)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var key = _step.value; | ||
var _src = look[key]; | ||
if (_src) { | ||
looks.push({ angle: parseFloat(key), src: _src }); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
return looks; | ||
}; | ||
function fromImage(element) { | ||
var _parseDataAttributes = parseDataAttributes(element), | ||
_parseDataAttributes$ = _parseDataAttributes.src, | ||
src = _parseDataAttributes$ === undefined ? {} : _parseDataAttributes$, | ||
fieldofvision = _parseDataAttributes.fieldofvision, | ||
timetodefault = _parseDataAttributes.timetodefault; | ||
var options = { | ||
default: element.getAttribute('src') | ||
}; | ||
if (timetodefault) options.timeToDefault = parseFloat(timetodefault); | ||
if (fieldofvision) options.fieldOfVision = parseFloat(fieldofvision); | ||
if (src.hover) options.hover = src.hover; | ||
if (src.look) options.looks = getLooks(src.look); | ||
return options; | ||
} | ||
function getOptions(img) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var userOptions = Object.assign({}, fromImage(img), options); | ||
if (!userOptions.default) throw new Error('A default URL must be specified'); | ||
return { | ||
fieldOfVision: userOptions.fieldOfVision || 150, | ||
default: userOptions.default, | ||
hover: userOptions.hover || '', | ||
points: userOptions.points || combined([mousePoints, fingerPoints]), | ||
looks: userOptions.looks || [], | ||
timeToDefault: userOptions.timeToDefault || 1000, | ||
debug: userOptions.debug || function () {} | ||
}; | ||
} | ||
var center = function center(node) { | ||
@@ -52,4 +246,10 @@ var coords = getElementCenter(node); | ||
var getAngle$1 = (function (img, point) { | ||
return getAngle(rotate(diff(point, center(img)), 90)); | ||
}); | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var shortest = function shortest(angle) { | ||
return Math.abs(angle) > Math.PI ? angle - sign(angle) * 2 * Math.PI : angle; | ||
return Math.abs(angle) > 180 ? angle - sign(angle) * 360 : angle; | ||
}; | ||
@@ -91,4 +291,3 @@ var compare = function compare(angle) { | ||
function pointToSrc(point, img, options) { | ||
var coords = point.coords; | ||
var getSrc = (function (img, point, angle, options) { | ||
var looks = options.looks, | ||
@@ -98,6 +297,5 @@ hover = options.hover, | ||
var angle = getAngle(rotate(diff(coords, center(img)), Math.PI / 2)); | ||
var src = options.default; | ||
if (hover && elementContains(img, coords)) { | ||
if (hover && elementContains(img, point)) { | ||
src = hover; | ||
@@ -112,150 +310,76 @@ } else { | ||
return src; | ||
} | ||
}); | ||
function showAndHideImages(imgs) { | ||
imgs.forEach(function (img) { | ||
img.style.position = 'fixed'; | ||
img.style.height = '0px'; | ||
document.body.appendChild(img); | ||
setTimeout(function () { | ||
return document.body.removeChild(img); | ||
}, 1000); | ||
var creepy = (function (img, options) { | ||
return new Observable(function (observer) { | ||
var backToDefault = debounce(function () { | ||
return observer.next({ src: options.default, options: options }); | ||
}, options.timeToDefault); | ||
return options.points.subscribe(function (point) { | ||
var angle = getAngle$1(img, point); | ||
var src = getSrc(img, point, angle, options); | ||
observer.next({ point: point, angle: angle, src: src, options: options }); | ||
backToDefault(); | ||
}); | ||
}); | ||
} | ||
}); | ||
function preload(img, srcs) { | ||
return loadImages(srcs).then(function (imgs) { | ||
img.creepyFaceReachableImages = imgs; | ||
if (isFirefox) showAndHideImages(imgs); | ||
var attach = (function (img, userOptions) { | ||
var options = getOptions(img, userOptions); | ||
var setSrc = function setSrc(src) { | ||
img.src = src; | ||
}; | ||
var subscribed = preload(img, options).then(function () { | ||
return creepy(img, options).subscribe(function (data) { | ||
setSrc(data.src); | ||
options.debug(data); | ||
}); | ||
}); | ||
} | ||
function point(p, target, source) { | ||
return { coords: p, target: target, source: source }; | ||
} | ||
var callWith = function callWith(value) { | ||
return function (fn) { | ||
return fn(value); | ||
}; | ||
}; | ||
function mappable(factory) { | ||
var subscribers = []; | ||
var next = function next(value) { | ||
return subscribers.forEach(function (_ref) { | ||
var apply = _ref.apply, | ||
nexts = _ref.nexts; | ||
return nexts.forEach(callWith(apply(value))); | ||
return function () { | ||
return subscribed.then(function (subscription) { | ||
subscription.unsubscribe(); | ||
setSrc(options.default); | ||
}); | ||
}; | ||
var map = function map(apply) { | ||
if (subscribers.length === 0) factory(next); | ||
var nexts = []; | ||
subscribers.push({ apply: apply, nexts: nexts }); | ||
return mappable(nexts.push.bind(nexts)); | ||
}; | ||
return { map: map }; | ||
} | ||
var events = (function (element, eventName) { | ||
return mappable(function (next) { | ||
return element.addEventListener(eventName, next, true); | ||
}); | ||
}); | ||
var mousePoints = events(document, 'mousemove').map(function (event) { | ||
return point([event.clientX, event.clientY], event.target, 'mouse'); | ||
}); | ||
var fingerPoints = events(document, 'touchmove').map(function (event) { | ||
var coords = [].slice.call(event.touches).map(function (touch) { | ||
return [touch.clientX, touch.clientY]; | ||
}).reduce(add, [0, 0]); | ||
return point(coords, event.target, 'finger'); | ||
}); | ||
var combined = (function (mappables) { | ||
return mappable(function (next) { | ||
return mappables.map(function (m) { | ||
return m.map(next); | ||
}); | ||
var watchElement = (function (node, onAdded, onRemoved) { | ||
var wasAdded = !!node.parentNode; | ||
if (wasAdded) onAdded(); | ||
if (!window.MutationObserver) return function () {}; | ||
var observer = new window.MutationObserver(function (mutations) { | ||
if (!node.parentNode && wasAdded) { | ||
onRemoved(); | ||
wasAdded = false; | ||
} else if (node.parentNode && !wasAdded) { | ||
onAdded(); | ||
wasAdded = true; | ||
} | ||
}); | ||
observer.observe(document, { childList: true, subtree: true }); | ||
return function () { | ||
return observer.disconnect(); | ||
}; | ||
}); | ||
/* global HTMLElement */ | ||
var textToAngle = function textToAngle(text) { | ||
return rad(isNaN(text) ? WindRose.getDegrees(text.toUpperCase()).value : parseFloat(text)); | ||
}; | ||
var getLooks = function getLooks(look) { | ||
return Object.keys(look || {}).map(function (key) { | ||
return { | ||
angle: textToAngle(key), src: look[key] | ||
}; | ||
/* global HTMLImageElement */ | ||
function creepyFace(img, options) { | ||
var detach = function detach() {}; | ||
var stopWatching = watchElement(img, function () { | ||
detach = attach(img, options); | ||
}, function () { | ||
detach(); | ||
}); | ||
}; | ||
var parseNumericOption = function parseNumericOption(option) { | ||
return isNaN(option) ? undefined : parseFloat(option); | ||
}; | ||
var getSrcs = function getSrcs(options) { | ||
var srcs = options.looks.map(function (_ref) { | ||
var src = _ref.src; | ||
return src; | ||
}); | ||
if (options.default) srcs.push(options.default); | ||
if (options.hover) srcs.push(options.hover); | ||
return srcs; | ||
}; | ||
function fromElement(element) { | ||
var _parseDataAttributes = parseDataAttributes(element), | ||
src = _parseDataAttributes.src, | ||
fieldofvision = _parseDataAttributes.fieldofvision, | ||
throttle$$1 = _parseDataAttributes.throttle, | ||
backtonormal = _parseDataAttributes.backtonormal; | ||
var _ref2 = src || {}, | ||
hover = _ref2.hover, | ||
look = _ref2.look; | ||
return defaults({ | ||
fieldOfVision: isNaN(fieldofvision) || rad(parseFloat(fieldofvision)), | ||
default: element.getAttribute('src'), | ||
hover: hover, | ||
looks: getLooks(look), | ||
throttle: parseNumericOption(throttle$$1), | ||
backToNormal: parseNumericOption(backtonormal) | ||
}, defaultOptions); | ||
return function () { | ||
stopWatching(); | ||
detach(); | ||
}; | ||
} | ||
var defaultOptions = { | ||
fieldOfVision: rad(150), | ||
default: '', | ||
hover: '', | ||
looks: [], | ||
points: combined([mousePoints, fingerPoints]), | ||
throttle: 0, | ||
backToNormal: 1000 | ||
}; | ||
function creepyFace(img, userOptions) { | ||
var options = defaults({}, userOptions, fromElement(img)); | ||
var backToNormal = debounce(function () { | ||
img.src = options.default; | ||
}, options.backToNormal); | ||
return preload(img, getSrcs(options)).then(function () { | ||
return options.points.map(throttle(function (point) { | ||
img.src = pointToSrc(point, img, options); | ||
options.backToNormal > 0 && backToNormal(); | ||
}, options.throttle)); | ||
}); | ||
} | ||
$('img[data-creepy]').forEach(function (img) { | ||
return creepyFace(img); | ||
$('img[data-creepy]').forEach(function (el) { | ||
if (el instanceof HTMLImageElement) creepyFace(el); | ||
}); | ||
module.exports = creepyFace; |
@@ -1,11 +0,78 @@ | ||
import getElementCenter from 'get-element-center'; | ||
import loadImages from 'image-promise'; | ||
import isFirefox from 'is-firefox'; | ||
import parseDataAttributes from 'data-attrs-to-js'; | ||
import WindRose from 'windrose'; | ||
import defaults from 'object.defaults'; | ||
import getElementCenter from 'get-element-center'; | ||
import debounce from 'debounce'; | ||
import $ from 'queryselectorall'; | ||
import throttle from 'throttleit'; | ||
import debounce from 'debounce'; | ||
/* global HTMLImageElement */ | ||
function showAndHideImages(imgs) { | ||
imgs.forEach(function (img) { | ||
img.style.position = 'fixed'; | ||
img.style.height = '0px'; | ||
var body = document.body; | ||
if (body) { | ||
body.appendChild(img); | ||
setTimeout(function () { | ||
return body.removeChild(img); | ||
}, 1000); | ||
} | ||
}); | ||
} | ||
var getSrcs = function getSrcs(options) { | ||
var srcs = options.looks.map(function (_ref) { | ||
var src = _ref.src; | ||
return src; | ||
}); | ||
if (options.default) srcs.push(options.default); | ||
if (options.hover) srcs.push(options.hover); | ||
return srcs; | ||
}; | ||
function preload(img, options) { | ||
return loadImages(getSrcs(options)).then(function (imgs) { | ||
img.creepyFaceReachableImages = imgs; | ||
if (isFirefox) showAndHideImages(imgs); | ||
}); | ||
} | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var Observable = function () { | ||
function Observable(subscriber) { | ||
_classCallCheck(this, Observable); | ||
this.subscriber = function (observer) { | ||
return function () {}; | ||
}; | ||
this.subscriber = subscriber; | ||
} | ||
_createClass(Observable, [{ | ||
key: 'subscribe', | ||
value: function subscribe(consumer) { | ||
var observer = { next: consumer }; | ||
var result = this.subscriber(observer); | ||
return typeof result === 'function' ? { unsubscribe: result } : result; | ||
} | ||
}]); | ||
return Observable; | ||
}(); | ||
/* global MouseEvent */ | ||
var mousePoints = new Observable(function (observer) { | ||
var next = function next(event) { | ||
return observer.next([event.clientX, event.clientY]); | ||
}; | ||
document.addEventListener('mousemove', next, true); | ||
return function () { | ||
return document.removeEventListener('mousemove', next, true); | ||
}; | ||
}); | ||
var diff = function diff(v1, v2) { | ||
@@ -28,2 +95,5 @@ return v1.map(function (x, i) { | ||
}; | ||
var deg = function deg(rad) { | ||
return rad * 180 / Math.PI; | ||
}; | ||
var mod = function mod(n, m) { | ||
@@ -33,10 +103,134 @@ return (m + n % m) % m; | ||
var getAngle = function getAngle(v) { | ||
return mod(Math.atan2(v[1], v[0]), 2 * Math.PI); | ||
return deg(mod(Math.atan2(v[1], v[0]), 2 * Math.PI)); | ||
}; | ||
var rotate = function rotate(v, rad) { | ||
return [v[0] * Math.cos(rad) - v[1] * Math.sin(rad), v[0] * Math.sin(rad) + v[1] * Math.cos(rad)]; | ||
var rotate = function rotate(v, deg) { | ||
return [v[0] * Math.cos(rad(deg)) - v[1] * Math.sin(rad(deg)), v[0] * Math.sin(rad(deg)) + v[1] * Math.cos(rad(deg))]; | ||
}; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
/* global TouchEvent */ | ||
var fingerPoints = new Observable(function (observer) { | ||
var next = function next(event) { | ||
var point = [0, 0]; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = event.touches[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var touch = _step.value; | ||
point = add(point, [touch.clientX, touch.clientY]); | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
observer.next(point); | ||
}; | ||
document.addEventListener('touchmove', next, true); | ||
return function () { | ||
return document.removeEventListener('touchmove', next, true); | ||
}; | ||
}); | ||
var combined = (function (observables) { | ||
return new Observable(function (observer) { | ||
var next = observer.next.bind(observer); | ||
var subscriptions = observables.map(function (o) { | ||
return o.subscribe(next); | ||
}); | ||
return function () { | ||
return subscriptions.forEach(function (s) { | ||
return s.unsubscribe(); | ||
}); | ||
}; | ||
}); | ||
}); | ||
/* eslint-disable no-use-before-define */ | ||
/* eslint-enable no-use-before-define */ | ||
var getLooks = function getLooks(look) { | ||
var looks = []; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = Object.keys(look)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var key = _step.value; | ||
var _src = look[key]; | ||
if (_src) { | ||
looks.push({ angle: parseFloat(key), src: _src }); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
return looks; | ||
}; | ||
function fromImage(element) { | ||
var _parseDataAttributes = parseDataAttributes(element), | ||
_parseDataAttributes$ = _parseDataAttributes.src, | ||
src = _parseDataAttributes$ === undefined ? {} : _parseDataAttributes$, | ||
fieldofvision = _parseDataAttributes.fieldofvision, | ||
timetodefault = _parseDataAttributes.timetodefault; | ||
var options = { | ||
default: element.getAttribute('src') | ||
}; | ||
if (timetodefault) options.timeToDefault = parseFloat(timetodefault); | ||
if (fieldofvision) options.fieldOfVision = parseFloat(fieldofvision); | ||
if (src.hover) options.hover = src.hover; | ||
if (src.look) options.looks = getLooks(src.look); | ||
return options; | ||
} | ||
function getOptions(img) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var userOptions = Object.assign({}, fromImage(img), options); | ||
if (!userOptions.default) throw new Error('A default URL must be specified'); | ||
return { | ||
fieldOfVision: userOptions.fieldOfVision || 150, | ||
default: userOptions.default, | ||
hover: userOptions.hover || '', | ||
points: userOptions.points || combined([mousePoints, fingerPoints]), | ||
looks: userOptions.looks || [], | ||
timeToDefault: userOptions.timeToDefault || 1000, | ||
debug: userOptions.debug || function () {} | ||
}; | ||
} | ||
var center = function center(node) { | ||
@@ -47,4 +241,10 @@ var coords = getElementCenter(node); | ||
var getAngle$1 = (function (img, point) { | ||
return getAngle(rotate(diff(point, center(img)), 90)); | ||
}); | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var shortest = function shortest(angle) { | ||
return Math.abs(angle) > Math.PI ? angle - sign(angle) * 2 * Math.PI : angle; | ||
return Math.abs(angle) > 180 ? angle - sign(angle) * 360 : angle; | ||
}; | ||
@@ -86,4 +286,3 @@ var compare = function compare(angle) { | ||
function pointToSrc(point, img, options) { | ||
var coords = point.coords; | ||
var getSrc = (function (img, point, angle, options) { | ||
var looks = options.looks, | ||
@@ -93,6 +292,5 @@ hover = options.hover, | ||
var angle = getAngle(rotate(diff(coords, center(img)), Math.PI / 2)); | ||
var src = options.default; | ||
if (hover && elementContains(img, coords)) { | ||
if (hover && elementContains(img, point)) { | ||
src = hover; | ||
@@ -107,150 +305,76 @@ } else { | ||
return src; | ||
} | ||
}); | ||
function showAndHideImages(imgs) { | ||
imgs.forEach(function (img) { | ||
img.style.position = 'fixed'; | ||
img.style.height = '0px'; | ||
document.body.appendChild(img); | ||
setTimeout(function () { | ||
return document.body.removeChild(img); | ||
}, 1000); | ||
var creepy = (function (img, options) { | ||
return new Observable(function (observer) { | ||
var backToDefault = debounce(function () { | ||
return observer.next({ src: options.default, options: options }); | ||
}, options.timeToDefault); | ||
return options.points.subscribe(function (point) { | ||
var angle = getAngle$1(img, point); | ||
var src = getSrc(img, point, angle, options); | ||
observer.next({ point: point, angle: angle, src: src, options: options }); | ||
backToDefault(); | ||
}); | ||
}); | ||
} | ||
}); | ||
function preload(img, srcs) { | ||
return loadImages(srcs).then(function (imgs) { | ||
img.creepyFaceReachableImages = imgs; | ||
if (isFirefox) showAndHideImages(imgs); | ||
var attach = (function (img, userOptions) { | ||
var options = getOptions(img, userOptions); | ||
var setSrc = function setSrc(src) { | ||
img.src = src; | ||
}; | ||
var subscribed = preload(img, options).then(function () { | ||
return creepy(img, options).subscribe(function (data) { | ||
setSrc(data.src); | ||
options.debug(data); | ||
}); | ||
}); | ||
} | ||
function point(p, target, source) { | ||
return { coords: p, target: target, source: source }; | ||
} | ||
var callWith = function callWith(value) { | ||
return function (fn) { | ||
return fn(value); | ||
}; | ||
}; | ||
function mappable(factory) { | ||
var subscribers = []; | ||
var next = function next(value) { | ||
return subscribers.forEach(function (_ref) { | ||
var apply = _ref.apply, | ||
nexts = _ref.nexts; | ||
return nexts.forEach(callWith(apply(value))); | ||
return function () { | ||
return subscribed.then(function (subscription) { | ||
subscription.unsubscribe(); | ||
setSrc(options.default); | ||
}); | ||
}; | ||
var map = function map(apply) { | ||
if (subscribers.length === 0) factory(next); | ||
var nexts = []; | ||
subscribers.push({ apply: apply, nexts: nexts }); | ||
return mappable(nexts.push.bind(nexts)); | ||
}; | ||
return { map: map }; | ||
} | ||
var events = (function (element, eventName) { | ||
return mappable(function (next) { | ||
return element.addEventListener(eventName, next, true); | ||
}); | ||
}); | ||
var mousePoints = events(document, 'mousemove').map(function (event) { | ||
return point([event.clientX, event.clientY], event.target, 'mouse'); | ||
}); | ||
var fingerPoints = events(document, 'touchmove').map(function (event) { | ||
var coords = [].slice.call(event.touches).map(function (touch) { | ||
return [touch.clientX, touch.clientY]; | ||
}).reduce(add, [0, 0]); | ||
return point(coords, event.target, 'finger'); | ||
}); | ||
var combined = (function (mappables) { | ||
return mappable(function (next) { | ||
return mappables.map(function (m) { | ||
return m.map(next); | ||
}); | ||
var watchElement = (function (node, onAdded, onRemoved) { | ||
var wasAdded = !!node.parentNode; | ||
if (wasAdded) onAdded(); | ||
if (!window.MutationObserver) return function () {}; | ||
var observer = new window.MutationObserver(function (mutations) { | ||
if (!node.parentNode && wasAdded) { | ||
onRemoved(); | ||
wasAdded = false; | ||
} else if (node.parentNode && !wasAdded) { | ||
onAdded(); | ||
wasAdded = true; | ||
} | ||
}); | ||
observer.observe(document, { childList: true, subtree: true }); | ||
return function () { | ||
return observer.disconnect(); | ||
}; | ||
}); | ||
/* global HTMLElement */ | ||
var textToAngle = function textToAngle(text) { | ||
return rad(isNaN(text) ? WindRose.getDegrees(text.toUpperCase()).value : parseFloat(text)); | ||
}; | ||
var getLooks = function getLooks(look) { | ||
return Object.keys(look || {}).map(function (key) { | ||
return { | ||
angle: textToAngle(key), src: look[key] | ||
}; | ||
/* global HTMLImageElement */ | ||
function creepyFace(img, options) { | ||
var detach = function detach() {}; | ||
var stopWatching = watchElement(img, function () { | ||
detach = attach(img, options); | ||
}, function () { | ||
detach(); | ||
}); | ||
}; | ||
var parseNumericOption = function parseNumericOption(option) { | ||
return isNaN(option) ? undefined : parseFloat(option); | ||
}; | ||
var getSrcs = function getSrcs(options) { | ||
var srcs = options.looks.map(function (_ref) { | ||
var src = _ref.src; | ||
return src; | ||
}); | ||
if (options.default) srcs.push(options.default); | ||
if (options.hover) srcs.push(options.hover); | ||
return srcs; | ||
}; | ||
function fromElement(element) { | ||
var _parseDataAttributes = parseDataAttributes(element), | ||
src = _parseDataAttributes.src, | ||
fieldofvision = _parseDataAttributes.fieldofvision, | ||
throttle$$1 = _parseDataAttributes.throttle, | ||
backtonormal = _parseDataAttributes.backtonormal; | ||
var _ref2 = src || {}, | ||
hover = _ref2.hover, | ||
look = _ref2.look; | ||
return defaults({ | ||
fieldOfVision: isNaN(fieldofvision) || rad(parseFloat(fieldofvision)), | ||
default: element.getAttribute('src'), | ||
hover: hover, | ||
looks: getLooks(look), | ||
throttle: parseNumericOption(throttle$$1), | ||
backToNormal: parseNumericOption(backtonormal) | ||
}, defaultOptions); | ||
return function () { | ||
stopWatching(); | ||
detach(); | ||
}; | ||
} | ||
var defaultOptions = { | ||
fieldOfVision: rad(150), | ||
default: '', | ||
hover: '', | ||
looks: [], | ||
points: combined([mousePoints, fingerPoints]), | ||
throttle: 0, | ||
backToNormal: 1000 | ||
}; | ||
function creepyFace(img, userOptions) { | ||
var options = defaults({}, userOptions, fromElement(img)); | ||
var backToNormal = debounce(function () { | ||
img.src = options.default; | ||
}, options.backToNormal); | ||
return preload(img, getSrcs(options)).then(function () { | ||
return options.points.map(throttle(function (point) { | ||
img.src = pointToSrc(point, img, options); | ||
options.backToNormal > 0 && backToNormal(); | ||
}, options.throttle)); | ||
}); | ||
} | ||
$('img[data-creepy]').forEach(function (img) { | ||
return creepyFace(img); | ||
$('img[data-creepy]').forEach(function (el) { | ||
if (el instanceof HTMLImageElement) creepyFace(el); | ||
}); | ||
export default creepyFace; |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.creepyFace=e()}(this,function(){"use strict";function t(t,e,n){var r=t.coords,o=n.looks,u=n.hover,a=n.fieldOfVision,i=p(y(s(r,N(e)),Math.PI/2)),l=n.default;if(u&&M(e,r))l=u;else{var c=S(i,o);c&&Math.abs(E(c.angle-i))<a/2&&(l=c.src)}return l}function e(t){if(!t)return Promise.reject();if("string"==typeof t){var n=t;(t=new Image).src=n}else{if(void 0!==t.length){var r=[].map.call(t,function(t){return e(t).catch(function(t){return t})});return Promise.all(r).then(function(t){var e=t.filter(function(t){return t.naturalWidth});return e.length===t.length?e:Promise.reject({loaded:e,errored:t.filter(function(t){return!t.naturalWidth})})})}if("IMG"!==t.tagName)return Promise.reject()}var o=new Promise(function(e,n){function r(){t.naturalWidth?e(t):n(t),t.removeEventListener("load",r),t.removeEventListener("error",r)}t.naturalWidth?e(t):t.complete?n(t):(t.addEventListener("load",r),t.addEventListener("error",r))});return o.image=t,o}function n(t){t.forEach(function(t){t.style.position="fixed",t.style.height="0px",document.body.appendChild(t),setTimeout(function(){return document.body.removeChild(t)},1e3)})}function r(t,e){return x(e).then(function(e){t.creepyFaceReachableImages=e,P&&n(e)})}function o(t){return function(e){var n;return n=/^data\-/.test(e.name),void 0===t?n:n&&t.test(e.name.slice(5))}}function u(t,e,n){return{coords:t,target:e,source:n}}function a(t){var e=[],n=function(t){return e.forEach(function(e){var n=e.apply;return e.nexts.forEach(O(n(t)))})};return{map:function(r){0===e.length&&t(n);var o=[];return e.push({apply:r,nexts:o}),a(o.push.bind(o))}}}function i(t,e,n){var r=t.length;return e=null==e?n||0:e<0?Math.max(r+e,0):Math.min(e,r)}function l(t){var e=k(t),n=e.src,r=e.fieldofvision,o=e.throttle,u=e.backtonormal,a=n||{},i=a.hover,l=a.look;return Y({fieldOfVision:isNaN(r)||m(parseFloat(r)),default:t.getAttribute("src"),hover:i,looks:q(l),throttle:G(o),backToNormal:G(u)},z)}function c(e,n){var o=Y({},n,l(e)),u=K(function(){e.src=o.default},o.backToNormal);return r(e,U(o)).then(function(){return o.points.map(J(function(n){e.src=t(n,e,o),o.backToNormal>0&&u()},o.throttle))})}var s=function(t,e){return t.map(function(t,n){return t-e[n]})},f=function(t,e){return t.map(function(t,n){return t+e[n]})},h=function(t){return t?t<0?-1:1:0},m=function(t){return t*Math.PI/180},d=function(t,e){return(e+t%e)%e},p=function(t){return d(Math.atan2(t[1],t[0]),2*Math.PI)},y=function(t,e){return[t[0]*Math.cos(e)-t[1]*Math.sin(e),t[0]*Math.sin(e)+t[1]*Math.cos(e)]},b=function(t){var e=t.getBoundingClientRect();return{y:e.top+window.pageYOffset+e.height/2,x:e.left+window.pageXOffset+e.width/2}},v=function(){function t(t,e){var n=[],r=!0,o=!1,u=void 0;try{for(var a,i=t[Symbol.iterator]();!(r=(a=i.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){o=!0,u=t}finally{try{!r&&i.return&&i.return()}finally{if(o)throw u}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),N=function(t){var e=b(t);return[e.x,e.y]},E=function(t){return Math.abs(t)>Math.PI?t-2*h(t)*Math.PI:t},g=function(t){return function(e,n){return Math.abs(E(e.angle-t))-Math.abs(E(n.angle-t))}},S=function(t,e){return e.slice(0).sort(g(t))[0]},W=function(t,e,n){return t>=e&&t<=n},w=function(t,e){var n=t.left,r=t.top,o=t.right,u=t.bottom,a=v(e,2),i=a[0],l=a[1];return W(i,n,o)&&W(l,r,u)},M=function(t,e){var n=v(e,2),r=n[0],o=n[1];return document.elementFromPoint?document.elementFromPoint(r,o)===t:w(t.getBoundingClientRect(),[r,o])},x=e,P="undefined"!=typeof navigator&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent),k=function(t,e){var n={};return void 0===(e=e||{}).separator&&(e.separator="-"),Array.prototype.slice.call(t.attributes).filter(o(e.pattern)).forEach(function(t){t.name.slice(5).split(e.separator).reduce(function(e,n,r,o){return"data"===n?e:(r===o.length-1?e[n]=t.value:e[n]=e[n]||{},e[n])},n)}),n},j=("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self,function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t,e){!function(e,n){t.exports=n()}(0,function(){var t=[90,45,22.5,11.25],e=[{symbol:"N",name:"North",depth:0},{symbol:"NbE",name:"North by East",depth:3},{symbol:"NNE",name:"North North East",depth:2},{symbol:"NEbN",name:"North East by North",depth:3},{symbol:"NE",name:"North East",depth:1},{symbol:"NEbE",name:"North East by East",depth:3},{symbol:"ENE",name:"East North East",depth:2},{symbol:"EbN",name:"East by North",depth:3},{symbol:"E",name:"East",depth:0},{symbol:"EbS",name:"East by South",depth:3},{symbol:"ESE",name:"East South East",depth:2},{symbol:"SEbE",name:"South East by East",depth:3},{symbol:"SE",name:"South East",depth:1},{symbol:"SEbS",name:"South East by South",depth:3},{symbol:"SSE",name:"South South East",depth:2},{symbol:"SbE",name:"South by East",depth:3},{symbol:"S",name:"South",depth:0},{symbol:"SbW",name:"South by West",depth:3},{symbol:"SSW",name:"South South West",depth:2},{symbol:"SWbS",name:"South West by South",depth:3},{symbol:"SW",name:"South West",depth:1},{symbol:"SWbW",name:"South West by West",depth:3},{symbol:"WSW",name:"West South West",depth:2},{symbol:"WbS",name:"West by South",depth:3},{symbol:"W",name:"West",depth:0},{symbol:"WbN",name:"West by North",depth:3},{symbol:"WNW",name:"West North West",depth:2},{symbol:"NWbW",name:"North West by West",depth:3},{symbol:"NW",name:"North West",depth:1},{symbol:"NWbN",name:"North West by North",depth:3},{symbol:"NNW",name:"North North West",depth:2},{symbol:"NbW",name:"North by West",depth:3}];return{getPoint:function(n,r){if(!(n<0||n>360)){(r=r||{}).depth=r.hasOwnProperty("depth")?r.depth:3;var o=Math.round(n/t[r.depth]),u=e.filter(function(t){return t.depth<=r.depth});return o===u.length&&(o=0),u[o]}},getDegrees:function(n,r){var o,u,a;if(r=r||{},r.depth=r.hasOwnProperty("depth")?r.depth:3,!(r.depth<0||r.depth>3)&&(e.forEach(function(e,r){n!==e.name&&n!==e.symbol||(o=r*t[3])}),u=o-t[r.depth]/2,a=o+t[r.depth]/2,void 0!==o))return{min:u>=0?u:360+u,value:o,max:a<=360?a:a-360}}}})})),O=function(t){return function(e){return e(t)}},T=function(t,e){return a(function(n){return t.addEventListener(e,n,!0)})},I=T(document,"mousemove").map(function(t){return u([t.clientX,t.clientY],t.target,"mouse")}),A=T(document,"touchmove").map(function(t){return u([].slice.call(t.touches).map(function(t){return[t.clientX,t.clientY]}).reduce(f,[0,0]),t.target,"finger")}),F=function(t,e,n){if(null!=t)for(var r=t.length,o=-1;++o<r;){var u=t[o];if(!1===e.call(n,u,o,t))break}},D=function(t,e,n){var r=t.length,o=[];for(e=i(t,e),n=i(t,n,r);e<n;)o.push(t[e++]);return o},C=function(t,e,n){for(var r in t)if(!1===e.call(n,t[r],r,t))break},L=Object.prototype.hasOwnProperty,R=function(t,e,n){C(t,function(r,o){if(L.call(t,o))return e.call(n,t[o],o,t)})},V=function(t){return null!=t&&"object"==typeof t&&!1===Array.isArray(t)},X=function(t,e){return null==t?{}:(F(D(arguments,1),function(e){V(e)&&R(e,function(e,n){null==t[n]&&(t[n]=e)})}),t)},Y=X;Y.immutable=function(){var t=D(arguments);return X.apply(null,[{}].concat(t))};var B=function(t){return m(isNaN(t)?j.getDegrees(t.toUpperCase()).value:parseFloat(t))},q=function(t){return Object.keys(t||{}).map(function(e){return{angle:B(e),src:t[e]}})},G=function(t){return isNaN(t)?void 0:parseFloat(t)},U=function(t){var e=t.looks.map(function(t){return t.src});return t.default&&e.push(t.default),t.hover&&e.push(t.hover),e},z={fieldOfVision:m(150),default:"",hover:"",looks:[],points:function(t){return a(function(e){return t.map(function(t){return t.map(e)})})}([I,A]),throttle:0,backToNormal:1e3},H=function(t){return!(!t||"object"!=typeof t)&&("object"==typeof window&&"object"==typeof window.Node?t instanceof window.Node:"number"==typeof t.nodeType&&"string"==typeof t.nodeName)},J=function(t,e){function n(){a=0,i=+new Date,u=t.apply(r,o),r=null,o=null}var r,o,u,a,i=0;return function(){r=this,o=arguments;var t=new Date-i;return a||(t>=e?n():a=setTimeout(n,e-t)),u}},K=function(t,e,n){function r(){var c=Date.now()-i;c<e&&c>=0?o=setTimeout(r,e-c):(o=null,n||(l=t.apply(a,u),a=u=null))}var o,u,a,i,l;null==e&&(e=100);var c=function(){a=this,u=arguments,i=Date.now();var c=n&&!o;return o||(o=setTimeout(r,e)),c&&(l=t.apply(a,u),a=u=null),l};return c.clear=function(){o&&(clearTimeout(o),o=null)},c};return function(t){return H(t)?[t]:"string"==typeof t?[].slice.call(document.querySelectorAll(t)):void 0}("img[data-creepy]").forEach(function(t){return c(t)}),c}); | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.creepyFace=t()}(this,function(){"use strict";function n(t){if(!t)return Promise.reject();if("string"==typeof t){var e=t;(t=new Image).src=e}else{if(void 0!==t.length){var r=[].map.call(t,function(t){return n(t).catch(function(n){return n})});return Promise.all(r).then(function(n){var t=n.filter(function(n){return n.naturalWidth});return t.length===n.length?t:Promise.reject({loaded:t,errored:n.filter(function(n){return!n.naturalWidth})})})}if("IMG"!==t.tagName)return Promise.reject()}var o=new Promise(function(n,e){function r(){t.naturalWidth?n(t):e(t),t.removeEventListener("load",r),t.removeEventListener("error",r)}t.naturalWidth?n(t):t.complete?e(t):(t.addEventListener("load",r),t.addEventListener("error",r))});return o.image=t,o}function t(n){n.forEach(function(n){n.style.position="fixed",n.style.height="0px";var t=document.body;t&&(t.appendChild(n),setTimeout(function(){return t.removeChild(n)},1e3))})}function e(n,e){return c(l(e)).then(function(e){n.creepyFaceReachableImages=e,f&&t(e)})}function r(n){return function(t){var e;return e=/^data\-/.test(t.name),void 0===n?e:e&&n.test(t.name.slice(5))}}function o(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function u(n){var t=s(n),e=t.src,r=void 0===e?{}:e,o=t.fieldofvision,u=t.timetodefault,i={default:n.getAttribute("src")};return u&&(i.timeToDefault=parseFloat(u)),o&&(i.fieldOfVision=parseFloat(o)),r.hover&&(i.hover=r.hover),r.look&&(i.looks=T(r.look)),i}function i(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=Object.assign({},u(n),t);if(!e.default)throw new Error("A default URL must be specified");return{fieldOfVision:e.fieldOfVision||150,default:e.default,hover:e.hover||"",points:e.points||O([h,M]),looks:e.looks||[],timeToDefault:e.timeToDefault||1e3,debug:e.debug||function(){}}}function a(n,t){var e=function(){},r=X(n,function(){e=W(n,t)},function(){e()});return function(){r(),e()}}var c=n,f="undefined"!=typeof navigator&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent),l=function(n){var t=n.looks.map(function(n){return n.src});return n.default&&t.push(n.default),n.hover&&t.push(n.hover),t},s=function(n,t){var e={};return void 0===(t=t||{}).separator&&(t.separator="-"),Array.prototype.slice.call(n.attributes).filter(r(t.pattern)).forEach(function(n){n.name.slice(5).split(t.separator).reduce(function(t,e,r,o){return"data"===e?t:(r===o.length-1?t[e]=n.value:t[e]=t[e]||{},t[e])},e)}),e},d=function(){function n(n,t){for(var e=0;e<t.length;e++){var r=t[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}}(),v=function(){function n(t){o(this,n),this.subscriber=function(n){return function(){}},this.subscriber=t}return d(n,[{key:"subscribe",value:function(n){var t={next:n},e=this.subscriber(t);return"function"==typeof e?{unsubscribe:e}:e}}]),n}(),h=new v(function(n){var t=function(t){return n.next([t.clientX,t.clientY])};return document.addEventListener("mousemove",t,!0),function(){return document.removeEventListener("mousemove",t,!0)}}),m=function(n,t){return n.map(function(n,e){return n-t[e]})},p=function(n,t){return n.map(function(n,e){return n+t[e]})},b=function(n){return n?n<0?-1:1:0},y=function(n){return n*Math.PI/180},g=function(n){return 180*n/Math.PI},w=function(n,t){return(t+n%t)%t},x=function(n){return g(w(Math.atan2(n[1],n[0]),2*Math.PI))},E=function(n,t){return[n[0]*Math.cos(y(t))-n[1]*Math.sin(y(t)),n[0]*Math.sin(y(t))+n[1]*Math.cos(y(t))]},M=new v(function(n){var t=function(t){var e=[0,0],r=!0,o=!1,u=void 0;try{for(var i,a=t.touches[Symbol.iterator]();!(r=(i=a.next()).done);r=!0){var c=i.value;e=p(e,[c.clientX,c.clientY])}}catch(n){o=!0,u=n}finally{try{!r&&a.return&&a.return()}finally{if(o)throw u}}n.next(e)};return document.addEventListener("touchmove",t,!0),function(){return document.removeEventListener("touchmove",t,!0)}}),O=function(n){return new v(function(t){var e=t.next.bind(t),r=n.map(function(n){return n.subscribe(e)});return function(){return r.forEach(function(n){return n.unsubscribe()})}})},T=function(n){var t=[],e=!0,r=!1,o=void 0;try{for(var u,i=Object.keys(n)[Symbol.iterator]();!(e=(u=i.next()).done);e=!0){var a=u.value,c=n[a];c&&t.push({angle:parseFloat(a),src:c})}}catch(n){r=!0,o=n}finally{try{!e&&i.return&&i.return()}finally{if(r)throw o}}return t},j=function(n){var t=n.getBoundingClientRect();return{y:t.top+window.pageYOffset+t.height/2,x:t.left+window.pageXOffset+t.width/2}},k=function(n){var t=j(n);return[t.x,t.y]},L=function(n,t){return x(E(m(t,k(n)),90))},P=function(){function n(n,t){var e=[],r=!0,o=!1,u=void 0;try{for(var i,a=n[Symbol.iterator]();!(r=(i=a.next()).done)&&(e.push(i.value),!t||e.length!==t);r=!0);}catch(n){o=!0,u=n}finally{try{!r&&a.return&&a.return()}finally{if(o)throw u}}return e}return function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return n(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),F=function(n){return Math.abs(n)>180?n-360*b(n):n},I=function(n){return function(t,e){return Math.abs(F(t.angle-n))-Math.abs(F(e.angle-n))}},A=function(n,t){return t.slice(0).sort(I(n))[0]},N=function(n,t,e){return n>=t&&n<=e},D=function(n,t){var e=n.left,r=n.top,o=n.right,u=n.bottom,i=P(t,2),a=i[0],c=i[1];return N(a,e,o)&&N(c,r,u)},S=function(n,t){var e=P(t,2),r=e[0],o=e[1];return document.elementFromPoint?document.elementFromPoint(r,o)===n:D(n.getBoundingClientRect(),[r,o])},C=function(n,t,e,r){var o=r.looks,u=r.hover,i=r.fieldOfVision,a=r.default;if(u&&S(n,t))a=u;else{var c=A(e,o);c&&Math.abs(F(c.angle-e))<i/2&&(a=c.src)}return a},R=function(n,t,e){function r(){var f=Date.now()-a;f<t&&f>=0?o=setTimeout(r,t-f):(o=null,e||(c=n.apply(i,u),i=u=null))}var o,u,i,a,c;null==t&&(t=100);var f=function(){i=this,u=arguments,a=Date.now();var f=e&&!o;return o||(o=setTimeout(r,t)),f&&(c=n.apply(i,u),i=u=null),c};return f.clear=function(){o&&(clearTimeout(o),o=null)},f},V=function(n,t){return new v(function(e){var r=R(function(){return e.next({src:t.default,options:t})},t.timeToDefault);return t.points.subscribe(function(o){var u=L(n,o),i=C(n,o,u,t);e.next({point:o,angle:u,src:i,options:t}),r()})})},W=function(n,t){var r=i(n,t),o=function(t){n.src=t},u=e(n,r).then(function(){return V(n,r).subscribe(function(n){o(n.src),r.debug(n)})});return function(){return u.then(function(n){n.unsubscribe(),o(r.default)})}},X=function(n,t,e){var r=!!n.parentNode;if(r&&t(),!window.MutationObserver)return function(){};var o=new window.MutationObserver(function(o){!n.parentNode&&r?(e(),r=!1):n.parentNode&&!r&&(t(),r=!0)});return o.observe(document,{childList:!0,subtree:!0}),function(){return o.disconnect()}},Y=function(n){return!(!n||"object"!=typeof n)&&("object"==typeof window&&"object"==typeof window.Node?n instanceof window.Node:"number"==typeof n.nodeType&&"string"==typeof n.nodeName)};return function(n){return Y(n)?[n]:"string"==typeof n?[].slice.call(document.querySelectorAll(n)):void 0}("img[data-creepy]").forEach(function(n){n instanceof HTMLImageElement&&a(n)}),a}); |
{ | ||
"name": "creepyface", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"author": "Alejandro Tardín <alejandro@tardin.com>", | ||
@@ -13,8 +13,14 @@ "license": "MIT", | ||
"devDependencies": { | ||
"babel-eslint": "^8.0.1", | ||
"babel-plugin-transform-class-properties": "^6.24.1", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-preset-flow": "^6.23.0", | ||
"eslint-plugin-flowtype": "^2.39.1", | ||
"flow-bin": "^0.58.0", | ||
"flow-typed": "^2.2.3", | ||
"jest": "^20.0.4", | ||
"lolex": "^2.1.2", | ||
"rollup": "^0.47.2", | ||
"rollup": "^0.50.0", | ||
"rollup-plugin-babel": "^3.0.1", | ||
"rollup-plugin-browsersync": "^0.2.2", | ||
"rollup-plugin-browsersync": "^0.2.5", | ||
"rollup-plugin-commonjs": "^8.1.0", | ||
@@ -32,6 +38,3 @@ "rollup-plugin-node-resolve": "^3.0.0", | ||
"is-firefox": "^1.0.3", | ||
"object.defaults": "^1.1.0", | ||
"queryselectorall": "^0.1.0", | ||
"throttleit": "^1.0.0", | ||
"windrose": "^2.0.2" | ||
"queryselectorall": "^0.1.0" | ||
}, | ||
@@ -43,5 +46,14 @@ "scripts": { | ||
"build:netlify": "npm run build && cp dist/creepyface.umd.js example/", | ||
"test": "standard && jest", | ||
"test": "flow --include-warnings --quiet && standard && jest", | ||
"fix": "standard --fix" | ||
}, | ||
"standard": { | ||
"ignore": [ | ||
"flow-typed/" | ||
], | ||
"parser": "babel-eslint", | ||
"plugins": [ | ||
"flowtype" | ||
] | ||
} | ||
} |
# Creepy Face | ||
Creepy Face is a little JavaScript tool (2.7K minified & gzipped) for making your face follow the mouse (or fingers). It is ideal for resumes, team presentation sites, etc... | ||
Creepy Face is a little JavaScript tool (<3K minified & gzipped) for making your face follow the mouse (or fingers). It is ideal for resumes, team presentation sites, etc... | ||
@@ -20,14 +20,14 @@ ![Example animated gif of a face following the pointer](example.gif) | ||
data-src-hover="img/face/crazy.jpg" | ||
data-src-look-n="img/face/north.jpg" | ||
data-src-look-ne="img/face/north-east.jpg" | ||
data-src-look-e="img/face/east.jpg" | ||
data-src-look-se="img/face/south-east.jpg" | ||
data-src-look-s="img/face/south.jpg" | ||
data-src-look-sw="img/face/south-west.jpg" | ||
data-src-look-w="img/face/west.jpg" | ||
data-src-look-nw="img/face/north-west.jpg" | ||
data-src-look-0="img/face/north.jpg" | ||
data-src-look-45="img/face/north-east.jpg" | ||
data-src-look-90="img/face/east.jpg" | ||
data-src-look-135="img/face/south-east.jpg" | ||
data-src-look-180="img/face/south.jpg" | ||
data-src-look-225="img/face/south-west.jpg" | ||
data-src-look-270="img/face/west.jpg" | ||
data-src-look-315="img/face/north-west.jpg" | ||
/> | ||
``` | ||
The `data-src-look` attributes can specify either compass points (n, ne, w...) or degrees (0 - 360). For example `data-src-look-s` would be equivalent to `data-src-look-180`. | ||
The `data-src-look` specify degrees (0 - 360). | ||
@@ -53,16 +53,19 @@ 3. Include creepyface script at the end of your page: | ||
creepyFace(faceImg, { | ||
throttle: 100, // Number of milliseconds to wait between src updates | ||
const cancel = creepyFace(faceImg, { | ||
hover: 'img/face/crazy.jpg', // Image URL to display on hover | ||
looks: [ // Each of the images looking at a given direction (angles in radians) | ||
{angle: 0 * Math.PI / 4, src: 'img/face/north.jpg'}, | ||
{angle: 1 * Math.PI / 4, src: 'img/face/north-east.jpg'}, | ||
{angle: 2 * Math.PI / 4, src: 'img/face/east.jpg'}, | ||
{angle: 3 * Math.PI / 4, src: 'img/face/south-east.jpg'}, | ||
{angle: 4 * Math.PI / 4, src: 'img/face/south.jpg'}, | ||
{angle: 5 * Math.PI / 4, src: 'img/face/south-west.jpg'}, | ||
{angle: 6 * Math.PI / 4, src: 'img/face/west.jpg'}, | ||
{angle: 7 * Math.PI / 4, src: 'img/face/north-west.jpg'} | ||
] | ||
looks: [ // Each of the images looking at a given direction | ||
{angle: 0, src: 'img/face/north.jpg'}, | ||
{angle: 45, src: 'img/face/north-east.jpg'}, | ||
{angle: 90, src: 'img/face/east.jpg'}, | ||
{angle: 135, src: 'img/face/south-east.jpg'}, | ||
{angle: 180, src: 'img/face/south.jpg'}, | ||
{angle: 225, src: 'img/face/south-west.jpg'}, | ||
{angle: 270, src: 'img/face/west.jpg'}, | ||
{angle: 315, src: 'img/face/north-west.jpg'} | ||
], | ||
timeToDefault: 1000 // Time (in ms) to show back the default image after no input is detected | ||
}) | ||
// at some point | ||
cancel() // will restore the original image and stop creepyface | ||
``` | ||
@@ -69,0 +72,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
34404
6
682
80
17
1
- Removedobject.defaults@^1.1.0
- Removedthrottleit@^1.0.0
- Removedwindrose@^2.0.2
- Removedarray-each@1.0.1(transitive)
- Removedarray-slice@1.1.0(transitive)
- Removedfor-in@1.0.2(transitive)
- Removedfor-own@1.0.0(transitive)
- Removedisobject@3.0.1(transitive)
- Removedobject.defaults@1.1.0(transitive)
- Removedthrottleit@1.0.1(transitive)
- Removedwindrose@2.1.0(transitive)