• javascript图形动画设计--以简单正弦波轨迹移动


    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Wave 1</title>
        <link rel="stylesheet" href="../include/style.css">
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
        
        <script src="../include/utils.js"></script>
        <script src="./classes/ball.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              ball = new Ball(),
              angle = 0,
              centerY = 200,
              range = 50,
              xspeed = 1,
              yspeed = 0.05;
            
          ball.x = 0;
            
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            ball.x += xspeed;
            ball.y = centerY / 2 + Math.sin(angle) * range;
            angle += yspeed;
            ball.draw(context);
          }());
        };
        </script>
      </body>
    </html>
    View Code

    其中util.js

    /**
     * Normalize the browser animation API across implementations. This requests
     * the browser to schedule a repaint of the window for the next animation frame.
     * Checks for cross-browser support, and, failing to find it, falls back to setTimeout.
     * @param {function}    callback  Function to call when it's time to update your animation for the next repaint.
     * @param {HTMLElement} element   Optional parameter specifying the element that visually bounds the entire animation.
     * @return {number} Animation frame request.
     */
    if (!window.requestAnimationFrame) {
      window.requestAnimationFrame = (window.webkitRequestAnimationFrame ||
                                      window.mozRequestAnimationFrame ||
                                      window.msRequestAnimationFrame ||
                                      window.oRequestAnimationFrame ||
                                      function (callback) {
                                        return window.setTimeout(callback, 17 /*~ 1000/60*/);
                                      });
    }
    
    /**
     * Cancels an animation frame request.
     * Checks for cross-browser support, falls back to clearTimeout.
     * @param {number}  Animation frame request.
     */
    if (!window.cancelRequestAnimationFrame) {
      window.cancelRequestAnimationFrame = (window.cancelAnimationFrame ||
                                            window.webkitCancelRequestAnimationFrame ||
                                            window.mozCancelRequestAnimationFrame ||
                                            window.msCancelRequestAnimationFrame ||
                                            window.oCancelRequestAnimationFrame ||
                                            window.clearTimeout);
    }
    
    
    /* Object that contains our utility functions.
     * Attached to the window object which acts as the global namespace.
     */
    window.utils = {};
    
    /**
     * Keeps track of the current mouse position, relative to an element.
     * @param {HTMLElement} element
     * @return {object} Contains properties: x, y, event
     */
    window.utils.captureMouse = function (element) {
      var mouse = {x: 0, y: 0, event: null},
          body_scrollLeft = document.body.scrollLeft,
          element_scrollLeft = document.documentElement.scrollLeft,
          body_scrollTop = document.body.scrollTop,
          element_scrollTop = document.documentElement.scrollTop,
          offsetLeft = element.offsetLeft,
          offsetTop = element.offsetTop;
      
      element.addEventListener('mousemove', function (event) {
        var x, y;
        
        if (event.pageX || event.pageY) {
          x = event.pageX;
          y = event.pageY;
        } else {
          x = event.clientX + body_scrollLeft + element_scrollLeft;
          y = event.clientY + body_scrollTop + element_scrollTop;
        }
        x -= offsetLeft;
        y -= offsetTop;
        
        mouse.x = x;
        mouse.y = y;
        mouse.event = event;
      }, false);
      
      return mouse;
    };
    
    /**
     * Keeps track of the current (first) touch position, relative to an element.
     * @param {HTMLElement} element
     * @return {object} Contains properties: x, y, isPressed, event
     */
    window.utils.captureTouch = function (element) {
      var touch = {x: null, y: null, isPressed: false, event: null},
          body_scrollLeft = document.body.scrollLeft,
          element_scrollLeft = document.documentElement.scrollLeft,
          body_scrollTop = document.body.scrollTop,
          element_scrollTop = document.documentElement.scrollTop,
          offsetLeft = element.offsetLeft,
          offsetTop = element.offsetTop;
    
      element.addEventListener('touchstart', function (event) {
        touch.isPressed = true;
        touch.event = event;
      }, false);
    
      element.addEventListener('touchend', function (event) {
        touch.isPressed = false;
        touch.x = null;
        touch.y = null;
        touch.event = event;
      }, false);
      
      element.addEventListener('touchmove', function (event) {
        var x, y,
            touch_event = event.touches[0]; //first touch
        
        if (touch_event.pageX || touch_event.pageY) {
          x = touch_event.pageX;
          y = touch_event.pageY;
        } else {
          x = touch_event.clientX + body_scrollLeft + element_scrollLeft;
          y = touch_event.clientY + body_scrollTop + element_scrollTop;
        }
        x -= offsetLeft;
        y -= offsetTop;
        
        touch.x = x;
        touch.y = y;
        touch.event = event;
      }, false);
      
      return touch;
    };
    
    /**
     * Returns a color in the format: '#RRGGBB', or as a hex number if specified.
     * @param {number|string} color
     * @param {boolean=}      toNumber=false  Return color as a hex number.
     * @return {string|number}
     */
    window.utils.parseColor = function (color, toNumber) {
      if (toNumber === true) {
        if (typeof color === 'number') {
          return (color | 0); //chop off decimal
        }
        if (typeof color === 'string' && color[0] === '#') {
          color = color.slice(1);
        }
        return window.parseInt(color, 16);
      } else {
        if (typeof color === 'number') {
          color = '#' + ('00000' + (color | 0).toString(16)).substr(-6); //pad
        }
        return color;
      }
    };
    
    /**
     * Converts a color to the RGB string format: 'rgb(r,g,b)' or 'rgba(r,g,b,a)'
     * @param {number|string} color
     * @param {number}        alpha
     * @return {string}
     */
    window.utils.colorToRGB = function (color, alpha) {
      //number in octal format or string prefixed with #
      if (typeof color === 'string' && color[0] === '#') {
        color = window.parseInt(color.slice(1), 16);
      }
      alpha = (alpha === undefined) ? 1 : alpha;
      //parse hex values
      var r = color >> 16 & 0xff,
          g = color >> 8 & 0xff,
          b = color & 0xff,
          a = (alpha < 0) ? 0 : ((alpha > 1) ? 1 : alpha);
      //only use 'rgba' if needed
      if (a === 1) {
        return "rgb("+ r +","+ g +","+ b +")";
      } else {
        return "rgba("+ r +","+ g +","+ b +","+ a +")";
      }
    };
    
    /**
     * Determine if a rectangle contains the coordinates (x,y) within it's boundaries.
     * @param {object}  rect  Object with properties: x, y, width, height.
     * @param {number}  x     Coordinate position x.
     * @param {number}  y     Coordinate position y.
     * @return {boolean}
     */
    window.utils.containsPoint = function (rect, x, y) {
      return !(x < rect.x ||
               x > rect.x + rect.width ||
               y < rect.y ||
               y > rect.y + rect.height);
    };
    
    /**
     * Determine if two rectangles overlap.
     * @param {object}  rectA Object with properties: x, y, width, height.
     * @param {object}  rectB Object with properties: x, y, width, height.
     * @return {boolean}
     */
    window.utils.intersects = function (rectA, rectB) {
      return !(rectA.x + rectA.width < rectB.x ||
               rectB.x + rectB.width < rectA.x ||
               rectA.y + rectA.height < rectB.y ||
               rectB.y + rectB.height < rectA.y);
    };
    View Code

    其中ball.js

    function Ball (radius, color) {
      if (radius === undefined) { radius = 40; }
      if (color === undefined) { color = "#ff0000"; }
      this.x = 0;
      this.y = 0;
      this.radius = radius;
      this.rotation = 0;
      this.scaleX = 1;
      this.scaleY = 1;
      this.color = utils.parseColor(color);
      this.lineWidth = 1;
    }
    
    Ball.prototype.draw = function (context) {
      context.save();
      context.translate(this.x, this.y);
      context.rotate(this.rotation);
      context.scale(this.scaleX, this.scaleY);
      
      context.lineWidth = this.lineWidth;
      context.fillStyle = this.color;
      context.beginPath();
      //x, y, radius, start_angle, end_angle, anti-clockwise
      context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
      context.closePath();
      context.fill();
      if (this.lineWidth > 0) {
        context.stroke();
      }
      context.restore();
    };
    View Code
    ruby前端观察
  • 相关阅读:
    关于python3导出excel图片链接转图片且图片内嵌表格内实现
    ios下载指定版本frida
    frida打印类下方法模板
    IDEA 报错 Package 'java.util' is declared in module 'java.base', which is not in the module graph
    linux统计当前路径下的文件数量
    Mac 中配置鼠标右键 Open Tabby here
    取消vim粘贴时自动注释功能
    mac 安装字体
    scp 命令提示 Permission denied, please try again.解决方法
    VScode 中如何取消设置文件内容可以滚动到最后一行之后
  • 原文地址:https://www.cnblogs.com/rubyxie/p/4606327.html
Copyright © 2020-2023  润新知