代码之家  ›  专栏  ›  技术社区  ›  Martyna

画布上的李萨如曲线

  •  1
  • Martyna  · 技术社区  · 7 年前

    伙计们,我需要用js编写代码,在画布上用李萨如曲线移动图像。 在小小的帮助下,我成功地编写了一个代码,在这些曲线中移动了一个小点,但真的不知道如何用图像(任何图像)替换它。 这是我的代码:

    function start() {
      var ctx, WIDTH, HEIGHT, x, y, dx, dy, angle, timeout;
    
      function init(data) {
        var canvas = document.getElementById("canvas");
        ctx = canvas.getContext("2d");
        WIDTH = 500;
        HEIGHT = 300;
        x = WIDTH / 2;
        y = HEIGHT / 2;
        dx = x * Math.sin(0);
        dy = x * Math.sin(0);
        angle = 0;
        draw((m1 = 1), (m2 = 2), (speed = 0.009));
      }
    
      function line(x, y, dx, dy, r) {
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(dx, dy);
        ctx.lineWidth = 5; // adding here to make it more visible
        ctx.stroke();
      }
      function clear() {
        ctx.clearRect(0, 0, WIDTH, HEIGHT);
      }
    
      function draw() {
        timeout = setTimeout(draw, 1);
        clear();
        nx = (x - 5) * Math.sin(angle * m1);
        ny = (y - 5) * Math.sin(angle * m2);
        line(x + dx, y + dy, x + nx, y + ny);
        dx = nx;
        dy = ny;
        angle += speed;
      }
      init();
    }
    start();
    <canvas id="canvas" width="500" height="300"></canvas>

    真的很感谢你的帮助,因为我现在陷入困境。我对这个完全不了解 学校需要这个。谢谢

    2 回复  |  直到 7 年前
        1
  •  0
  •   Minh Ngo    7 年前

    看看 CanvasRenderingContext2D.drawImage() .

    我在这里添加了一个代码示例,对代码的某些部分进行了注释,以便您可以查看编辑:)

    function start() {
      var ctx, WIDTH, HEIGHT, x, y, dx, dy, angle, phaseAngle, timeout;
      var image = document.getElementById("img");
    
      function init(data) {
        var canvas = document.getElementById("canvas");
        ctx = canvas.getContext("2d");
        //WIDTH = 500;
        //HEIGHT = 300;
        WIDTH = canvas.width;
        HEIGHT = canvas.height;
        PI = 3.14159265;
        x = WIDTH / 2;
        y = HEIGHT / 2;
        angle = 0;
        phaseAngle = PI/2;
        //dx = x * Math.sin(0);
        //dy = x * Math.sin(0);
        dx = (x - 50) * Math.sin(angle);
        dy = (y - 50) * Math.sin(angle+phaseAngle);
        //angle = 0;
        draw((m1 = 1), (m2 = 2), (speed = 0.009));
      }
    
      function line(x, y, dx, dy, r) {
        ctx.drawImage(image, x, y);
        // ctx.beginPath();
        // ctx.moveTo(x, y);
        // ctx.lineTo(dx, dy);
        // ctx.lineWidth = 5; // adding here to make it more visible
        // ctx.stroke();
      }
      function clear() {
        ctx.clearRect(0, 0, WIDTH, HEIGHT);
      }
    
      function draw() {
        timeout = setTimeout(draw, 1);
        clear();
        //nx = (x - 5) * Math.sin(angle * m1);
        //ny = (y - 5) * Math.sin(angle * m2);
        nx = (x - 50) * Math.sin(angle * m1);
        ny = (y - 50) * Math.sin(angle * m2 + phaseAngle);
        line(x + dx, y + dy, x + nx, y + ny);
        dx = nx;
        dy = ny;
        angle += speed;
      }
      init();
    }
    start();
    <canvas id="canvas" width="500" height="300"></canvas>
    <img id="img" src="https://i.stack.imgur.com/cRMrk.png" hidden> <!-- hide image, we need it only inside canvas -->

    编辑 :更改了曲线的公式。添加的相位角使曲线以90度角运行(270度角将生成相同的曲线)。

    李萨如图形,也称为鲍迪奇曲线,是两条正弦曲线相交形成的图形,其轴线相互成直角。 参考: https://www.britannica.com/science/Lissajous-figure

        2
  •  0
  •   Aaron Krajeski    7 年前

    你能用吗 THREE.js ? 这种东西太棒了。我认为从长远来看,你会发现它的可扩展性更强。

    Here's a fiddle 我为你所说的做好了准备。JSFIDLE不允许跨源请求,所以我无法为您实际加载图像,只需将“path/to/image”替换为图像url所在的位置即可。

    function start() {
      var renderer, scene, camera, mesh;
      var width = window.innerWidth;
      var height = window.innerHeight;
      var m1 = 1;
      var m2 = 2;
      var speed = 0.009;
      var angle = 0;
      var x = width/2;
      var y = height/2;
    
      function init(data) {
        var canvas = document.getElementById("canvas");
        renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
        renderer.setSize( window.innerWidth, window.innerHeight );
        scene = new THREE.Scene();
        camera = new THREE.OrthographicCamera(width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
        camera.position.set(x, y, 50);
    
        var g = new THREE.PlaneBufferGeometry(30, 30);
        var mat = new THREE.MeshBasicMaterial({color: "pink"});
        mesh = new THREE.Mesh(g, mat)
        mesh.position.set(x, y, 0);
        scene.add(mesh);
    
        var loader = new THREE.TextureLoader();
        loader.load("path/to/image", function(img) {
          mat.map = img;
          mat.needsUpdate = true;
        });
      }
    
      function update() {
        var nx = (x - 5) * Math.sin(angle * m1);
        var ny = (y - 5) * Math.sin(angle * m2);
    
        mesh.position.set(x + nx, y + ny, 0);
        angle += speed;
    
        renderer.render(scene, camera);
        requestAnimationFrame(update);
      }
    
      init();
      update();
    }
    start();