Permalink
Browse files

Initial commit

  • Loading branch information...
dinohamzic committed Nov 29, 2018
0 parents commit 929edee66c1cc18f1c229dd2fd9bbae81c9a41db
Showing with 4,567 additions and 0 deletions.
  1. +6 −0 .babelrc
  2. +2 −0 .eslintignore
  3. +8 −0 .eslintrc.json
  4. +2 −0 .gitignore
  5. +1 −0 lib/displaceable.js
  6. +4,355 −0 package-lock.json
  7. +35 −0 package.json
  8. +158 −0 src/displaceable.js
@@ -0,0 +1,6 @@
{
"presets": [
["@babel/preset-env", { "targets": { "ie": "10" } }],
"minify"
]
}
@@ -0,0 +1,2 @@
lib
node_modules
@@ -0,0 +1,8 @@
{
"env": { "browser": true },
"extends": "standard",
"rules": {
"padded-blocks": ["error", { "classes": "always" }],
"space-before-function-paren": ["error", "never"]
}
}
@@ -0,0 +1,2 @@
.DS_Store
node_modules

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,35 @@
{
"name": "displaceable",
"version": "0.1.0",
"description": "Super smooth element displacement on mouse move.",
"main": "lib/displaceable.js",
"scripts": {
"build": "babel src -d lib"
},
"keywords": [
"animate",
"animation",
"displace",
"element",
"elements",
"mouse",
"pointer",
"skew",
"smooth",
"tilt"
],
"author": "Dino Hamzić",
"license": "MIT",
"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"babel-preset-minify": "^0.5.0",
"eslint": "^5.9.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^8.0.0",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0"
}
}
@@ -0,0 +1,158 @@
export default class Displaceable {
constructor(nodes, settings = {}) {
try {
this.nodes = this.normalizeNodes(nodes)
this.initializeSettings(settings)
this.initializeTrigger()
} catch (e) {
return console.error(e)
}
this.initializeNodes()
this.addEventListeners()
}
normalizeNodes(nodes) {
if (!nodes) {
throw new Error(
`Unable to initialize Displaceable: ` +
`"${nodes}" is not a Node, NodeLists or array of Nodes.`
)
}
if (nodes instanceof Node) {
return [nodes]
}
if (nodes instanceof NodeList) {
return [].slice.call(nodes)
}
if (nodes instanceof Array) {
nodes.forEach(node => {
if (!(node instanceof Node)) {
throw new Error(`Error: "${node}" is not a valid Node.`)
}
})
return nodes
}
}
initializeSettings(customSettings) {
this.settings = {
displaceFactor: 3,
lockX: false,
lockY: false,
resetTime: 1000,
skewFactor: 5,
trigger: window,
...customSettings
}
}
initializeTrigger() {
const { trigger } = this.settings
if (!(trigger instanceof Node) && trigger !== window) {
throw new Error(
`Error: "${trigger}" is not a valid displacement trigger. ` +
`The displacement trigger must be a valid HTML Node.`
)
}
if (trigger === window) {
this.triggerCenterX = window.innerWidth / 2
this.triggerCenterY = window.innerHeight / 2
} else {
const { x, y, width, height } = trigger.getBoundingClientRect()
if (width === 0 || height === 0) {
throw new Error(
`Error: "${trigger}" has invalid dimensions. ` +
`Both width and height must be greater than zero.`
)
}
this.triggerCenterX = x + width / 2
this.triggerCenterY = y + height / 2
}
}
initializeNodes() {
this.nodes.forEach(node => {
node.style.pointerEvents = `none`
node.style.willChange = `transform`
})
}
addEventListeners() {
const { trigger } = this.settings
trigger.onmousemove = e => this.handleMouseMove(e)
trigger.onmouseout = () => this.handleMouseOut()
window.addEventListener(`resize`, () => this.initializeTrigger())
}
handleMouseMove(e) {
window.requestAnimationFrame(() => this.animateNodes(e))
}
handleMouseOut() {
const { resetTime } = this.settings
window.requestAnimationFrame(() => {
this.nodes.forEach(node => {
node.style.transition = `transform ${resetTime}ms`
node.style.transform = ``
})
})
}
animateNodes(e) {
const mouseX = e.clientX
const mouseY = e.clientY
const displacementStrengthX = mouseX - this.triggerCenterX
const displacementStrengthY = mouseY - this.triggerCenterY
let { displaceFactor, skewFactor } = this.settings
this.nodes.forEach(node => {
displaceFactor = node.dataset.displaceFactor
? parseFloat(node.dataset.displaceFactor)
: displaceFactor
skewFactor = node.dataset.skewFactor
? parseFloat(node.dataset.skewFactor)
: skewFactor
const normalizedSkewFactor = skewFactor / 100
let displaceX = Math.sqrt(Math.abs(displacementStrengthX)) * displaceFactor
let displaceY = Math.sqrt(Math.abs(displacementStrengthY)) * displaceFactor
let skewX = Math.sqrt(Math.abs(displacementStrengthX)) * normalizedSkewFactor
let skewY = Math.sqrt(Math.abs(displacementStrengthY)) * normalizedSkewFactor
if (displacementStrengthX < 0) {
displaceX *= -1
skewX *= -1
skewY *= -1
}
if (displacementStrengthY < 0) {
displaceY *= -1
}
const transform = (
`translate(${displaceX}px, ${displaceY}px) ` +
`skew(${skewY}deg, ${skewX}deg)`
)
node.style.transition = `transform .05s`
node.style.transform = transform
})
}
}

0 comments on commit 929edee

Please sign in to comment.