• JS绘制极坐标颜色渐变


    SVG如何做到极坐标渐变

    原生SVG是不支持这样渐变的。矢量绘图软件在作出这些渐变后也要在导出时将渐变转换为位图,内嵌在矢量图里,但是这样做要么不能解决放大缩小带来的失真问题,要么使得矢量图太大。那么如何用SVG作出这种渐变呢?

    通常SVG渐变是这样做的:

    <defs>
    	<linearGradient id="grad1" x1="0%" y1="100%" x2="100%" y2="0%">
    		<stop offset="0%" stop-color="#fff" stop-opacity="1"/>
    		<stop offset="100%" stop-color="#000" stop-opacity="1"/>
    	</linearGradient>
    </defs>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    表示从y=100%, x=0%开始到y=0%,x=100%结束中,0%处为颜色#fff100%处为颜色#000;即左下角为白色,右上角为黑色。

    整体SVG:

    <svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg"><defs>
    	<linearGradient id="grad1" x1="0%" y1="100%" x2="100%" y2="0%">
    		<stop offset="0%" stop-color="#fff" stop-opacity="1"/>
    		<stop offset="100%" stop-color="#000" stop-opacity="1"/>
    	</linearGradient>
    </defs>
    
    <circle cx="50" cy="50" r="50" fill="url(#grad1)"/>
    </svg>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    但是这样只是得到一个圆形的线性渐变而不是我们想要的下面这样的渐变👇

    欸呦图丢了

    如何做旋转渐变

    因为不支持而做不到,那只能绕个弯子,关键是CSS也不支持……
    办法倒也不是没有,在SVG中插入<foreignObject/>然后直接用JS在<canvas/>上画出渐变。画出来的话,占用空间更小一点而且分辨率没有太多限制,除非分辨率太高需要很久才能画完。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            canvas {
                width: 200px;
                height: 200px;
            }
        </style>
    </head>
    
    <body>
        <canvas id="canvas" width="100" height="100"></canvas>
    </body>
    <script>
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext("2d");
        var w = canvas.width;
        var h = canvas.height;
        const CX = w / 2;
        const CY = h / 2;
        const OFFSET = 90;//旋转角度
        const START = 90;//开始渐变角度
        const RANGE = 180;//渐变角度
        const ROUNT = 360;//周角
        const WHITE = 255;//最亮颜色值
        for (var y = 0; y < h; y++) {
            for (var x = 0; x < w; x++) {
                var theta = (Math.atan2(y - CY, x - CX) + Math.PI) / (Math.PI * 2) * (ROUNT - 1);
                theta = (theta + OFFSET) % ROUNT + START
                theta = Math.max(Math.min(Math.floor(((ROUNT - 1) - theta) / RANGE * WHITE), WHITE), 0);
                var color = theta.toString(16);
                while (color.length < 2) {
                    color = '0' + color
                }
                color = '#000000' + color
                ctx.fillStyle = color;
                ctx.fillRect(x, y, 1, 1)
            }
        }
    </script>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    linux两块硬盘挂载同一个目录
    Fiber的理解
    Android Navigation 过渡动画
    第十九章总结
    园子开店记:被智能的淘宝处罚,说是“预防性的违规”
    Tomcat 源码构建
    小程序面试题:小程序兼容性问题
    5_spring-cloud-zuul-网关
    【重识云原生】第六章容器基础6.4.9.3节——Service拓扑感知
    Vue打包好的dist如何在本地运行
  • 原文地址:https://blog.csdn.net/dscn15848078969/article/details/125510077