I am trying to create an animated drag and drop feature, like this: http://moduscreate.com/animated_drag_and_drop_with_react_native/
I want to change it so that when the user starts the touch, the object moves upwards so that it is no longer hidden under their finger. I want this movement to be animated, but I also want to track the panning gesture during the animation.
Right now I have the animation working, as long as the user doesn't move their finger. I am using this code to animate the object up when the touch starts:
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.pan,
{
...animationConstants,
toValue: { x: 0, y: -70 },
}
).start((status) => {
// This part ensures that the offset and value are
// set correctly after the animation.
this.state.pan.y.setOffset(-70);
this.state.pan.y.setValue(0);
});
},
But as soon as they move their finger, it cancels the animation and jumps to the top. I am using this code for onPanResponderMove:
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
I want the animation to continue, even while the user is moving their finger.
How could I change the code so that I am animating the "offset", instead of the "value"? I think I could solve this problem if Animated.spring had the option to use toOffset: {x: ..., y: ...}, as well as to toValue. But I don't think it has that, and I'm not sure how I should emulate this.
I figured something out. I'm not sure about performance, but it seems to work fine.
I set up a separate Animated.Value to animate the offset. I just added a callback using addListener, which calls setOffset to animate the value.
constructor(props){
super(props);
this.state = {
pan: new Animated.ValueXY(),
offset: new Animated.Value(0)
};
this.state.offset.addListener((value) => {
this.state.pan.y.setOffset(value.value);
});
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.offset,
{ toValue: -70 }
).start();
},
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
onPanResponderRelease: (e, gesture) => {
Animated.spring(
this.state.pan,
{
toValue: { x: 0, y: 0 }
}
).start();
Animated.spring(
this.state.offset,
{ toValue: 0 }
).start();
}
});
}
Related
I'm using GSAP with ASScroll to add a couple of animations to my static site generated with Hugo. All animations work as intended. However when I reload the page only when I'm not scrolled all the way up the animations will go to the last frame and stop. The same thing occurs when the toolbar of Chrome mobile goes all the way up after you scroll down far enough. This occurs on very consistent spots, but not everywhere. For example when scrolling 600px down it would always occur, but at 700px it would never occur.
I'm not getting any errors or warning in the console.
using:
#ashthornton/asscroll 2.0.11
gsap 3.11.3
main.js setup
import ASScroll from '#ashthornton/asscroll'
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';
import {
Timeline
} from 'gsap/gsap-core';
gsap.registerPlugin(ScrollTrigger);
const isTouch = ('ontouchstart' in document.documentElement);
const asscroll = new ASScroll({
disableRaf: true,
ease: 0.175,
touchEase: 0.175
});
gsap.ticker.add(asscroll.update);
ScrollTrigger.defaults({
scroller: asscroll.containerElement
});
ScrollTrigger.scrollerProxy(asscroll.containerElement, {
scrollTop(value) {
return arguments.length ? asscroll.currentPos = value : asscroll.currentPos;
},
getBoundingClientRect() {
return {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight
};
}
});
asscroll.on("update", () => ScrollTrigger.refresh());
ScrollTrigger.addEventListener("refresh", asscroll.resize);
window.addEventListener("load", () => {
// ...
Animation:
const imgMicroservice = document.getElementById('img-microservices');
gsap.timeline({
scrollTrigger: {
trigger: imgMicroservice,
start: "top bottom",
onRefresh: () => {},
end: "bottom top",
invalidateOnRefresh: false,
scrub: 1,
},
})
.fromTo(imgMicroservice, {
y: 150,
scale: 0.96,
ease: "none"
}, {
y: 0,
ease: 0,
scale: 1,
rotate: "0deg",
}, 0)
I tried disabling ASScroll, this solved the problem. Though I want to use it or any other smooth scroll js library.
mediapipe's face detection predict every frame but I want to predict every 10 seconds
Can I adjust predict time?
Or Can I use static image?
Or recommend other face detection library please
I tried it like this
To adjust predict time, I use setInterval but mediapipe predict every frame
To use static image, I use image but mediapipe don't operate
I need to face-image because it is tensorflow js model's input
How can I solve this?
please recommend solution or other face detection library in javascript
function CropFace(results) {
document.body.classList.add('loaded');
fpsControl.tick();
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (results.detections.length > 0) {
drawRectangle(
ctx, results.detections[0].boundingBox,
{color: 'white', lineWidth: 1, fillColor: '#00000000'});
// drawLandmarks(ctx, results.detections[0].landmarks, {
// color: 'red',
// radius: 5,
// });
}
ctx.drawImage(results.image, 0, 0, canvas.width, canvas.height);
}
const faceDetection = new FaceDetection(
{locateFile: (file) => {
// console.log(file)
return `https://cdn.jsdelivr.net/npm/#mediapipe/face_detection#0.0/${file}`;
}
}
);
// setInterval(faceDetection.onResults(CropFace), 10000);
faceDetection.onResults(CropFace)
// asnyc function input_image() {
// await faceDetection.send({image: image});
//}
const camera = new Camera(video, {
onFrame: async () => {
await faceDetection.send({image: video});
},
width: 224,
height: 224
}
);
camera.start();
new ControlPanel(controlsElement1, {
selfieMode: true,
minDetectionConfidence: 0.5,
})
.add([
new StaticText({title: 'MediaPipe Face Detection'}),
fpsControl,
new Toggle({title: 'Selfie Mode', field: 'selfieMode'}),
new Slider({
title: 'Min Detection Confidence',
field: 'minDetectionConfidence',
range: [0, 1],
step: 0.01
}),
])
.on(options => {
video.classList.toggle('selfie', options.selfieMode);
faceDetection.setOptions(options);
}
);
{ image } in faceDetection.send can be HTMLVideoElement, HTMLImageElement or HTMLCanvasElement
so in your case, create canvas, draw frame on it and call faceDetection.send manually as you want using your canvas as input.
I can add animations to anime timeline using the timeline.add({parameters}) function. Is it possible to remove all the previously added animations and reset the whole timeline?
Thanks,
You can reset the timeline by calling the restart method:
const tl = anime.timeline({
duration: 400,
easing: 'easeInOutQuad',
})
tl.add({
targets: '.box',
rotate: 360,
translateX: {
value: 400,
delay: 400,
}
})
document.querySelector('button').addEventListener('click', () => {
tl.restart();
});
I'm trying to tween a sprite from one point to another and have it fade away while it's moving. I've tried this:
const tween = game.tweens.add({
targets: [log.sprite],
x: fire.x,
y: fire.y + (fire.height * 0.2),
opacity: 0,
duration: 300,
repeat: 0,
onComplete() {
destroyLog(log);
resolve();
},
});
But this doesn't work. I'm having a lot of trouble finding good API docs for Phaser 3, so I'm not sure where I should be looking for this information.
You probably should use alpha instead of opacity. Below is a working example for Phaser3. The start and end value lambdas are good just for flexibility. I guess you can replace them by values directly. this refers to Phaser.Scene instance.
this.add.tween({
targets: [sprite],
ease: 'Sine.easeInOut',
duration: 1000,
delay: 0,
x: {
getStart: () => startX,
getEnd: () => endX
},
y: {
getStart: () => startY,
getEnd: () => endY
},
alpha: {
getStart: () => startAlpha,
getEnd: () => endAlpha
},
onComplete: () => {
// Handle completion
}
});
You can easily find helpful usage examples for Phaser 3 by cloning the repo locally and searching for some keywords in the code.
I want to be able to set the slider value without getting the update event to fire. I tried with setting a second parameter (fireSetEvent) in the set function, but that doesn't work.
nouiContrast = document.getElementById('nouiContrast');
noUiSlider.create(nouiContrast, {
start: 0,
step: 0.01,
behaviour: 'tap',
connect: [true, false],
range: {
'min': 0,
'max': 1
}
});
nouiContrast.noUiSlider.on('update', function(values, handle) {
applyFilterValue(6, 'contrast', values[handle]);
});
//....
nouiContrast.noUiSlider.set(val, false);
If you want to handle updates only when the user dragging the slider but not when the code set an update, you can listen to the slide event.
From the docs:
This event is useful when you specifically want to listen to a handle being dragged, but want to ignore other updates to the slider value. This event also fires on a change by a 'tap'. In most cases, the update is the better choice.
nouiContrast = document.getElementById('nouiContrast');
noUiSlider.create(nouiContrast, {
start: 0,
step: 0.01,
behaviour: 'tap',
connect: [true, false],
range: {
'min': 0,
'max': 1
}
});
nouiContrast.noUiSlider.on('slide', function(values, handle) {
applyFilterValue(6, 'contrast', values[handle]);
});
//....
nouiContrast.noUiSlider.set(val, false);