简体   繁体   中英

What's wrong with my rewrite from jquery to react

I try to rewrite this liquid button https://codepen.io/waaark/pen/VbgwEM , it use jquery.

I want to rewrite it for my react component, but don't know what is wrong:

here is the component code:

 import React from "react"; import Link from "next/link"; import { useRef } from 'react'; import { useEffect } from 'react'; import { useState } from 'react'; const getPixelRatio = context => { var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return (window.devicePixelRatio || 1) / backingStore; }; const useMove = () => { let ref = useRef(); /* let msx = 0; let msy = 0; let mlx = 0; let mly = 0; */ /* function mouseSpeed() { msx = state.x - state.mouseLastXX; msy = state.y - state.mouseLastYY; mlx = state.x; mly = state.y; setTimeout(mouseSpeed, 50); } */ const [state, setState] = useState({x: 0, y: 0, mouseDirectionXX:0, mouseDirectionYY:0, mouseSpeedXX:0, mouseSpeedYY:0, mouseLastXX:0, mouseLastYY:0}) const handleMouseMove = e => { //e.persist() let xx = state.mouseDirectionX; let yy = state.mouseDirectionY; //mouseSpeed(); if (state.x < e.clientX) xx = 1; else if (state.x > e.clientX) xx = -1; else xx = 0; if (state.y < e.clientY) yy = 1; else if (state.y > e.clientY) yy = -1; else yy = 0; //rx = (state.x - offset.left); //ry = (state.y - offset.top); setState(state => ({...state, x: e.clientX, y: e.clientY, mouseDirectionXX:xx, mouseDirectionYY:yy})) //mouseX = e.clientX; //mouseY = e.clientY; //relMouseX = (mouseX - canvas.offsetLeft); //relMouseY = (mouseY - canvas.offsetTop); //console.log(xx + "///" + yy); } useEffect(() => { window.addEventListener("mousemove", handleMouseMove); return () => window.removeEventListener("mousemove", handleMouseMove); }, []); return { mouseX: state.x, mouseY: state.y, mouseDirectionX: state.mouseDirectionXX, mouseDirectionY: state.mouseDirectionYY, mouseLastX: state.mouseLastXX, mouseLastY: state.mouseLastYY, mouseSpeedX: state.mouseSpeedXX, mouseSpeedY: state.mouseSpeedYY, //relMouseX: state.relMouseXX, //relMouseY: state.relMouseYY, handleMouseMove, } } const LiquidButton = () => { const {mouseX, mouseY, mouseDirectionX, mouseDirectionY, handleMouseMove} = useMove(); let ref = useRef(); let buttonWidth = 240; let buttonHeight = 60; let points = 8; let pointsA = [], pointsB = []; let viscosity = 10, mouseDist = 70, damping = 0.05, showIndicators = false; let relMouseX = 0; let relMouseY = 0; //let canvas = ref.current; /* function mouseSpeed() { mouseSpeedX = mouseX - mouseLastX; mouseSpeedY = mouseY - mouseLastY; mouseLastX = mouseX; mouseLastY = mouseY; setTimeout(mouseSpeed, 50); //console.log("AYE"); } mouseSpeed(); */ useEffect(() => { let canvas = ref.current; let context = canvas.getContext('2d'); let canvaspos = canvas.getBoundingClientRect(); let offset = { top: canvaspos.top, left: canvaspos.left, }; let mouseLastX = 0; let mouseLastY = 0; //mouseDirectionX = 0, //mouseDirectionY = 0, let mouseSpeedX = 0; let mouseSpeedY = 0; relMouseX = (mouseX - offset.left); relMouseY = (mouseY - offset.top); mouseSpeedX = mouseX - mouseLastX; mouseSpeedY = mouseY - mouseLastY; mouseLastX = mouseX; mouseLastY = mouseY; //NEW console.log("mouseX:" + mouseX) console.log("mouseLastX: "+ mouseLastX); console.log("mouseSpeedX: "+ mouseSpeedX); console.log("relMouseX:" + relMouseX) console.log("mouseDirectionX: "+ mouseDirectionX); console.log("mouseY:" + mouseY) console.log("mouseLastY: "+ mouseLastY); console.log("mouseSpeedY: "+ mouseSpeedY); console.log("relMouseY:" + relMouseY) console.log("mouseDirectionY: "+ mouseDirectionY); function Point(x, y, level) { this.x = this.ix = 75+x; this.y = this.iy = 75+y; this.vx = 0; this.vy = 0; this.cx1 = 0; this.cy1 = 0; this.cx2 = 0; this.cy2 = 0; this.level = level; } Point.prototype.move = function() { this.vx += (this.ix - this.x) / (viscosity*this.level); this.vy += (this.iy - this.y) / (viscosity*this.level); var dx = this.ix - relMouseX, dy = this.iy - relMouseY; var relDist = (1-Math.sqrt((dx * dx) + (dy * dy))/mouseDist); // Move x if ((mouseDirectionX > 0 && relMouseX > this.x) || (mouseDirectionX < 0 && relMouseX < this.x)) { if (relDist > 0 && relDist < 1) { this.vx = (mouseSpeedX / 4) * relDist; } } this.vx *= (1 - damping); this.x += this.vx; // Move y if ((mouseDirectionY > 0 && relMouseY > this.y) || (mouseDirectionY < 0 && relMouseY < this.y)) { if (relDist > 0 && relDist < 1) { this.vy = (mouseSpeedY / 4) * relDist; } } this.vy *= (1 - damping); this.y += this.vy; }; function addPoints(x, y) { pointsA.push(new Point(x, y, 1)); pointsB.push(new Point(x, y, 2)); } //NEW-END let ratio = getPixelRatio(context); let width = getComputedStyle(canvas) .getPropertyValue('width') .slice(0, -2); let height = getComputedStyle(canvas) .getPropertyValue('height') .slice(0, -2); canvas.width = buttonWidth+150; canvas.height = buttonHeight+150; //canvas.width = width * ratio; //canvas.height = height * ratio; canvas.style.width = width+`px`; canvas.style.height = height+`px`; let x = buttonHeight/2; for(var j = 1; j < points; j++) { addPoints((x+((buttonWidth-buttonHeight)/points)*j), 0); } addPoints(buttonWidth-buttonHeight/5, 0); addPoints(buttonWidth+buttonHeight/10, buttonHeight/2); addPoints(buttonWidth-buttonHeight/5, buttonHeight); for(var j = points-1; j > 0; j--) { addPoints((x+((buttonWidth-buttonHeight)/points)*j), buttonHeight); } addPoints(buttonHeight/5, buttonHeight); addPoints(-buttonHeight/10, buttonHeight/2); addPoints(buttonHeight/5, 0); let requestId, i = 0; const render = () => { // Clear scene context.clearRect(0, 0, canvas.width, canvas.height); context.fillStyle = "rgba(0, 0, 200, 0.0)"; context.fillRect(0, 0, canvas.width, canvas.height); // Move points for (var i = 0; i <= pointsA.length - 1; i++) { pointsA[i].move(); pointsB[i].move(); } // Create dynamic gradient var gradientX = Math.min(Math.max(mouseX - offset.left, 0), canvas.width); var gradientY = Math.min(Math.max(mouseY - offset.top, 0), canvas.height); var distance = Math.sqrt(Math.pow(gradientX - canvas.width/2, 2) + Math.pow(gradientY - canvas.height/2, 2)) / Math.sqrt(Math.pow(canvas.width/2, 2) + Math.pow(canvas.height/2, 2)); var gradient = context.createRadialGradient(gradientX, gradientY, 300+(300*distance), gradientX, gradientY, 0); gradient.addColorStop(0, '#102ce5'); gradient.addColorStop(1, '#E406D6'); // Draw shapes var groups = [pointsA, pointsB] for (var j = 0; j <= 1; j++) { var points = groups[j]; if (j == 0) { // Background style context.fillStyle = '#1CE2D8'; } else { // Foreground style context.fillStyle = gradient; } context.beginPath(); context.moveTo(points[0].x, points[0].y); for (var i = 0; i < points.length; i++) { var p = points[i]; var nextP = points[i + 1]; var val = 30*0.552284749831; if (nextP != undefined) { // if (nextP.ix > p.ix && nextP.iy < p.iy) { // p.cx1 = px; // p.cy1 = py-val; // p.cx2 = nextP.x-val; // p.cy2 = nextP.y; // } else if (nextP.ix > p.ix && nextP.iy > p.iy) { // p.cx1 = p.x+val; // p.cy1 = py; // p.cx2 = nextP.x; // p.cy2 = nextP.y-val; // } else if (nextP.ix < p.ix && nextP.iy > p.iy) { // p.cx1 = px; // p.cy1 = p.y+val; // p.cx2 = nextP.x+val; // p.cy2 = nextP.y; // } else if (nextP.ix < p.ix && nextP.iy < p.iy) { // p.cx1 = px-val; // p.cy1 = py; // p.cx2 = nextP.x; // p.cy2 = nextP.y+val; // } else { p.cx1 = (p.x+nextP.x)/2; p.cy1 = (p.y+nextP.y)/2; p.cx2 = (p.x+nextP.x)/2; p.cy2 = (p.y+nextP.y)/2; context.bezierCurveTo(px, py, p.cx1, p.cy1, p.cx1, p.cy1); // continue; // } // context.bezierCurveTo(p.cx1, p.cy1, p.cx2, p.cy2, nextP.x, nextP.y); } else { nextP = points[0]; p.cx1 = (p.x+nextP.x)/2; p.cy1 = (p.y+nextP.y)/2; context.bezierCurveTo(px, py, p.cx1, p.cy1, p.cx1, p.cy1); } } // context.closePath(); context.fill(); } if (showIndicators) { // Draw points context.fillStyle = '#000'; context.beginPath(); for (var i = 0; i < pointsA.length; i++) { var p = pointsA[i]; context.rect(px - 1, py - 1, 2, 2); } context.fill(); // Draw controls context.fillStyle = '#f00'; context.beginPath(); for (var i = 0; i < pointsA.length; i++) { var p = pointsA[i]; context.rect(p.cx1 - 1, p.cy1 - 1, 2, 2); context.rect(p.cx2 - 1, p.cy2 - 1, 2, 2); } context.fill(); } requestId = requestAnimationFrame(render); }; render(); return () => { cancelAnimationFrame(requestId); }; }); return ( <div> <canvas ref={ref} style={{ width: '390px', height: '210px' }} > <a href="#" className="btn-liquid"> <span className="inner">Press Button</span> </a> </canvas> <div className="mouseArea"> Hook <div className="mouseInfo"> The current mouse position is ({mouseX}, {mouseY}) <br /> Mouse Direction is ({mouseDirectionX}, {mouseDirectionY}) <br /> {/* Mouse Last ({mouseLastX}, {mouseLastY}) <br /> */} {/* Mouse Speed ({mouseSpeedX}, {mouseSpeedY}) <br /> */} </div> </div> </div> ); }; export default LiquidButton;

i tried to calculate the mouse speed and mouse direction, but still confuse where to put the code.When I console log the value, the mouse position, mouse speed and mouse last position are the same value

How about this?

 let pointsA = []; let pointsB = []; let $canvas = null; let canvas = null; let context = null; // let vars = null; let points = 8; let viscosity = 20; let mouseDist = 70; let damping = 0.05; let showIndicators = false; let mouseX = 0; let mouseY = 0; let relMouseX = 0; let relMouseY = 0; let mouseLastX = 0; let mouseLastY = 0; let mouseDirectionX = 0; let mouseDirectionY = 0; let mouseSpeedX = 0; let mouseSpeedY = 0; function mouseDirection(e) { if (mouseX < e.pageX) mouseDirectionX = 1; else if (mouseX > e.pageX) mouseDirectionX = -1; else mouseDirectionX = 0; if (mouseY < e.pageY) mouseDirectionY = 1; else if (mouseY > e.pageY) mouseDirectionY = -1; else mouseDirectionY = 0; mouseX = e.pageX; mouseY = e.pageY; relMouseX = (mouseX - $canvas.offset().left); relMouseY = (mouseY - $canvas.offset().top); } function mouseSpeed() { mouseSpeedX = mouseX - mouseLastX; mouseSpeedY = mouseY - mouseLastY; mouseLastX = mouseX; mouseLastY = mouseY; setTimeout(mouseSpeed, 50); } mouseSpeed(); function initButton(button) { // Get button // var button = $('.btn-liquid'); var buttonWidth = button.width(); var buttonHeight = button.height(); // Create canvas $canvas = $('<canvas></canvas>'); button.append($canvas); canvas = $canvas.get(0); canvas.width = buttonWidth + 100; canvas.height = buttonHeight + 100; context = canvas.getContext('2d'); // Add points var x = buttonHeight / 2; for (let j = 1; j < points; j++) { addPoints((x + ((buttonWidth - buttonHeight) / points) * j), 0); } addPoints(buttonWidth - buttonHeight / 5, 0); addPoints(buttonWidth + buttonHeight / 10, buttonHeight / 2); addPoints(buttonWidth - buttonHeight / 5, buttonHeight); for (let j = points - 1; j > 0; j--) { addPoints((x + ((buttonWidth - buttonHeight) / points) * j), buttonHeight); } addPoints(buttonHeight / 5, buttonHeight); addPoints(-buttonHeight / 10, buttonHeight / 2); addPoints(buttonHeight / 5, 0); // addPoints(x, 0); // addPoints(0, buttonHeight/2); // addPoints(0, buttonHeight/2); // addPoints(buttonHeight/4, 0); // Start render renderCanvas(); } function addPoints(x, y) { pointsA.push(new Point(x, y, 1)); pointsB.push(new Point(x, y, 2)); } function Point(x, y, level) { this.x = this.ix = 50 + x; this.y = this.iy = 50 + y; this.vx = 0; this.vy = 0; this.cx1 = 0; this.cy1 = 0; this.cx2 = 0; this.cy2 = 0; this.level = level; } Point.prototype.move = function() { this.vx += (this.ix - this.x) / (viscosity * this.level); this.vy += (this.iy - this.y) / (viscosity * this.level); var dx = this.ix - relMouseX, dy = this.iy - relMouseY; var relDist = (1 - Math.sqrt((dx * dx) + (dy * dy)) / mouseDist); // Move x if ((mouseDirectionX > 0 && relMouseX > this.x) || (mouseDirectionX < 0 && relMouseX < this.x)) { if (relDist > 0 && relDist < 1) { this.vx = (mouseSpeedX / 4) * relDist; } } this.vx *= (1 - damping); this.x += this.vx; // Move y if ((mouseDirectionY > 0 && relMouseY > this.y) || (mouseDirectionY < 0 && relMouseY < this.y)) { if (relDist > 0 && relDist < 1) { this.vy = (mouseSpeedY / 4) * relDist; } } this.vy *= (1 - damping); this.y += this.vy; }; function renderCanvas() { // rAF // rafID = requestAnimationFrame(renderCanvas); // Clear scene context.clearRect(0, 0, $canvas.width(), $canvas.height()); context.fillStyle = '#fff'; context.fillRect(0, 0, $canvas.width(), $canvas.height()); // Move points for (var i = 0; i <= pointsA.length - 1; i++) { pointsA[i].move(); pointsB[i].move(); } // Create dynamic gradient var gradientX = Math.min(Math.max(mouseX - $canvas.offset().left, 0), $canvas.width()); var gradientY = Math.min(Math.max(mouseY - $canvas.offset().top, 0), $canvas.height()); var distance = Math.sqrt(Math.pow(gradientX - $canvas.width() / 2, 2) + Math.pow(gradientY - $canvas.height() / 2, 2)) / Math.sqrt(Math.pow($canvas.width() / 2, 2) + Math.pow($canvas.height() / 2, 2)); var gradient = context.createRadialGradient(gradientX, gradientY, 300 + (300 * distance), gradientX, gradientY, 0); gradient.addColorStop(0, '#102ce5'); gradient.addColorStop(1, '#E406D6'); // Draw shapes var groups = [pointsA, pointsB] for (var j = 0; j <= 1; j++) { var points = groups[j]; if (j === 0) { // Background style context.fillStyle = '#1CE2D8'; } else { // Foreground style context.fillStyle = gradient; } context.beginPath(); context.moveTo(points[0].x, points[0].y); for (let i = 0; i < points.length; i++) { var p = points[i]; var nextP = points[i + 1]; // var val = 30*0.552284749831; if (nextP !== undefined) { // if (nextP.ix > p.ix && nextP.iy < p.iy) { // p.cx1 = px; // p.cy1 = py-val; // p.cx2 = nextP.x-val; // p.cy2 = nextP.y; // } else if (nextP.ix > p.ix && nextP.iy > p.iy) { // p.cx1 = p.x+val; // p.cy1 = py; // p.cx2 = nextP.x; // p.cy2 = nextP.y-val; // } else if (nextP.ix < p.ix && nextP.iy > p.iy) { // p.cx1 = px; // p.cy1 = p.y+val; // p.cx2 = nextP.x+val; // p.cy2 = nextP.y; // } else if (nextP.ix < p.ix && nextP.iy < p.iy) { // p.cx1 = px-val; // p.cy1 = py; // p.cx2 = nextP.x; // p.cy2 = nextP.y+val; // } else { p.cx1 = (px + nextP.x) / 2; p.cy1 = (py + nextP.y) / 2; p.cx2 = (px + nextP.x) / 2; p.cy2 = (py + nextP.y) / 2; context.bezierCurveTo(px, py, p.cx1, p.cy1, p.cx1, p.cy1); // continue; // } // context.bezierCurveTo(p.cx1, p.cy1, p.cx2, p.cy2, nextP.x, nextP.y); } else { nextP = points[0]; p.cx1 = (px + nextP.x) / 2; p.cy1 = (py + nextP.y) / 2; context.bezierCurveTo(px, py, p.cx1, p.cy1, p.cx1, p.cy1); } } // context.closePath(); context.fill(); } if (showIndicators) { // Draw points context.fillStyle = '#000'; context.beginPath(); for (let i = 0; i < pointsA.length; i++) { // var p = pointsA[i]; context.rect(px - 1, py - 1, 2, 2); } context.fill(); // Draw controls context.fillStyle = '#f00'; context.beginPath(); for (let i = 0; i < pointsA.length; i++) { // var p = pointsA[i]; context.rect(p.cx1 - 1, p.cy1 - 1, 2, 2); context.rect(p.cx2 - 1, p.cy2 - 1, 2, 2); } context.fill(); } } const StaticLiquidButton = ({ className, liquidBtnRef, href }) => ( < a href = { href } className = "btn-liquid" ref = { liquidBtnRef } > < span class = "inner" > Liquid button ? < /span> < /a> ); StaticLiquidButton.propTypes = { className: PropTypes.string.isRequired }; const LiquidButton = () => { const liquidBtnRef = React.useRef() React.useEffect(() => { const button = liquidBtnRef.current; initButton($(button)); $(document).on('mousemove', mouseDirection); return () => { $(document).off('mousemove', mouseDirection) } },[]) return ( <StaticLiquidButton className="TeslaAppUI-LiquidButton" href="http://waaark.com" liquidBtnRef={liquidBtnRef} /> ) } function App() { return ( < div > < LiquidButton / > < /div> ); } ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
 body { margin: 0; display: flex; height: 100vh; align-items: center; justify-content: center; } .btn-liquid { display: inline-block; position: relative; width: 240px; height: 60px; border-radius: 27px; color: #fff; font: 700 14px/60px "Droid Sans", sans-serif; letter-spacing: 0.05em; text-align: center; text-decoration: none; text-transform: uppercase; } .btn-liquid .inner { position: relative; z-index: 2; } .btn-liquid canvas { position: absolute; top: -50px; right: -50px; bottom: -50px; left: -50px; z-index: 1; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js" integrity="sha512-ssNhh7jlzc+K93ckIlSXFHHz6fSFv0l619WOv8xbFNRbFOujbasb42LVMOggDrQR1ScJncoWb+KAJx1uF3ipjw==" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

Good Luck...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM