• 周日. 11月 27th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

canvas小试牛刀

admin

11月 28, 2021

时钟

 canvas绘制时钟

<canvas id="canvas" width="600" height="600"></canvas>
    <script>
        var canvasId=document.getElementById("canvas");
        var ctx=canvasId.getContext("2d");

        setInterval(()=>{
            ctx.save()
            ctx.clearRect(0, 0, 600, 600)
            ctx.translate(300, 300) // 设置中心点,此时300,300变成了坐标的0,0
            ctx.save()
            //大
            ctx.beginPath();
            ctx.arc(0,0,100,0,2 * Math.PI);
            ctx.stroke();
            ctx.closePath();
            //小
            ctx.beginPath();
            ctx.arc(0,0,5,0,2 * Math.PI);
            ctx.stroke();
            ctx.closePath();
            //当前时间
            var time = new Date();
            let hour = time.getHours() % 12;
            let min = time.getMinutes();
            let sec = time.getSeconds();
            console.log("ss",hour,min,sec);

            //时钟
            ctx.rotate(2 * Math.PI /12 *hour + 2*Math.PI/12 *(min/60) -Math.PI /2);
            ctx.beginPath()
            //moveTo设置画线起点
            ctx.moveTo(-10,0)
            //lineTo设置画线经过点
            ctx.lineTo(54,0);
            ctx.lineWidth=6;
            ctx.strokeStyle = '#000'
            ctx.stroke()
            ctx.closePath()
            // 恢复成上一次save的状态
            ctx.restore()
            // 恢复完再保存一次
            ctx.save()

            //分钟
            ctx.rotate(2* Math.PI/60 * min + 2* Math.PI/60 *(sec/60) - Math.PI/2);
            ctx.beginPath();
            ctx.moveTo(-10, 0);
            ctx.lineTo(90, 0);
            ctx.lineWidth=3;
            ctx.strokeStyle = '#000'
            ctx.stroke()
            ctx.closePath()
            ctx.restore()
            ctx.save()

            //秒针
            ctx.rotate(2 * Math.PI / 60 * sec - Math.PI / 2)
            ctx.beginPath()
            ctx.moveTo(-10, 0)
            ctx.lineTo(80, 0)
            ctx.strokeStyle = '#666'
            ctx.stroke()
            ctx.closePath()
            ctx.restore()
            ctx.save()

            // 绘制刻度,也是跟绘制时分秒针一样,只不过刻度是死的
            ctx.lineWidth = 1
            for (let i = 0; i < 60; i++) {
                ctx.rotate(2 * Math.PI / 60)
                ctx.beginPath()
                ctx.moveTo(90, 0)
                ctx.lineTo(100, 0)
                // ctx.strokeStyle = 'red'
                ctx.stroke()
                ctx.closePath()
            }
            ctx.restore()
            ctx.save()

            ctx.lineWidth = 5

            for (let i = 0; i < 12; i++) {
                ctx.rotate(2 * Math.PI / 12)
                ctx.beginPath()
                ctx.moveTo(85, 0)
                ctx.lineTo(100, 0)
                ctx.stroke()
                ctx.closePath()
            }
            ctx.restore()
            ctx.restore()
        },1000)

    </script>

2刮刮卡

html
<div class="html5">
        <div class="warp">
            <div class="inner-warp">
                <canvas id="canvas" class="canvas"></canvas>
                <div class="rs mentos abs"></div>
                <div class="rs empty abs"></div>
            </div>
        </div>
    </div>
css
<style>
        * {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            height: 100%;
            overflow: hidden;
        }
        .html5{
             320px;
            height: 188px;
            background: url(http://img.aimoge.com/Fnna0oYkHLIJqoqJ5L10aJwS7-99) 0 0 no-repeat;
            background-size: 100% auto;
            margin:0 auto;
            position: relative;
        }
        .abs {
            position: absolute;
        }
        .warp{
            position: relative;
             260px;
            height: 120px;
            top: 31px;
            left: 30px;
            padding:6px 10px;
            box-sizing: border-box;
            background-color: #fff;
        }
        .inner-warp{
            100%;
            height:100%;
            position: relative;
        }
        .canvas {
            position:absolute;
            top: 0px;
            left: 0px;
            z-index: 350;
        }
        .html5 .rs {
            position: absolute;
             240px;
            height: 108px;
            top: 0px;
            left: 0px;
            display: none;
            background-size: 100% auto;
            background-repeat: no-repeat;
            z-index: 300;
        }

        .html5 .rs.mentos {
            background-image:刮刮卡下面的图片;
        }  
<script>
        var img = new Image();
        img.crossOrigin = '';
        img.src = 'http://img.aimoge.com/FluRH5rP3ur-Se2XTKatZaLZvdTD';

        function initCanvasResult(){
           document.querySelector(".mentos").style.display="block";
        }
     //计算偏移量
        function getPoint(obj){
            let t = obj.offsetTop;
            let l = obj.offsetLeft;
            while(obj = obj.offsetParent){
                t += obj.offsetTop;
                l += obj.offsetLeft;
            }
            return{
                offsetTop:t,
                offsetLeft:l
            }
        }
        function getTransparentPercent(ctx,width,height){
            console.log("ss",ctx,width,height)
            var imgData = ctx.getImageData(0, 0, width, height),
                        pixles = imgData.data,
                        transPixs = [];
            console.log("sssss",imgData,pixles,transPixs)
            for (var i = 0, j = pixles.length; i < j; i += 4) {
                var a = pixles[i + 3];
                if (a < 128) {
                    transPixs.push(i);
                }
            }
            return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
            
        }

        img.onload =function(){
            const canvas = document.querySelector('#canvas');
            let canvasOffset = getPoint(canvas);
            let ctx = canvas.getContext('2d');
            let width=240,height=108,precent=0;
            canvas.width = width;
            canvas.height = height;
            //偏移量
            let offsetX = canvasOffset.offsetLeft, offsetY = canvasOffset.offsetTop;
            
            ctx.drawImage(img, 0, 0, width, height);
            //显示挂挂卡下面的底图
            initCanvasResult();
            var mousedown = false;

            canvas.addEventListener('touchstart',function(e){
                mousedown = true;
                ctx.globalCompositeOperation = "destination-out";
				ctx.lineWidth = 40;
				ctx.lineCap = "round";
				ctx.lineJoin = "round";
            })

            canvas.addEventListener('touchmove',function(e){
                e.preventDefault();
                let touches = e.changedTouches[0];
                if(!mousedown){
                    return;
                }
               
                if(touches){
                    var x = touches.clientX - offsetX,
                        y = touches.clientY - offsetY;
                    ctx.arc(x, y, 10, 0, Math.PI * 2);
                    ctx.fill();
                }
            })

            canvas.addEventListener('touchend',function(e){
                mousedown=false;
                precent = getTransparentPercent(ctx,width,height);
                if (precent > 50 && precent != 100) {
                    ctx.clearRect(0, 0, width, height);
                    alert('恭喜,获得礼品一份!!!');
                }
            })
        }
    </script>

 圆环,只写个大概,等有时间加入到组件库里面去

//html
<div class="pie-wrap pie-wrap-small">
        <canvas id="pie-canvas" class="pie-canvas"></canvas>
        <div class="pie-text-wrap">
            <div class="title">
                25%
            </div>
        </div>
    </div>
//css
.pie-wrap{
            position: relative;
        }
        .pie-wrap-small{
            110px;
            height: 110px;
        }
        .pie-canvas{
             110px;
            height: 110px;
        }
        .pie-text-wrap{
            position: absolute;
            top: 0px;
            left: 0px;
             110px;
            height: 110px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }
        .pie-text-wrap .title{
            font-weight: bold;
            font-size: 26px;
            letter-spacing: 0;
            text-align: center;
            line-height: 30px;
        }
//js
var setProps={
            type: 'info',
            size: 'small',
            value: '0.25',
            title: '',
            subtitle: '',
            titleColor: '',
            subtitleColor: '#666',
            /*背景色*/
            bgRingColor: "#eee",
            /** 上层圆环颜色 */
            fgRingColor: '#3377FF'
        }
        
        function calcSizes(){
            /** 视觉稿中饼图边长 */
            let canvasCSSEdgeLength = 110
            /** 视觉稿中线段宽度 */
            let lineCSSWidth = 10
            switch (setProps.size) {
                case 'small':
                    canvasCSSEdgeLength = 110
                    lineCSSWidth = 10
                    break
                case 'large':
                    canvasCSSEdgeLength = 220
                    lineCSSWidth = 20
                    break
            }
            const pixelRatio = 750 / Math.min(document.documentElement.clientWidth, 750);
            
            /** canvas 实际边长 */
            /** canvas 实际边长 */
            const canvasEdgeLength =(canvasCSSEdgeLength * window.devicePixelRatio) / pixelRatio;
            /** canvas 中线段实际宽度 */
            const lineWidth = (lineCSSWidth * window.devicePixelRatio) / pixelRatio
            console.log("qqq",canvasEdgeLength,lineWidth);
            return{
                canvasEdgeLength,
                lineWidth
            }
            
        }
        function initRenderCanvas(){
            const canvas=document.getElementById("pie-canvas");
            const ctx = canvas.getContext("2d");
            //圆心x轴
            let canvasEdgeLength=calcSizes().canvasEdgeLength;
            let lineWidth =calcSizes().lineWidth;
            canvas.width=canvasEdgeLength;
            canvas.height=canvasEdgeLength;
            const centerX = canvasEdgeLength/2;
            const centerY = centerX;
            let  percentValue = setProps.value;
            console.log("sss",centerX)
            //圆环半径
            const ringRadius = centerX - lineWidth /2;
            /** 圆弧的起点,x轴方向开始计算,单位以弧度表示 */
            const startAngle = -0.5 * Math.PI
            /** 下层圆环的终点 */
            const bgRingEndAngle = 1.5 * Math.PI
            /** 上层圆环的终点,根据百分比计算 */
            const fgRingAngle = (2 * setProps.value - 0.5) * Math.PI
            ctx.lineWidth = lineWidth // 线段宽度
            ctx.lineCap = 'round' // 线段末端样式
            //绘制下层灰色圆环
            ctx.beginPath()
            ctx.strokeStyle = setProps.bgRingColor // 画笔颜色
            ctx.arc(centerX, centerY, ringRadius, startAngle, bgRingEndAngle, false)
            ctx.stroke()
            // 绘制上层百分比圆环
            if(percentValue>0){
                ctx.beginPath();
                ctx.strokeStyle = setProps.fgRingColor
                ctx.arc(centerX, centerY, ringRadius, startAngle, fgRingAngle, false)
                ctx.stroke();
            }

        }
        window.onload=function(){
            calcSizes()
            initRenderCanvas();
        }

上面这个圆环可以继续拓展
setProps这个对象里面定义的属性可以继续加进去封装成组件,知道就行,懒得弄

参考地址:https://juejin.cn/post/6986785259966857247

日常所遇,随手而记。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注