import { Override, Data, motionValue, useTransform, transform, useAnimation, useCycle,} from "framer";// ts-ignoreimport { cloneElement } from "react";const data = Data({ toggle: true, text: "交互事件", currentIndicator: 0, loading: "false",});// 除了更改文字内容,其他override要作用在frame元素上。/* 关于 Tap 事件 whileTap: 当元素被 手指/鼠标 按下时改变动画的属性 onTapStart: 在被点击的元素上开始轻击手势时进行的回调 onTap: 当轻击手势成功结束时还在此元素上进行回调 onTapCancle: 当轻击手势结束于此元素之外时进行回调 event: MouseEvent | TouchEvent | PointerEvent*/export function TapEvent(): Override { return { whileTap: { scale: 1.2, }, onTapStart(event, info) { console.log( "onTapStart:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onTapStart"); }, onTap(event, info) { console.log( "onTap:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onTap"); }, onTapCancel(event, info) { console.log( "onTapCancle:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onTapCancle"); }, };}/* 关于 Hover 事件 whileHover: 当鼠标悬浮在元素上改变动画的属性 onHoverStart: 当鼠标悬浮在元素上产生回调 onHoverEnd:当鼠标悬浮在元素上然后离开产生回调 event: MouseEvent*/export function HoverEvent(): Override { return { whileHover: { scale: 1.2, }, onHoverStart(event, info) { console.log( "onHoverStart:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ); }, onHoverEnd(event, info) { console.log( "onHoverEnd:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ); }, };}/* 关于 pan 事件 The pan gesture recognises when a pointer presses down on a component and moves further than 3 pixels. The pan gesture is ended when the pointer is released. onPan: the pan gesture is recognised on this element. onPanStart: the pan gesture begins on this element. onPanEnd: the pan gesture ends on this element. event: MouseEvent | TouchEvent | PointerEvent info: PanInfo A PanInfo object containing x and y values for: point: Relative to the device or page. delta: Distance moved since the last event. offset: Offset from the original pan event. velocity: Current velocity of the pointer.*/export function PanEvent(): Override { return { onPanStart(event, info) { console.log( "onPanStart:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onPanStart"); }, onPan(event, info) { console.log( "onPan:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onPan"); }, onPanEnd(event, info) { console.log( "onPanEnd:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onPanEnd"); }, };}/* 关于 Drag 事件 The drag gesture follows the rules of the pan gesture but applies pointer movement to the x and/or y axis of the component. onDrag: fires when the component is dragged. onDragStart: fires when dragging starts. onDragEnd: fires when dragging ends. event: MouseEvent | TouchEvent | PointerEvent info: PanInfo A PanInfo object containing x and y values for: point: Relative to the device or page. delta: Distance moved since the last event. offset: Offset from the original pan event. velocity: Current velocity of the pointer.*/export function DragEvent(): Override { return { drag: true, // boolean | "x" | "y" dragConstraints: { left: 0, right: 0, top: 0, bottom: 0 }, // Applies constraints on the permitted draggable area. "left" | "right" | "top" | "bottom" dragElastic: 0.6, //boolean | number ,The degree of movement allowed outside constraints.0 = no movement, 1 = full movement. Set to 0.5 by default. dragTransition: { bounceStiffness: 600, bounceDamping: 20 }, dragMomentum: true, //true default dragDirectionLock: true, //true or false dragPropagation: false, // false default // onDragStart(event, info) { console.log( "onDragStart:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onDragStart"); }, onDrag(event, info) { console.log( "onDrag:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onDrag"); }, onDragEnd(event, info) { console.log( "onDragEnd:", "pointX", info.point.x, "pointX", info.point.y, event.isTrusted ), (data.text = "onDragEnd"); }, };}/* 关于 Scroll 事件 onScroll: fires when the component is Scrollged. onScrollStart: fires when Scrollging starts. onScrollEnd: fires when Scrollging ends. event: MouseEvent | TouchEvent | PointerEvent info: PanInfo A PanInfo object containing x and y values for: point: Relative to the device or page. delta: Distance moved since the last event. offset: Offset from the original pan event. velocity: Current velocity of the pointer.*/export function ScrollEvent(): Override { const scrollY = motionValue(0); scrollY.onChange((point) => { console.log(point); }); return { contentOffsetY: scrollY, onScrollStart(info) { console.log( "onScrollStart:", "pointX", info.point.x, "pointX", info.point.y ), (data.text = "onScrollStart"); }, onScroll(info) { // console.log("onScroll:","pointX",info.offset.x,"scrollY",info.offset.y), data.text = "onScroll"; }, onScrollEnd(info) { console.log( "onScrollEnd:", "pointX", info.point.x, "pointX", info.point.y ), (data.text = "onScrollEnd"); }, };}export function ScrollRefresh(): Override { const controls = useAnimation(); const scrollY = motionValue(0); const transition = { duration: 0.2, ease: [0.3, 0.0, 0.1, 1.0], }; return { contentOffsetY: scrollY, // Only enable drag when the spinner is not loading dragEnabled: data.loading === "false", // When the layer has been dragged past a certain point, begin the loading animation onPanEnd() { if (data.loading === "false" && scrollY.get() > 116) { // Keep the layer pinned at 116px from the top while loading data.loading = "true"; controls.start({ y: 116 }); // When the animation is complete, animate the layer back to the top and set the loading state to false setTimeout(() => { data.loading = "false"; controls.start({ y: 0, transition: transition }); }, 1500); } else { controls.start({ y: 0 }); } }, scrollAnimate: controls, };}/* 关于Page组件 这个函数只用于Page组件*/export function Page(): Override { return { onChangePage(current, previous) { data.currentIndicator = current; }, };}// 这个用于通过index控制很多元素相同的字组件的属性,一般和Page组件相关export function sameItemGroup(props): Override { return { children: props.children.map((indicator, index) => { let opacity = 0.3; if (index === data.currentIndicator) { opacity = 1; } return cloneElement(indicator, { animate: { opacity: opacity }, }); }), };}export function Page_Effects(): Override { return { gap: 0, effect(info) { const offset = info.normalizedOffset; const opacity = transform(offset, [-1, 0, 1], [0.4, 1, 0.4]); const scale = transform(offset, [-1, 0, 1], [0.5, 1, 0.5]); const x = transform(offset, [-1, 0, 1], [20, 0, -20]); return { opacity, scale, x }; }, };}// 属性大全export function VisualStyle(): Override { return { visible: true, text: "", originX: 0.5, originY: 1, originZ: 0.1, animate: { // basic width: 100, height: 100, opacity: 0.8, background: "#09D", // "#09F" | border: "1px solid #000", radius: 20, shadow: "10px 5px 5px rgba(0,0,0,0.1)", // transform x: 1, y: 1, z: 1, rotate: 20, rotateX: 10, rotateY: 10, rotateZ: 10, scale: 1.2, scaleX: 1.3, scaleY: 1.3, skew: 15, skewX: 13, skewY: 14, perspective: 500, }, onUpdate(latest) { console.log(latest.width, latest.height); //这里可以调用animate中变化的元素的实时的值 }, onAnimationStart() { console.log("animation start"); }, onAnimationComplete() { console.log("Animation completed"); }, };}// animation controls 这种用于一次性改变多个属性 或者是序列动画/* Supported Value Types Numbers Strings All Unit Types (px, %, calc(), etc.) Colors (hex, rgba, hsla) Complex Values (Strings with numbers and colors) x, y, z rotate, rotateX, rotateY, rotateZ scale, scaleX, scaleY, scaleZ skewX, skewY originX, originY perspective*/export function Animation_controls(): Override { const controls = useAnimation(); async function sequence() { await controls.start({ x: 60, backgroundColor: "#f00", transition: { duration: 3 }, }); await controls.start({ x: -20, backgroundColor: "rgb(217, 15, 224)", transition: { duration: 2 }, }); } return { animate: controls, onTap() { sequence(); }, };}// useCycle 循环多种状态export function UseCycle(): Override { const variants = { green: { background: "#1ea463" }, yellow: { background: "#fecd45" }, red: { background: "#de5347" }, }; const [current, cycle] = useCycle("green", "yellow", "red"); return { variants: variants, animate: current, onTap() { cycle(); }, };}export function Text(): Override { return { textContent: data.text, };}