分别用python,java,HTML+JS+CSS绘制心型

分别用python,java,HTML+JS+CSS绘制心型

  • python绘制
  • java绘制
  • HTML+JS+CSS

python绘制

多的不说直接上代码

import random
from math import sin, cos, pi, log
from tkinter import *

CANVAS_WIDTH = 640
CANVAS_HEIGHT = 480
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR = "#FFC0CB" #ff2121


def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):

    x = 16 * (sin(t) ** 3)
    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

    x *= shrink_ratio
    y *= shrink_ratio

    x += CANVAS_CENTER_X
    y += CANVAS_CENTER_Y

    return int(x), int(y)


def scatter_inside(x, y, beta=0.15):

    ratio_x = - beta * log(random.random())
    ratio_y = - beta * log(random.random())

    dx = ratio_x * (x - CANVAS_CENTER_X)
    dy = ratio_y * (y - CANVAS_CENTER_Y)

    return x - dx, y - dy


def shrink(x, y, ratio):

    force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)  # 这个参数...
    dx = ratio * force * (x - CANVAS_CENTER_X)
    dy = ratio * force * (y - CANVAS_CENTER_Y)
    return x - dx, y - dy


def curve(p):

    return 2 * (2 * sin(4 * p)) / (2 * pi)


class Heart:

    def __init__(self, generate_frame=20):
        self._points = set()  # 原始爱心坐标集合
        self._edge_diffusion_points = set()  # 边缘扩散效果点坐标集合
        self._center_diffusion_points = set()  # 中心扩散效果点坐标集合
        self.all_points = {}  # 每帧动态点坐标
        self.build(2000)

        self.random_halo = 1000

        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):

        for _ in range(number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t)
            self._points.add((x, y))


        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.05)
                self._edge_diffusion_points.add((x, y))


        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.17)
            self._center_diffusion_points.add((x, y))

    @staticmethod
    def calc_position(x, y, ratio):

        force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)  # 魔法参数

        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)

        return x - dx, y - dy

    def calc(self, generate_frame):
        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例

        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))

        all_points = []

        heart_halo_point = set()
        for _ in range(halo_number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t, shrink_ratio=11.6)
            x, y = shrink(x, y, halo_radius)
            if (x, y) not in heart_halo_point:
                heart_halo_point.add((x, y))
                x += random.randint(-14, 14)
                y += random.randint(-14, 14)
                size = random.choice((1, 2, 2))
                all_points.append((x, y, size))

        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 3)
            all_points.append((x, y, size))

        for x, y in self._edge_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        for x, y in self._center_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        self.all_points[generate_frame] = all_points

    def render(self, render_canvas, render_frame):
        for x, y, size in self.all_points[render_frame % self.generate_frame]:
            render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)


def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
    render_canvas.delete('all')
    render_heart.render(render_canvas, render_frame)
    main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)


if __name__ == '__main__':
    root = Tk()  # 一个Tk
    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()
    draw(root, canvas, heart)
    root.mainloop()

运行结果:
分别用python,java,HTML+JS+CSS绘制心型_第1张图片

java绘制

第一种:

package Student;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Toolkit;

import javax.swing.JFrame;

public class xin extends JFrame {

    private static final long serialVersionUID = -1284128891908775645L;

// 定义加载窗口大小

    public static final int GAME_WIDTH = 500;

    public static final int GAME_HEIGHT = 500;

// 获取屏幕窗口大小

    public static final int WIDTH = Toolkit.getDefaultToolkit()

            .getScreenSize().width;

    public static final int HEIGHT = Toolkit.getDefaultToolkit()

            .getScreenSize().height;

    public void Demo() {

// 设置窗口标题

        this.setTitle("心形曲线");

// 设置窗口初始位置

        this.setLocation((WIDTH - GAME_WIDTH) / 2, (HEIGHT - GAME_HEIGHT) / 2);

// 设置窗口大小

        this.setSize(GAME_WIDTH, GAME_HEIGHT);

// 设置背景色

        this.setBackground(Color.BLACK);

// 设置窗口关闭方式

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// 设置窗口显示

        this.setVisible(true);

    }

    @Override

    public void paint(Graphics g) {

        double x, y, r;

        Image OffScreen = createImage(GAME_WIDTH, GAME_HEIGHT);

        Graphics drawOffScreen = OffScreen.getGraphics();

        for (int i = 0; i < 90; i++) {

            for (int j = 0; j < 90; j++) {

                r = Math.PI / 45 * i * (1 - Math.sin(Math.PI / 45 * j)) * 18;

                x = r * Math.cos(Math.PI / 45 * j) * Math.sin(Math.PI / 45 * i)

                        + GAME_WIDTH / 2;

                y = -r * Math.sin(Math.PI / 45 * j) + GAME_HEIGHT / 4;

//设置画笔颜色

                drawOffScreen.setColor(Color.PINK);

// 绘制椭圆

                drawOffScreen.fillOval((int) x, (int) y, 2, 2);

            }

// 生成图片

            g.drawImage(OffScreen, 0, 0, this);

        }

    }

    public static void main(String[] args) {

        xin demo = new xin();

        demo.setVisible(true);

    }

}

运行结果:
分别用python,java,HTML+JS+CSS绘制心型_第2张图片
第二种:

package Student;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Toolkit;

import javax.swing.JFrame;

@SuppressWarnings("serial")

class Cardioid extends JFrame {

// 定义窗口大小

    private static final int WIDTH = 480;

    private static final int HEIGHT = 600;

// 获取屏幕大小

    private static int WINDOW_WIDTH = Toolkit.getDefaultToolkit()

            .getScreenSize().width;

    private static int WINDOW_HEIGHT = Toolkit.getDefaultToolkit()

            .getScreenSize().height;

// 构造函数

    public Cardioid() {

// 设置窗口标题

        super("❤形线");

// 设置背景色

        this.setBackground(Color.BLACK);

// 设置窗口位置

        this.setLocation((WINDOW_WIDTH - WIDTH) / 2,

                (WINDOW_HEIGHT - HEIGHT) / 2);

// 设置窗口大小

        this.setSize(WIDTH, HEIGHT);

// 设置窗口布局

        this.setLayout(getLayout());

// 设置窗口可见

        this.setVisible(true);

// 设置窗口默认关闭方式

        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    }

    public void paint(Graphics g) {

        double x, y, r; // 横纵坐标及半径

        Image image = this.createImage(WIDTH, HEIGHT);

        Graphics pic = image.getGraphics();

// 绘制图形

        for (int i = 0; i < 100; i++) {

            for (int j = 0; j < 100; j++) {

                r = Math.PI / 45 + Math.PI / 45 * i

                        * (1 - Math.sin(Math.PI / 45 * j)) * 18;

                x = r * Math.cos(Math.PI / 45 * j) * Math.sin(Math.PI / 45 * i)

                        + WIDTH / 2;

                y = -r * Math.sin(Math.PI / 45 * j) + HEIGHT / 2;

                pic.setColor(Color.MAGENTA);

                pic.fillOval((int) x, (int) y, 2, 2);

            }

// 生成图片

            g.drawImage(image, 0, 0, this);

        }

    }

    public static void main(String[] args) {

        new Cardioid();

    }

}

结果:
分别用python,java,HTML+JS+CSS绘制心型_第3张图片

HTML+JS+CSS

如果你的电脑上啥编译器也没有,你自己也不想安装,好吧用它就行了
第一种:

<HTML>
  <style>
  html, body {
  height: 100%;
  padding: 0;
  margin: 0;
  background: #000;
}
canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}
  style>
 HEAD>
 
 <BODY>
  <canvas id="pinkboard">canvas>
  <script>
  /*
 * Settings
 */
var settings = {
  particles: {
    length:   500, // maximum amount of particles
    duration:   2, // particle duration in sec
    velocity: 100, // particle velocity in pixels/sec
    effect: -0.75, // play with this for a nice effect
    size:      30, // particle size in pixels
  },
};
 
/*
 * RequestAnimationFrame polyfill by Erik Möller
 */
(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());
 
/*
 * Point class
 */
var Point = (function() {
  function Point(x, y) {
    this.x = (typeof x !== 'undefined') ? x : 0;
    this.y = (typeof y !== 'undefined') ? y : 0;
  }
  Point.prototype.clone = function() {
    return new Point(this.x, this.y);
  };
  Point.prototype.length = function(length) {
    if (typeof length == 'undefined')
      return Math.sqrt(this.x * this.x + this.y * this.y);
    this.normalize();
    this.x *= length;
    this.y *= length;
    return this;
  };
  Point.prototype.normalize = function() {
    var length = this.length();
    this.x /= length;
    this.y /= length;
    return this;
  };
  return Point;
})();
 
/*
 * Particle class
 */
var Particle = (function() {
  function Particle() {
    this.position = new Point();
    this.velocity = new Point();
    this.acceleration = new Point();
    this.age = 0;
  }
  Particle.prototype.initialize = function(x, y, dx, dy) {
    this.position.x = x;
    this.position.y = y;
    this.velocity.x = dx;
    this.velocity.y = dy;
    this.acceleration.x = dx * settings.particles.effect;
    this.acceleration.y = dy * settings.particles.effect;
    this.age = 0;
  };
  Particle.prototype.update = function(deltaTime) {
    this.position.x += this.velocity.x * deltaTime;
    this.position.y += this.velocity.y * deltaTime;
    this.velocity.x += this.acceleration.x * deltaTime;
    this.velocity.y += this.acceleration.y * deltaTime;
    this.age += deltaTime;
  };
  Particle.prototype.draw = function(context, image) {
    function ease(t) {
      return (--t) * t * t + 1;
    }
    var size = image.width * ease(this.age / settings.particles.duration);
    context.globalAlpha = 1 - this.age / settings.particles.duration;
    context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
  };
  return Particle;
})();
 
/*
 * ParticlePool class
 */
var ParticlePool = (function() {
  var particles,
      firstActive = 0,
      firstFree   = 0,
      duration    = settings.particles.duration;
  
  function ParticlePool(length) {
    // create and populate particle pool
    particles = new Array(length);
    for (var i = 0; i < particles.length; i++)
      particles[i] = new Particle();
  }
  ParticlePool.prototype.add = function(x, y, dx, dy) {
    particles[firstFree].initialize(x, y, dx, dy);
    
    // handle circular queue
    firstFree++;
    if (firstFree   == particles.length) firstFree   = 0;
    if (firstActive == firstFree       ) firstActive++;
    if (firstActive == particles.length) firstActive = 0;
  };
  ParticlePool.prototype.update = function(deltaTime) {
    var i;
    
    // update active particles
    if (firstActive < firstFree) {
      for (i = firstActive; i < firstFree; i++)
        particles[i].update(deltaTime);
    }
    if (firstFree < firstActive) {
      for (i = firstActive; i < particles.length; i++)
        particles[i].update(deltaTime);
      for (i = 0; i < firstFree; i++)
        particles[i].update(deltaTime);
    }
    
    // remove inactive particles
    while (particles[firstActive].age >= duration && firstActive != firstFree) {
      firstActive++;
      if (firstActive == particles.length) firstActive = 0;
    }
    
    
  };
  ParticlePool.prototype.draw = function(context, image) {
    // draw active particles
    if (firstActive < firstFree) {
      for (i = firstActive; i < firstFree; i++)
        particles[i].draw(context, image);
    }
    if (firstFree < firstActive) {
      for (i = firstActive; i < particles.length; i++)
        particles[i].draw(context, image);
      for (i = 0; i < firstFree; i++)
        particles[i].draw(context, image);
    }
  };
  return ParticlePool;
})();
 
/*
 * Putting it all together
 */
(function(canvas) {
  var context = canvas.getContext('2d'),
      particles = new ParticlePool(settings.particles.length),
      particleRate = settings.particles.length / settings.particles.duration, // particles/sec
      time;
  
  // get point on heart with -PI <= t <= PI
  function pointOnHeart(t) {
    return new Point(
      160 * Math.pow(Math.sin(t), 3),
      130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
    );
  }
  
  // creating the particle image using a dummy canvas
  var image = (function() {
    var canvas  = document.createElement('canvas'),
        context = canvas.getContext('2d');
    canvas.width  = settings.particles.size;
    canvas.height = settings.particles.size;
    // helper function to create the path
    function to(t) {
      var point = pointOnHeart(t);
      point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
      point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
      return point;
    }
    // create the path
    context.beginPath();
    var t = -Math.PI;
    var point = to(t);
    context.moveTo(point.x, point.y);
    while (t < Math.PI) {
      t += 0.01; // baby steps!
      point = to(t);
      context.lineTo(point.x, point.y);
    }
    context.closePath();
    // create the fill
    context.fillStyle = '#ea80b0';
    context.fill();
    // create the image
    var image = new Image();
    image.src = canvas.toDataURL();
    return image;
  })();
  
  // render that thing!
  function render() {
    // next animation frame
    requestAnimationFrame(render);
    
    // update time
    var newTime   = new Date().getTime() / 1000,
        deltaTime = newTime - (time || newTime);
    time = newTime;
    
    // clear canvas
    context.clearRect(0, 0, canvas.width, canvas.height);
    
    // create new particles
    var amount = particleRate * deltaTime;
    for (var i = 0; i < amount; i++) {
      var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
      var dir = pos.clone().length(settings.particles.velocity);
      particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
    }
    
    // update and draw particles
    particles.update(deltaTime);
    particles.draw(context, image);
  }
  
  // handle (re-)sizing of the canvas
  function onResize() {
    canvas.width  = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
  }
  window.onresize = onResize;
  
  // delay rendering bootstrap
  setTimeout(function() {
    onResize();
    render();
  }, 10);
})(document.getElementById('pinkboard'));
  script>
 BODY>
HTML>

效果展示:
分别用python,java,HTML+JS+CSS绘制心型_第4张图片
第二种:


DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>流动爱心表白title>
    <link rel="stylesheet" href="css/style.css" />
  head>
 
  <body>
    
    <canvas id="canvas" width="1400" height="600">canvas>
    
    <script src="js/script.js">script>
  body>
html>
 

效果展示:
分别用python,java,HTML+JS+CSS绘制心型_第5张图片
第三种:
这种有点复杂,但是嘎嘎板正:
你需要创建一个文件夹叫啥名都行里面在创建三个文件夹分别命名 img,js,css,在js里面创建script.js,在css里面创建style.css,在主文件创建***.HTML文件。在img文件夹里面加入六张图片,向我下面这样命名就行。
分别用python,java,HTML+JS+CSS绘制心型_第6张图片

***.HTML文件

DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }
        
        body {
            perspective: 1000px;
        }
        
        #cube {
            position: relative;
            left: 0;
            top: 0;
            width: 200px;
            height: 200px;
            transform-origin: 50% 50% -100px;
            /*设置3D的环境*/
            transform-style: preserve-3d;
            transition: 2s;
            transform: translateX(60px) translateY(300px) translateZ(60px);
        }
        
        #cube div {
            position: absolute;
            width: 200px;
            height: 200px;
        }
        
        #cube div:nth-child(1) {
            top: -200px;
            transform-origin: bottom;
            transform: rotateX(90deg);
        }
        
        #cube div:nth-child(2) {
            top: 200px;
            transform-origin: top;
            transform: rotateX(-90deg);
        }
        
        #cube div:nth-child(3) {
            left: -200px;
            transform-origin: right;
            transform: rotateY(-90deg);
        }
        
        #cube div:nth-child(4) {
            left: 200px;
            transform-origin: left;
            transform: rotateY(90deg);
        }
        
        #cube div:nth-child(5) {
            transform: translateZ(-200deg)
        }
        
        #cube div:nth-child(6) {}
        
        body {
            background-color: black;
        }
        
        #heard {
            position: relative;
            width: 300px;
            height: 600px;
            margin: 100px auto;
            transform-style: preserve-3d;
            animation: rot 10s linear infinite;
        }
        
        @keyframes rot {
            from {
                transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg)
            }
            to {
                transform: rotateY(360deg) rotateX(360deg) rotate(270deg)
            }
        }
        
        #heard div.heard {
            position: absolute;
            left: 0;
            top: 0;
            width: 300px;
            height: 600px;
            /*border: 2px solid red;*/
            border-left: 0;
            border-bottom: 0;
            border-radius: 50% 50% 0 /40% 50% 0;
        }
        
        #cube img {
            width: 200px;
            height: 200px;
        }
    style>
head>

<body>
    <div id=heard>
        <div id="cube">
            <div><img src="img/01.jpg" />div>
            <div><img src="img/02.jpg" />div>
            <div><img src="img/b_3.jpg" />div>
            <div><img src="img/b_4.jpg" />div>
            <div><img src="img/b_5.jpg" />div>
            <div><img src="img/b_6.jpg" />div>
        div>
    div>

body>
<script type="text/javascript">
    var colors = ["#FFB6C1", "#DB7093", "#FF69B4", "#483D8B", "# 4169E1", "#87CEFA", "#00BFFF", "#5F9EA0", "#00FA9A",
        "#00FF7F", "#7FFF00", "#FFFFE0", "#F5DEB3", "#BC8F8F", "#800000"
    ];
    var heard = document.getElementById("heard");
    for (var i = 0; i < 36; i++) {
        var cdiv = document.createElement("div");
        cdiv.className = "heard";
        cdiv.style.border = "2px solid " + colors[i % 15];
        cdiv.style.borderLeft = "0";
        cdiv.style.borderBottom = "0";
        cdiv.style.transform = "rotateY(" + i * 10 + "deg) rotateZ(45deg) translateX(150px)";
        heard.appendChild(cdiv);
    }
script>

html>

script.js

var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Initialize the GL context
var gl = canvas.getContext('webgl');
if (!gl) {
    console.error("Unable to initialize WebGL.");
}
//Time step
var dt = 0.015;
//Time
var time = 0.0;
//************** Shader sources **************
var vertexSource = `
attribute vec2 position;
void main() {
	gl_Position = vec4(position, 0.0, 1.0);
}
`;
 
var fragmentSource = `
precision highp float;
uniform float width;
uniform float height;
vec2 resolution = vec2(width, height);
uniform float time;
#define POINT_COUNT 8
vec2 points[POINT_COUNT];
const float speed = -0.5;
const float len = 0.25;
float intensity = 0.9;
float radius = 0.015;
//https://www.shadertoy.com/view/MlKcDD
//Signed distance to a quadratic bezier
float sdBezier(vec2 pos, vec2 A, vec2 B, vec2 C){    
	vec2 a = B - A;
	vec2 b = A - 2.0*B + C;
	vec2 c = a * 2.0;
	vec2 d = A - pos;
	float kk = 1.0 / dot(b,b);
	float kx = kk * dot(a,b);
	float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0;
	float kz = kk * dot(d,a);      
	float res = 0.0;
	float p = ky - kx*kx;
	float p3 = p*p*p;
	float q = kx*(2.0*kx*kx - 3.0*ky) + kz;
	float h = q*q + 4.0*p3;
	if(h >= 0.0){ 
		h = sqrt(h);
		vec2 x = (vec2(h, -h) - q) / 2.0;
		vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0));
		float t = uv.x + uv.y - kx;
		t = clamp( t, 0.0, 1.0 );
		// 1 root
		vec2 qos = d + (c + b*t)*t;
		res = length(qos);
	}else{
		float z = sqrt(-p);
		float v = acos( q/(p*z*2.0) ) / 3.0;
		float m = cos(v);
		float n = sin(v)*1.732050808;
		vec3 t = vec3(m + m, -n - m, n - m) * z - kx;
		t = clamp( t, 0.0, 1.0 );
		// 3 roots
		vec2 qos = d + (c + b*t.x)*t.x;
		float dis = dot(qos,qos);
        
		res = dis;
		qos = d + (c + b*t.y)*t.y;
		dis = dot(qos,qos);
		res = min(res,dis);
		
		qos = d + (c + b*t.z)*t.z;
		dis = dot(qos,qos);
		res = min(res,dis);
		res = sqrt( res );
	}
    
	return res;
}
//http://mathworld.wolfram.com/HeartCurve.html
vec2 getHeartPosition(float t){
	return vec2(16.0 * sin(t) * sin(t) * sin(t),
							-(13.0 * cos(t) - 5.0 * cos(2.0*t)
							- 2.0 * cos(3.0*t) - cos(4.0*t)));
}
//https://www.shadertoy.com/view/3s3GDn
float getGlow(float dist, float radius, float intensity){
	return pow(radius/dist, intensity);
}
float getSegment(float t, vec2 pos, float offset, float scale){
	for(int i = 0; i < POINT_COUNT; i++){
		points[i] = getHeartPosition(offset + float(i)*len + fract(speed * t) * 6.28);
	}
    
	vec2 c = (points[0] + points[1]) / 2.0;
	vec2 c_prev;
	float dist = 10000.0;
    
	for(int i = 0; i < POINT_COUNT-1; i++){
		//https://tinyurl.com/y2htbwkm
		c_prev = c;
		c = (points[i] + points[i+1]) / 2.0;
		dist = min(dist, sdBezier(pos, scale * c_prev, scale * points[i], scale * c));
	}
	return max(0.0, dist);
}
void main(){
	vec2 uv = gl_FragCoord.xy/resolution.xy;
	float widthHeightRatio = resolution.x/resolution.y;
	vec2 centre = vec2(0.5, 0.5);
	vec2 pos = centre - uv;
	pos.y /= widthHeightRatio;
	//Shift upwards to centre heart
	pos.y += 0.02;
	float scale = 0.000015 * height;
	
	float t = time;
    
	//Get first segment
	float dist = getSegment(t, pos, 0.0, scale);
	float glow = getGlow(dist, radius, intensity);
    
	vec3 col = vec3(0.0);
    
	//White core
	col += 10.0*vec3(smoothstep(0.003, 0.001, dist));
	//Pink glow
	col += glow * vec3(0.94,0.14,0.4);
    
	//Get second segment
	dist = getSegment(t, pos, 3.4, scale);
	glow = getGlow(dist, radius, intensity);
    
	//White core
	col += 10.0*vec3(smoothstep(0.003, 0.001, dist));
	//Blue glow
	col += glow * vec3(0.2,0.6,1.0);
        
	//Tone mapping
	col = 1.0 - exp(-col);
	//Output to screen
 	gl_FragColor = vec4(col,1.0);
}
`;
 
//************** Utility functions **************
 
window.addEventListener('resize', onWindowResize, false);
 
function onWindowResize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.uniform1f(widthHandle, window.innerWidth);
    gl.uniform1f(heightHandle, window.innerHeight);
}
 
 
//Compile shader and combine with source
function compileShader(shaderSource, shaderType) {
    var shader = gl.createShader(shaderType);
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        throw "Shader compile failed with: " + gl.getShaderInfoLog(shader);
    }
    return shader;
}
 
//From https://codepen.io/jlfwong/pen/GqmroZ
//Utility to complain loudly if we fail to find the attribute/uniform
function getAttribLocation(program, name) {
    var attributeLocation = gl.getAttribLocation(program, name);
    if (attributeLocation === -1) {
        throw 'Cannot find attribute ' + name + '.';
    }
    return attributeLocation;
}
 
function getUniformLocation(program, name) {
    var attributeLocation = gl.getUniformLocation(program, name);
    if (attributeLocation === -1) {
        throw 'Cannot find uniform ' + name + '.';
    }
    return attributeLocation;
}
 
//************** Create shaders **************
 
//Create vertex and fragment shaders
var vertexShader = compileShader(vertexSource, gl.VERTEX_SHADER);
var fragmentShader = compileShader(fragmentSource, gl.FRAGMENT_SHADER);
 
//Create shader programs
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
 
gl.useProgram(program);
 
//Set up rectangle covering entire canvas 
var vertexData = new Float32Array([-1.0, 1.0, // top left
    -1.0, -1.0, // bottom left
    1.0, 1.0, // top right
    1.0, -1.0, // bottom right
]);
 
//Create vertex buffer
var vertexDataBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
 
// Layout of our data in the vertex buffer
var positionHandle = getAttribLocation(program, 'position');
 
gl.enableVertexAttribArray(positionHandle);
gl.vertexAttribPointer(positionHandle,
    2, // position is a vec2 (2 values per component)
    gl.FLOAT, // each component is a float
    false, // don't normalize values
    2 * 4, // two 4 byte float components per vertex (32 bit float is 4 bytes)
    0 // how many bytes inside the buffer to start from
);
 
//Set uniform handle
var timeHandle = getUniformLocation(program, 'time');
var widthHandle = getUniformLocation(program, 'width');
var heightHandle = getUniformLocation(program, 'height');
 
gl.uniform1f(widthHandle, window.innerWidth);
gl.uniform1f(heightHandle, window.innerHeight);
 
function draw() {
    //Update time
    time += dt;
 
    //Send uniforms to program
    gl.uniform1f(timeHandle, time);
    //Draw a triangle strip connecting vertices 0-4
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
 
    requestAnimationFrame(draw);
}
 
draw();

style.css

body {
    background-color: #000;
    margin: 0;
    overflow: hidden;
    background-repeat: no-repeat;
}

看成品:
她当然是动态的,就不给大家演示了!
分别用python,java,HTML+JS+CSS绘制心型_第7张图片

你可能感兴趣的:(python,java,html)