canvas实现简单时钟

2d时钟的实现

<!-- html中新增一个canvas,给定宽高 -->
<canvas id="timer" width="800" height="800"></canvas>
复制代码
//canvas必须的两步,获取到html上的canvas元素,获取一只画笔
let draw = document.getElementById('timer');
let mypen = draw.getContext('2d');
复制代码
//对于一些基础参数的定义
let {
    sin,
    cos,
    PI
} = Math;
const [CENTERX, CENTERY] = [300, 300], // 圆心中心点
SECONDL = 135, // 秒针长度
    MINUTESL = 110, // 分针长度
    HOURL = 80, // 时针长度
    PERIOD = 60, // 时间周期
    OUTCIRCLE = 150, // 外圈长度
    INCIRCLE = 145, // 内圈长度
    WIDTH = 800, // canvas的宽
    HEIGHT = 800; // canvas的高
复制代码
//主要执行的函数
if (draw.getContext) {
    // this.getTime 和 this.getTime()有什么区别
    // 初始化的时候运行一次
    this.getTimer(); //放在循环外面避免重新绘制,但是清理画布这个动作会把这个文字也清理掉
    this.getTimeNum();//获取时间点对应数字
    setInterval(this.getTimer, 1000);
}
复制代码
/**
 * 得到内外两个圈
 */
function getCirles() {
    mypen.arc(CENTERX, CENTERY, OUTCIRCLE, 0, 2 * PI, false);
    //可以尝试一下不移动坐标点
    mypen.moveTo(INCIRCLE + CENTERX, CENTERY);
    mypen.arc(CENTERX, CENTERY, INCIRCLE, 0, 2 * PI, false);
    mypen.moveTo(CENTERX, CENTERY);
}
/**
 * 渲染出时钟
 */
function getTimer() {
    let [hour, minutes, second] = this.getNow();
    mypen.beginPath();
    this.getCirles();
    this.getPiont(hour, minutes, second, HOURL);
    this.getPiont(hour, minutes, second, MINUTESL);
    this.getPiont(hour, minutes, second, SECONDL);
    // 旋转是改变不了旋转方向的
    // 这条路是行不通的
    // mypen.translate(CENTERX, CENTERY)
    // mypen.rotate(180)
    // 清除画布
    mypen.clearRect(0, 0, WIDTH, HEIGHT);
    // 获取时间表上的数字
    // 问题就是每次都得重新渲染
    this.getTimeNum();
    mypen.stroke();
}
/**
 * 获得指针
 * @param {number} pointH 时间点小时
 * @param {number} pointM 时间点分钟
 * @param {number} pointS 时间点秒
 * @param {number} POINTL 各种指针长度
 */
function getPiont(pointH, pointM, pointS, POINTL) {
    let secondX, secondY, MinutesX, MinutesY, HourX, HourY, normalH; // 用来保存基本弧度
    normalH = (2 * PI) / PERIOD; // 基本弧度
    if (POINTL === HOURL) {
        // 为什么时针还有问题
        // 因为分针和秒针都是60秒,60分钟
        // 时针只有12小时
        HourX = POINTL * sin(-5 * normalH * (pointH + pointM / PERIOD) + PI);
        HourY = POINTL * cos(-5 * normalH * (pointH + pointM / PERIOD) + PI);
        lineX = HourX;
        lineY = HourY;
    } else if (POINTL === MINUTESL) {
        // 分针对了
        // 分针选择直接弹过去那种
        MinutesX = POINTL * sin(-normalH * pointM + PI);
        MinutesY = POINTL * cos(-normalH * pointM + PI);
        lineX = MinutesX;
        lineY = MinutesY;
    } else {
        // 秒针对了
        secondX = POINTL * sin(-normalH * pointS + PI);
        secondY = POINTL * cos(-normalH * pointS + PI);
        lineX = secondX;
        lineY = secondY;
    }
    mypen.lineTo(CENTERX + lineX, CENTERY + lineY);
    mypen.moveTo(CENTERX, CENTERY);
}
/**
 * 获取当前时间
 */
function getNow() {
    let time = new Date(),
        hour = time.getHours(),
        minutes = time.getMinutes(),
        second = time.getSeconds();
    return [hour, minutes, second];
}
function getTimeNum() {
    // let count = 0;
    // 简单的字体三件套
    mypen.font = 'bold 14px Arial';
    mypen.textAlign = 'center';
    mypen.textBaseline = 'middle';
    //这个循环只要执行一次
    // mypen.fillText('12', 200, 200);
    //断点先是画出来了,然后就消失了
    for (let i = 0; i < 12; i++) {
        // count++
        let tempX = CENTERX + INCIRCLE * sin(-i * PI / 6 + PI),
            tempY = CENTERY + INCIRCLE * cos(-i * PI / 6 + PI);
        if (i === 0) {
            // 假如等于0的时候换成12
            mypen.fillText('12', tempX, tempY);
        } else {
            mypen.fillText(i, tempX, tempY);
        }

    }
}
复制代码

加上3d纹理

<!-- 引入three.js -->
<script src="../three.js"></script>
复制代码
// 创建一系列three.js套装,摄像头,场景,渲染器,物体,和纹理
let camera, scene, renderer, mesh, texture;
复制代码
/**
 * 初始化
 */
function init() {
    renderer = new THREE.WebGLRenderer();//渲染器
    renderer.setSize(window.innerWidth, window.innerHeight);//设置宽高
    document.body.appendChild(renderer.domElement);//在body这个节点上加上子节点
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);//透视摄像机参考文章
    //http://www.hewebgl.com/article/getarticle/59
    camera.position.z = 400;
    scene = new THREE.Scene();
    // 画几何体
    let geometry = new THREE.CubeGeometry(300, 300, 300);
    let canvas = document.getElementById('timer');
    // 添加几何纹理
    texture = new THREE.Texture(canvas);
    let material = new THREE.MeshBasicMaterial({
        map: texture
    });
    texture.needsUpdate = true;
    mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);
    // window.addEventListener('resize', onWindowResize, false);
}
复制代码
代码地址

github.com/kelecola/si…

ps. 前端萌新发帖,初次尝试canvas和webgl,有问题,或者改进建议还望指出,部分参考webgl中文网。www.hewebgl.com/article/get… 代码注释较少不喜勿喷。

转载于:https://juejin.im/post/5bbb7961f265da0afd4b549e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值