Skip to content

Commit 7418fc9

Browse files
committed
refactor mouse shadow to use event controller
1 parent f87ce2e commit 7418fc9

File tree

12 files changed

+172
-59
lines changed

12 files changed

+172
-59
lines changed

blocks/card/Card--main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default class CardMain extends CardAbstract {
1111
*/
1212
constructor() {
1313
// in main cards, nothing happens
14-
// after the transformation, thus the empty function
15-
super('--main', () => {});
14+
// after the transformation, thus the empty functions
15+
super('--main', () => {}, () => {});
1616
}
1717
}

blocks/card/Card--projects.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export default class CardProjects extends CardAbstract {
1818
super(
1919
'--projects',
2020
CardProjects._postTransformFunction,
21+
() => {},
2122
CardProjects._transformationFunction
23+
//TODO: implement shadowFunction for project cards
2224
);
2325
}
2426

blocks/card/Card.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import CardAbstract from './CardAbstract.js';
77
export default class Card extends CardAbstract {
88
constructor() {
99
// in cards without modifiers, nothing happens
10-
// after the transformation, thus the empty function
11-
super('', () => {});
10+
// after the transformation, thus the empty functions
11+
super('', () => {}, () => {});
1212
}
1313
}

blocks/card/CardAbstract.js

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import CT
2-
from './CardTransformable.js';
3-
import TF
4-
from '../../js/transformationNew/TransformationFunctions.js';
5-
import LA
6-
from '../../js/math/LinearAlgebra.js';
1+
import CT from './CardTransformable.js';
2+
import CM from './CardMouseShadowed.js';
3+
import TF from '../../js/transformationNew/TransformationFunctions.js';
4+
import LA from '../../js/math/LinearAlgebra.js';
75

86
/**
97
* Base for the transformation controller for card blocks, which automates
@@ -23,7 +21,10 @@ export default class cardAbstract {
2321
constructor(
2422
modifier = '',
2523
postTransformFunction,
26-
transformationFunction = cardAbstract._transformationFunction) {
24+
postShadowFunction,
25+
transformationFunction = cardAbstract._transformationFunction,
26+
shadowFunction = cardAbstract._shadowFunction
27+
) {
2728

2829
this._throwIfAbstractClass();
2930

@@ -32,6 +33,12 @@ export default class cardAbstract {
3233
postTransformFunction,
3334
transformationFunction
3435
);
36+
37+
this._cm = new CM(
38+
modifier,
39+
postShadowFunction,
40+
shadowFunction
41+
)
3542
}
3643

3744
/**
@@ -56,13 +63,8 @@ export default class cardAbstract {
5663
invRotAxis = [
5764
rotAxis[1],
5865
-rotAxis[0]
59-
],
60-
rect = args.eventControlElement.domElement.getBoundingClientRect(),
61-
hover = [
62-
args.event.clientX - rect.left,
63-
args.event.clientY - rect.top
6466
];
65-
67+
6668
return {
6769
transform:
6870
`perspective(2000px) ` +
@@ -71,21 +73,32 @@ export default class cardAbstract {
7173
`scale(${TF
7274
.advBellCurve(args.transformOrigin, args.mousePosition,
7375
0.9, 1, 2)}) ` +
74-
'translateZ(0) ',
75-
'--card__inner--hover-left': hover[0] + 'px',
76-
'--card__inner--hover-top': hover[1] + 'px'
76+
'translateZ(0) '
7777
};
7878
}
7979

80+
static _shadowFunction(args) {
81+
const
82+
rect = args.eventControlElement.domElement.getBoundingClientRect(),
83+
hover = [
84+
args.event.clientX - rect.left,
85+
args.event.clientY - rect.top
86+
];
87+
88+
return {
89+
'--card__inner--mouse-shadow-left': hover[0] + 'px',
90+
'--card__inner--mouse-shadow-top': hover[1] + 'px'
91+
}
92+
}
93+
8094
/**
81-
* more specific version of {TransformationController}'s
82-
* mousemoveEventTransform that already specifies where to find the
83-
* passed transformation functions and what elements it applies to
95+
* @todo what does this do in simple words
8496
* @see TransformationController
8597
* @returns {void}
8698
*/
8799
mousemoveEvent() {
88100
this._ct.mousemoveEventTransform();
101+
this._cm.mousemoveEventShadow();
89102
}
90103

91104
/**

blocks/card/CardMouseShadowed.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import MC from '../../js/mouseShadow/MouseShadowController.js';
2+
3+
/**
4+
* Base for the mouse shadow controller for card blocks, which automates
5+
* the mouse shadow effect
6+
* @abstract
7+
* @extends MouseShadowController
8+
*/
9+
export default class CardMouseShadowed extends MC {
10+
/**
11+
* @param {String} [modifier = ''] Modifier of the card block.
12+
* Default '' means mo modifier.
13+
* @returns {void}
14+
*/
15+
constructor(
16+
modifier = '',
17+
postShadowFunction,
18+
shadowFunction) {
19+
20+
super(
21+
document.body,
22+
`.card${modifier} > .card__inner`
23+
);
24+
25+
this._postShadowFunction = postShadowFunction;
26+
this._shadowFunction = shadowFunction;
27+
}
28+
29+
/**
30+
* more specific version of {MouseShadowController}'s
31+
* mousemoveEventShadow that already specifies where to find the
32+
* passed shadow functions and what elements it applies to
33+
* @see MouseShadowController
34+
* @returns {void}
35+
*/
36+
mousemoveEventShadow() {
37+
super.mousemoveEventShadow(
38+
this._shadowFunction,
39+
'*',
40+
this._postShadowFunction
41+
);
42+
}
43+
}

blocks/card/CardTransformable.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import TC
2-
from '../../js/transformationNew/TransformationController.js';
1+
import TC from '../../js/transformationNew/TransformationController.js';
32

43
/**
54
* Base for the transformation controller for card blocks, which automates
65
* the 3d effect
76
* @abstract
87
* @extends TransformationController
98
*/
10-
export default class cardTransformable extends TC {
9+
export default class CardTransformable extends TC {
1110
/**
1211
* @param {String} [modifier = ''] Modifier of the card block.
1312
* Default '' means mo modifier.
@@ -25,8 +24,6 @@ export default class cardTransformable extends TC {
2524

2625
this._postTransformFunction = postTransformFunction;
2726
this._transformationFunction = transformationFunction;
28-
29-
console.log(this);
3027
}
3128

3229
/**

blocks/card/card.blockdoc.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ <h3><code id="modifiers---_button--s">.button--s</code></h3>
174174
<td>
175175
<textarea cols="70">&lt;input type="button" class="button" value="button"&gt;</textarea>
176176
</td>
177-
<td><input type="button" class="button button--s" value="button"</td>
177+
<td><input type="button" class="button button--s" value="button"></td>
178178
</tr>
179179
</table>
180180
<h2>variables</h2>

blocks/card/card.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
/**
55
* @variable {length} --card--padding
66
* @variable {bg-image} --card--additional-background-image
7-
* @variable {length} --card__inner--hover-left
8-
* @variable {length} --card__inner--hover-top
7+
* @variable {length} --card__inner--mouse-shadow-left
8+
* @variable {length} --card__inner--mouse-shadow-top
99
*/
1010
.card {
1111
/* local private vars */
@@ -48,11 +48,11 @@
4848
radial-gradient(
4949
circle at
5050
calc(
51-
var(--card__inner--hover-left, -100%)
51+
var(--card__inner--mouse-shadow-left, -100%)
5252
/ var(--_hover-scale)
5353
)
5454
calc(
55-
var(--card__inner--hover-top, -100%) /
55+
var(--card__inner--mouse-shadow-top, -100%) /
5656
var(--_hover-scale)
5757
),
5858
var(--_c0) 0,

js/eventControl/EventController.js

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default class EventController {
2525
* doesn't do anything, delete it.
2626
* @returns {void}
2727
*/
28-
constructor(baseElement, queryFilter = '*', onlyNewElements = true,
28+
constructor(baseElement, queryFilter = '*', classes = [], onlyNewElements = true,
2929
eventControlClass = ECE) {
3030
/**
3131
* @type {MutationObserver}
@@ -45,10 +45,8 @@ export default class EventController {
4545
this.onlyNewElements = onlyNewElements;
4646
/**
4747
* @type {string}
48-
* @todo add more specific classes in child classes of this classes
49-
* for example .transformable-element
5048
*/
51-
this.classes = ['event-controlled-element'];
49+
this.classes = ['event-controlled-element', ...classes];
5250
/**
5351
* @type {class}
5452
*/
@@ -68,16 +66,11 @@ export default class EventController {
6866
* @returns {void}
6967
*/
7068
_addExistingElements(baseElement) {
71-
const classesConnected = this.classes
72-
.map(className => '.' + className)
73-
.join(' ');
74-
7569
const filtered =
7670
[...baseElement.querySelectorAll(this.queryFilter)]
7771
.filter(e =>
78-
this.onlyNewElements ?
79-
e.matches(`:not(${classesConnected})`) :
80-
true
72+
!this.onlyNewElements ||
73+
this.classes.some(c => e.matches(`:not(.${c})`))
8174
);
8275

8376
filtered.forEach(element =>
@@ -146,22 +139,17 @@ export default class EventController {
146139
/**
147140
* Adds an array of elements to the system. Calling this method from
148141
* outside this class only makes sense in few cases, because changes
149-
* to the element are not observed if itn't child of the baseElement.
142+
* to the element are not observed if isn't child of the baseElement.
150143
* @param {object[]} elements - Array of DOM elements. Only elements
151144
* that pass the queryFilter are added.
152145
* @returns {void}
153146
*/
154147
add(elements) {
155-
const classesConnected = this.classes
156-
.map(className => '.' + className)
157-
.join(' ');
158-
159148
elements
160149
.filter(e => e.matches(this.queryFilter))
161150
.filter(e =>
162-
this.onlyNewElements ?
163-
e.matches(`:not(${classesConnected})`) :
164-
true
151+
!this.onlyNewElements ||
152+
this.classes.some(c => e.matches(`:not(.${c})`))
165153
)
166154
.forEach(element =>
167155
this.addEventControlElement(element)
@@ -210,7 +198,7 @@ export default class EventController {
210198
* @param {string} [additionalFilter='*'] - css query that has to
211199
* apply additionaly to the one passed in the constructor
212200
* @param {function} [postFunction = (event, element)=>{}] - optional
213-
* function that runs after the css change is sucessfully
201+
* function that runs after the css change is successfully
214202
* handeled internally. See {PostTransformFunctions} for examples
215203
* and predefined functions.
216204
* @returns {void}
@@ -219,14 +207,17 @@ export default class EventController {
219207
eventType = 'mousemove',
220208
modificationFunction = args => [],
221209
additionalFilter = '*',
222-
postFunction = (controller, event, element) => {}) {
210+
postFunction = (controller, event, element) => {}
211+
) {
212+
223213
this.eventControlElements
224214
.filter(ece => ece.domElement.matches(additionalFilter))
225-
.forEach(ece =>
215+
.forEach(ece => {
226216
document.addEventListener(eventType, event => {
227217
this._modify(event, ece, modificationFunction);
228218
postFunction.call(this, event, ece);
229219
})
220+
}
230221
);
231222
}
232223

@@ -245,7 +236,7 @@ export default class EventController {
245236
*/
246237
_modify(event, ece, modificationFunction) {
247238
/**
248-
* @todo remove transformOrigin and make modification funtions use that directly
239+
* @todo remove transformOrigin and make modification functions use that directly
249240
* from eventControlElement
250241
*/
251242
const args = {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import EC from '../eventControl/EventController.js';
2+
import ME from './MouseShadowElement.js';
3+
4+
/**
5+
* Simplifies watching and regulating CSS shadow effects that are supposed
6+
* to replace the mouse pointer by by linking DOM elements
7+
* MouseShadowElements and actions that should be performed after
8+
* transforming. Also watches for DOM mutations that could create or
9+
* delete transforming nodes or change the way these nodes are
10+
* transformed. This class is really similar to {TrabsformationController}
11+
* @todo delete MouseShadowElements of elements that where removed
12+
*/
13+
export default class MouseShadowController extends EC {
14+
/**
15+
* @param {object} baseElement - The common ancestor DOM element of
16+
* all shadowed elements. Attention: Depending on how many
17+
* children and subchildren this element has, the choice of the
18+
* correct baseElement affects the website performance. Don't spam
19+
* DOM mutations in the baseElement subtree.
20+
* @param {string} [queryFilter = '*'] - This method only looks for
21+
* elements that match the queryFilter. Again: The more specific,
22+
* the better.
23+
* @param {boolean} [onlyNewElements = true] forgot what it does.
24+
* @todo Find out what exactly onlyNewElements does and add docs. If it
25+
* doesn't do anything, delete it.
26+
* @returns {void}
27+
*/
28+
constructor(baseElement, queryFilter = '*', onlyNewElements = true) {
29+
super(baseElement, queryFilter, ['mouse-shadow-element'], onlyNewElements, ME);
30+
}
31+
32+
/**
33+
* Adds an mousemove eventListener for each DOM element that matches
34+
* the criteria. Defines how the element should be shadowed in case
35+
* of a mousemove and what should happen afterwards
36+
* @param {function} [shadowFunction=(o, m)=>'none'] - returns
37+
* a css transformation string. params: array of mouse position
38+
* (x, y).
39+
* @param {string} [additionalFilter='*'] - css query that has to
40+
* apply additionally to the one passed in the constructor
41+
* @param {function} [postFunction = (event, element)=>{}] - optional
42+
* function that runs after the mouse shadow is successfully
43+
* added internally.
44+
* @returns {void}
45+
*/
46+
mousemoveEventShadow(
47+
shadowFunction = (o, m)=>'none',
48+
additionalFilter='*',
49+
postFunction = (event, element)=>{} ) {
50+
this.listenToChangeCss(
51+
'mousemove', shadowFunction,
52+
additionalFilter, postFunction
53+
);
54+
}
55+
}

0 commit comments

Comments
 (0)