react magnetic snap scroll with react-scroll - animation

ive got a component where i try to make some sort of magnetic snap scroll. i know the css usual css way of snap-y, and setting snap behavior to smooth, but the snap is too fast. so i tried on my own to create a component where if the app detects a scroll down or up with the function, and a scroll below
const [scrollDir, setScrollDir] = useState("");
const [index, setIndex] = useState("0")
useEffect(() => {
const threshold = 0;
let lastScrollY = window.pageYOffset;
let ticking = false;
const updateScrollDir = () => {
const scrollY = window.pageYOffset;
if (Math.abs(scrollY - lastScrollY) < threshold) {
ticking = false;
return;
}
if(scrollY>lastScrollY){
// setScrollDir("scrolling down")
scroller.scrollTo('about',{
duration: 1000,
delay: 100,
smooth: 'linear',
})
}
// setScrollDir(scrollY > lastScrollY ? "scrolling down" : "scrolling up");
lastScrollY = scrollY > 0 ? scrollY : 0;
ticking = false;
};
const onScroll = () => {
if (!ticking) {
window.requestAnimationFrame(updateScrollDir);
ticking = true;
}
};
window.addEventListener("scroll", onScroll);
console.log(scrollDir);
return () => window.removeEventListener("scroll", onScroll);
}, [scrollDir]);
the magnetic scroll doesnt work, the page goes all jumpy. i could add a global css to make smooth scrolling, but that defeats the purpose of giving easein animation of scrolling. is there a way to work around this?

Related

how to enable damping without controls.update

here is my code
when i try to call controls.update() to enable damping all things messed up.i also try control.target but it's not working.if i don't call controls.update() all things work properly.can anyone tell me what should i do
// about direct
points.filter((data) => {
return data.projectDirect === 'aboutDirect'
}).map((projectDirect) => {
projectDirect.element.addEventListener('click', (e) => {
controls.enableRotate = false;
controls.enableZoom = false;
controls.enablePan = false;
e.stopPropagation();
gsap.to(camera.position, {
duration: 1.5,
x: aboutCenter.x + 8,
y: aboutCenter.y,
z: aboutCenter.z,
onUpdate: function () {
camera.lookAt(aboutCenter);
}
});
})
//tick function
const clock = new THREE.Clock()
const tick = () =\> {
const elapsedTime = clock.getElapsedTime()
// controls.update()
// Render
renderer.render(scene, camera)
// Call tick again on the next frame
window.requestAnimationFrame(tick)
}
tick()
Your code does not work since the result of camera.lookAt(aboutCenter); will be overwritten by controls.update(). Write your GSAP code like so:
gsap.to(controls.target, {
duration: 1.5,
x: aboutCenter.x + 8,
y: aboutCenter.y,
z: aboutCenter.z
});
And update the controls in the animation loop.

ChartJs linechart adddata animation

I am trying to make a 'Movie-Chart' with ChartJs v3.9.1 where I add and remove data:
https://codepen.io/ipax77/pen/YzLrNEM
<...>
let chartdata = { x: label, y: stepdata.Winrate };
chart.data.labels.push(label);
chart.data.datasets.forEach(dataset => {
if (dataset.label == stepdata.Commander) {
dataset.data.push(chartdata);
dataadded = true;
}
});
chart.update();
<...>
if (chart.data.labels.length > 6) {
let removelabel = chart.data.labels[0];
chart.data.labels.splice(0, 1);
chart.data.datasets.forEach(dataset => {
const index = dataset.data.findIndex(obj => obj.x == removelabel);
if (index > -1) {
dataset.data.splice(index, 1);
}
});
Somehow the animation for new datapoints starts from the xAxis rather than the previouse datapoint. Is there a way to fix this?
I tried working with timescale axis and chartjs-adapter-date-fns which fixes the problem, but then the animation for lines that don't start with the first label are messed up.
You could disable animation on the y-axis by defining options.animation as follows:
options: {
responsive: true,
animation: {
y: {
duration: 0
}
},

Code working in D3-V3 not working in D3-V4

I have to disable panning from mouse left button in d3-v4, it should pan only using mouse right button. My below code was working in d3-v3 but not in v4
this.zoomListener = d3.zoom().on("start", this.zoomstart.bind(this)).on("zoom", this.zoom.bind(this)).on("end", this.zoomend.bind(this));
const eventProxy = (fn: any) => {
return () => {
// Enable events if enableEvents=== true
if (d3.event.which === 3) {
fn.apply(this, arguments);
}
};
};
this.parentSvg.call(this.zoomListener).on("dblclick.zoom", null);
const mouseDownTarget = this.parentSvg.on("mousedown.zoom");
this.parentSvg.on("mousedown.zoom", eventProxy(mouseDownTarget));
Does anyone know how to do it in V4

Hide actionbar on scroll listview

I have an app that has an action bar and a Tabview. Inside the tabview there is a listview. What I want is the actionbar to hide when the user is scrolling down the list and pop up when the user is scrolling up and do it nicely. As an example youtube app for android is doing this.
I have tried this code https://gist.github.com/vakrilov/6edc783b49df1f5ffda5 but as I hide the bar a white space appears on the bottom of the screen so not really useful in this case.
I tried and fail to modify it and increase the height as I hide the bar using:
var params = userList.android.getLayoutParams();
params.height = 500;
userList.android.setLayoutParams(params);
userList.android.requestLayout();
Also this
var LayoutParams= android.view.ViewGroup.LayoutParams;
var params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Finally I came out with a kind of working thing but it is too sudden no animation on the hiding/appearing
var isChangingBar = false;
var isBarHidden = false;
userList.on("pan", function(args) {
var delta = args.deltaY;
console.log("deltaY: " + delta);
if (!isChangingBar) {
if (delta > 0 && isBarHidden === true) {
isChangingBar = true;
isBarHidden = false;
page.actionBarHidden = false;
isBarHidden = false;
setTimeout(function() {
isChangingBar = false;
}, 250);
}
else if (delta < 0 && isBarHidden === false) {
isChangingBar = true;
page.actionBarHidden = true;
isBarHidden = true;
setTimeout(function() {
isChangingBar = false;
}, 250);
}
}
}
Some idea if there is a better way?
You can add actionbar animation on hide/show:
declare const java: any;
declare const android: any;
export enum LayoutTransitionTypes {
CHANGE_APPEARING = 0,
CHANGE_DISAPPEARING,
APPEARING,
DISAPPEARING,
CHANGING
}
export function initPageActionBarVisibilityAnimations(page) {
if (!page.actionBar) {
return;
}
const actionBarH = page.actionBar.getMeasuredHeight();
if (actionBarH < 1) {
return;
}
const lt = new android.animation.LayoutTransition();
lt.setAnimator(LayoutTransitionTypes.APPEARING, (function () {
const a = new android.animation.ObjectAnimator();
a.setPropertyName('translationY');
a.setFloatValues([0.0]);
a.setDuration(lt.getDuration(2));
return a;
})());
lt.setAnimator(LayoutTransitionTypes.DISAPPEARING, (function () {
const a = new android.animation.ObjectAnimator();
a.setPropertyName('translationY');
a.setFloatValues([-actionBarH]);
a.setDuration(lt.getDuration(3));
return a;
})());
lt.setStartDelay(LayoutTransitionTypes.CHANGE_APPEARING, 0);
lt.setStartDelay(LayoutTransitionTypes.CHANGE_DISAPPEARING, 0);
lt.setStartDelay(LayoutTransitionTypes.APPEARING, 0);
lt.setStartDelay(LayoutTransitionTypes.DISAPPEARING, 0);
lt.setStartDelay(LayoutTransitionTypes.CHANGING, 0);
page.nativeView.setLayoutTransition(lt);
}
Now we may use page pan event to automatically hide/show action bar on scroll pan up/down events. Every change of page.actionBarHidden will start smooth actionbar hide/show transition.
export function onScrollPan(ev: PanGestureEventData) {
const actionBar = page.actionBar;
const scrollView: ScrollView = <ScrollView>page.getViewById('mainScrollView');
const voffset = scrollView.verticalOffset;
const dh = 50;
if (page.actionBarHidden && ev.deltaY > dh * 5) {
initPageActionBarVisibilityAnimations(page);
page.actionBarHidden = false;
} else if (!page.actionBarHidden
&& ev.deltaY < -dh
&& voffset > 0 && voffset > 2 * actionBar.getMeasuredHeight()) {
initPageActionBarVisibilityAnimations(page);
page.actionBarHidden = true;
}
}

Activate (or not) jQuery plugin depending on screen width

So I got this jQuery plugin to active a sliding menu tab:
$(document).ready(function() {
var closeAll,
$parentItem = $('div#tabWrapper'),
slideAmt = $('div#tabBG').width(),
direction;
$('a#toggle').click(function() {
if (parseInt($parentItem.css('marginLeft'), 10) < 0) {
direction = '+=';
$(this).addClass('expanded');
}
else {
$(this).removeClass('expanded');
direction = '-=';
}
$parentItem.animate({marginLeft: direction + slideAmt}, 400)
return false;
});
$parentItem.mouseleave(function() {
closeAll = setTimeout(function() {
$('a#toggle').removeClass('expanded').parent().animate({marginLeft: -slideAmt}, 300);
return false;
}, 600);
})
.mouseenter(function() {
clearTimeout(closeAll);
}) });
But I only want this animation to work on a higher screen width than 1024px.
How would make this happen?
Thanks all!
You can get the screen resolution using
screen.height;
screen.width;
Then do what you want to do depending on these values

Resources