Intersection Observer + anime.js - javascript

I want to animate my text when it's in the viewport. I'm just trying things out and saw that many are using Intersection Observer for checking if the element is in the viewport. But now I came up with a problem. My browser tells me: "Uncaught TypeError: IntersectionObserver.observe: Argument 1 is not an object."
Here's the code:
// Fade-up animation.
const ani1 = document.querySelector(".fade__up__normal");
const callback = (entries, observer) => {
entries.forEach((entry) => {
if(entry.isIntersecting) {
fadeUpNormal.play();
observer.unobserve(entry.target);
}
})
}
const options = {
root: null,
rootMargin: "0px",
threshold: .2,
}
const myObserver = new IntersectionObserver(callback, options)
myObserver.observe(ani1)
// Fade-up animations (on-scroll).
const ani2 = document.querySelector(".fade__up__scroll");
const callback1 = (entries, observer) => {
entries.forEach((entry) => {
if(entry.isIntersecting) {
fadeUpScrollInView.play();
observer.unobserve(entry.target);
}
})
};
const secondObserver = new IntersectionObserver(callback1, options);
secondObserver.observe(ani2);
//...
var fadeUpNormal = anime.timeline({
loop: false,
autoplay: false,
}).add({
targets: '.fade__up__normal',
translateY: [100,0],
translateZ: 0,
opacity: [0,1],
easing: 'easeOutExpo',
duration: 1400,
delay: 100,
});
var fadeUpScrollInView = anime.timeline({
loop: false,
autoplay: false,
}).add({
targets: '.fade__up__scroll',
translateY: [100,0],
translateZ: 0,
opacity: [0,1],
easing: 'easeOutExpo',
duration: 1400,
delay: 100,
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/intersection-observer#0.12.0/intersection-observer.js"></script>
<div class="text fade__up__normal">This is an example.</div>
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<br>.
<div class="text2 fade__up__scroll">This is an example.</div>
But the problem here is that when I go on my other HTML site the error pops up. Maybe I can't use .observe two times? Unfortunately, my knowledge is not yet sufficient for this.

Related

fabric.js: Asynchronously add to group fails

I am trying to create an abstraction for a loadable group. In this instance, I am using the load svg function to create a arrow to add to the group, but this similarly fails when adding anything to the canvas dynamically.
export class CustomGroup extends fabric.Group {
ready = new BehaviorSubject(false);
constructor(title: string = '') {
super(
[
// Adding something here causes everything to magically work
// new fabric.IText(title)
],
{
left: 500,
top: 250,
originX: 'center',
originY: 'center',
angle: 90,
hasRotatingPoint: false,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
}
);
setTimeout(() => {
// Load an svg or some other stuff dynamically...
// This doesn't show up if I don't add a thing during construction time (above)
this.add(new fabric.Circle({ fill: '#ff0000', radius: 5 }));
this.ready.next(true);
}, 500);
// This fails the same way
// fabric.loadSVGFromString(ARROW_SVG, (svg: fabric.Object[]) => {
// this.add(...svg);
// this.ready.next(true);
// });
}
}
const group = new CustomGroup('test');
group.ready.subscribe((ready) => {
if (ready) {
canvas.add(group);
}
});
When I run this code, my circle shows up fine, but I have to add something to the group beforehand in order to make it work, which is something I don't want to do.
Why won't the add work when I'm using it this way?

Use Element.animate() to change background-color

Trying to use Element.animate() to change background-color, to mimic refresh effect.
Code:
const blinkOnPage = (id) => {
document.getElementById(id).animate(
[
{"background-color": '#def', color: '#def'},
], {
easing: 'ease-in-out',
duration: 200
});
}
In my test, color works, but background-color doesn't, how to fix it?
Never mind, just found the solution:
Change background-color to background works.
const blinkOnPage = (id) => {
document.getElementById(id).animate(
[
{background: '#def', color: '#def'},
], {
easing: 'ease-in-out',
duration: 100
});
}

I am having trouble understanding the Leader-Line js documentation

I am trying to create code that will draw a line from point a to point b using the leaderline library. https://github.com/anseki/leader-line
It looks like the section I need to reference is under Methods
self = line.show([showEffectName[, animOptions]])
where showEffectName: 'draw' and animOptions: {duration: 500, timing: [0.58, 0, 0.42, 1]}
Here is an example shown using a button to show/hide the line
var line = new LeaderLine(startElement, endElement, {hide: true});
showButton.addEventListener('click', function() { line.show(); }, false);
hideButton.addEventListener('click', function() { line.hide(); }, false);
How do I implement the self= code into the button? I'm not even sure what self= is supposed to mean. The below code does not work
var line = new LeaderLine(startElement, endElement, {hide: true});
line.show() = line.show({showEffectName:'draw'}, {animOptions: {duration: 3000, timing: 'linear'}});
startElement.addEventListener('click', function() { line.show(); });
Here is what you are looking for
line.show('draw', {
animOptions: {
duration: 3000,
timing: [0.5, 0, 1, 0.42]
}
})
And now you can call this in any function
button.addEventListener('click', function() {
line.show('draw', {
animOptions: {
duration: 3000,
timing: [0.5, 0, 1, 0.42]
}
})
});
Your code does not work because you have to put only value like below.
var line = new LeaderLine(startElement, endElement, {hide: true});
startElement.addEventListener("click", function () {
line.show("draw", {duration: 3000, timing: 'linear'});
});

Scheduling ToneJS events while transport is playing

I have 4 notes playing in my Tone JS app and would like to change the 3rd note to be something else whilst the transport is currently playing. Here is my code:
JS:
import { Transport, start, Sampler } from "tone";
const notesToPlay = [
{
timing: 0.25,
sameAsLast: false,
duration: 0.1,
velocity: 1
},
{
timing: 0.5,
sameAsLast: true,
duration: 0.1,
velocity: 1
},
{
timing: 0.75,
sameAsLast: false,
duration: 0.1,
velocity: 1
},
{
timing: 1,
sameAsLast: false,
duration: 0.2,
velocity: 1
}
];
var eventIds = [];
(function () {
function playSynth() {
Transport.start();
start();
}
const sampler = new Sampler({
urls: {
A1: "A1.mp3",
A2: "A2.mp3"
},
baseUrl: "https://tonejs.github.io/audio/casio/",
onload: () => {
loadNotes();
}
}).toDestination();
function loadNotes() {
notesToPlay.forEach((n) => {
const eventId = Transport.scheduleRepeat((time) => {
sampler.triggerAttackRelease(
["A1"],
n.duration,
n.timing + time,
n.velocity
);
}, 4);
eventIds.push(eventId);
});
}
document.getElementById("play").addEventListener("click", function () {
playSynth();
});
document.getElementById("stop").addEventListener("click", function () {
Transport.stop();
});
document.getElementById("replace").addEventListener("click", function () {
const arrayIdxToReplace = 2;
Transport.clear(eventIds[arrayIdxToReplace]);
const note = notesToPlay[arrayIdxToReplace];
Transport.scheduleRepeat((time) => {
sampler.triggerAttackRelease(
["D1"],
note.duration,
note.timing + time,
note.velocity
);
}, 4);
});
})();
HTML:
<div id="app">
<button id="play">play me</button>
<button id="stop">stop</button>
<button id="replace">Replace 3rd note</button>
</div>
When I click the replace 3rd note button it removes the old event which is good but when it schedules the new event in it is out of sync with where the old 3rd note would be.
A way to get around this is by stopping the Transport then clicking to replace the 3rd note and then clicking play again however I want to be able to do this while the Transport is still playing. Where have I gone Wrong?
Here is a fiddle to demo the issue:
https://codesandbox.io/s/tonejs-forked-fxhzm?file=/src/index.js:0-1643
This is pretty awkward to fix the way it is structured now. The trouble is that every note you add is on its own loop, which begins whenever you call scheduleRepeat ... you would have to correct for the offset between the original loop and the new one, which seems kind of tricky.
I'd suggest that you have call scheduleRepeat only once, and have the callback read the list of notes you have stored. That way you can just replace or alter one of those notes and the next time around it'll be changed, and you won't have any timing problems. I think that would mean including the pitch in your note schema.

JQuery - JNotify - Click-function issue

I'm using JNotify-plugin to display notifications on my site. I works well, but I need to use a click-function to trigger some events.
Basiclly what happens is:
When I get a new chat-message my JNotify-function triggers and a notification-div shows up. Then when I click that div, I want to trigger my other fuction(the #showNewMsg-click-function). But it won't work. If I use any other div to trigger the #showNewMsg-click-function everything works fine. But not when clicking the JNotify rendered div. So how can a make this work?
Here is my try...
JNotify-fuction:
var newMessage;
$(function () {
newMessage = function () {
jSuccess(
"<div id='showNewMsg'><i class='glyphicon glyphicon-envelope'></i>" + ' New chat msg! Click to read!' + '</div>',
{
autoHide: false,
HideTimeEffect: 500,
LongTrip: 20,
ColorOverlay: '#000',
HorizontalPosition: "center",
VerticalPosition: "bottom",
ShowOverlay: false,
OpacityOverlay: 0.5,
MinWidth: 350
});
}
newMessage();
});
Click-funtion to trigger some other click events:
$("#showNewMsg").click(function () {
$("#chat-toggle").click();
$('a[href="#room1"]').click();
});
JNotify GitHub
Answers my own question, in case somone else is wondering.
Found the answer, by reading the JNotify-documentation a little bit closer.
By adding the onClosed-part, instead of trying to do a separate function with click-events, everything works perfect now.
onClosed fires of when the notification div is closed.
var newMessage;
$(function () {
newMessage = function () {
jSuccess(
"<div id='showNewMsg'><i class='glyphicon glyphicon-envelope'></i>" + ' New chat msg! Click to read!' + '</div>',
{
autoHide: false,
HideTimeEffect: 500,
LongTrip: 20,
ColorOverlay: '#000',
HorizontalPosition: "center",
VerticalPosition: "bottom",
ShowOverlay: false,
OpacityOverlay: 0.5,
MinWidth: 350,
//THIS PART BELOW
onClosed: function () {
$("#chat-toggle").click();
$('a[href="#room1"]').click();
},
});
}
newMessage();
});
Since the notification DIV is being inserted into the DOM dynamically, it never gets bound to that click you set up. Try binding the click in the onCompleted function of jNotify. This function fires after the element is inserted, so you should be able to operate on it.
jSuccess(
"<div id='showNewMsg'><i class='glyphicon glyphicon-envelope'></i>" + ' New chat msg! Click to read!' + '</div>',
{
autoHide: false,
HideTimeEffect: 500,
LongTrip: 20,
ColorOverlay: '#000',
HorizontalPosition: "center",
VerticalPosition: "bottom",
ShowOverlay: false,
OpacityOverlay: 0.5,
MinWidth: 350,
onCompleted : function() {
$("#showNewMsg").click(function () {
alert('You clicked on the notification!');
});
}
}
);
jsFiddle here.

Categories