马黑黑 发表于 2022-8-21 10:45

线条之美

<style>
#papa { left: -214px; width: 1024px; height: 640px; display: grid; place-items: center; background: darkgray url('https://638183.freep.cn/638183/t22/51/line.jpg') no-repeat center/cover; box-shadow: 3px 3px 20px #000; position: relative; z-index: 5; }
#canv { position: relative; }
#disc { position: absolute; width: 40px; height: 40px; left: 10px; top: 10px; background: conic-gradient(red,orange,yellow,green,teal,blue,purple); mask: radial-gradient(transparent 4px,red 0); -webkit-mask: radial-gradient(transparent 4px,red 0); border-radius: 50%; cursor: pointer; z-index: 10; animation: rot 2s linear infinite; }
#lrcbox { position: absolute; left: 60px; top: 10px;font: bold 22px / 40px sans-serif; color: lightblue; text-shadow: 2px 2px 4px #222; }
@keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <span id="disc"></span>
        <span id="lrcbox">线条之美</span>
        <canvas id="canv" width="500" height="500"></canvas>
</div>

<script>
let ctx = canv.getContext('2d');
let lines = []; //线条数组
let total = 200, lineLen = canv.width / 2, idx = 0; //线条总数、线长、当前线条索引
let aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=1931775815.mp3';
aud.loop = true;
aud.autoplay = true;

disc.style.animationPlayState = aud.paused ? 'paused' : 'running';
disc.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('playing',()=> disc.style.animationPlayState = 'running');
aud.addEventListener('pause',()=> disc.style.animationPlayState = 'paused');

function Line(x1,y1,x2,y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        lines.push(this);
}

Line.prototype.draw = function() {
        ctx.beginPath();
        ctx.strokeStyle = this.color;
        ctx.setLineDash();
        ctx.moveTo(this.x1, this.y1);
        ctx.lineTo(this.x2,this.y2);
        ctx.stroke();
}


for(let j = 0; j < total; j ++) {
        let line = new Line();
        line.x1 = lineLen;
        line.y1 = lineLen;
        let angle = j* (360 / total);
        line.x2 = rotPos(line.x1,line.y1, lineLen, angle).xx;
        line.y2 = rotPos(line.x1,line.y1, lineLen, angle).yy;
}

(function render() {
        let id = idx;
        if(id <= lines.length - 1) {
                lines.color = '#' + Math.random().toString(16).substr(-6);
                lines.draw();
        }
        idx ++;
        if(idx > lines.length) {
                setTimeout(function() {
                        ctx.clearRect(0,0,canv.width, canv.height);
                        idx = 0;
                        render();
                }, 4000);
        } else {
                setTimeout(render,50);
        }
})();

function rotPos(x,y,r,angle) {
        let xx = x + r * Math.sin(angle * Math.PI / 180);
        let yy = y + r * Math.cos(angle * Math.PI / 180);
        return ({xx, yy});
}
</script>

马黑黑 发表于 2022-8-21 10:45

代码分享(全)
<style>
#papa { left: -214px; width: 1024px; height: 640px; display: grid; place-items: center; background: darkgray url('https://638183.freep.cn/638183/t22/51/line.jpg') no-repeat center/cover; box-shadow: 3px 3px 20px #000; position: relative; z-index: 5; }
#canv { position: relative; }
#disc { position: absolute; width: 40px; height: 40px; left: 10px; top: 10px; background: conic-gradient(red,orange,yellow,green,teal,blue,purple); mask: radial-gradient(transparent 4px,red 0); -webkit-mask: radial-gradient(transparent 4px,red 0); border-radius: 50%; cursor: pointer; z-index: 10; animation: rot 2s linear infinite; }
#lrcbox { position: absolute; left: 60px; top: 10px;font: bold 22px / 40px sans-serif; color: lightblue; text-shadow: 2px 2px 4px #222; }
@keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <span id="disc"></span>
        <span id="lrcbox">线条之美</span>
        <canvas id="canv" width="500" height="500"></canvas>
</div>

<script>
let ctx = canv.getContext('2d');
let lines = []; //线条数组
let total = 200, lineLen = canv.width / 2, idx = 0; //线条总数、线长、当前线条索引
let aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=1931775815.mp3';
aud.loop = true;
aud.autoplay = true;

disc.style.animationPlayState = aud.paused ? 'paused' : 'running';
disc.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('playing',()=> disc.style.animationPlayState = 'running');
aud.addEventListener('pause',()=> disc.style.animationPlayState = 'paused');

function Line(x1,y1,x2,y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        lines.push(this);
}

Line.prototype.draw = function() {
        ctx.beginPath();
        ctx.strokeStyle = this.color;
        ctx.setLineDash();
        ctx.moveTo(this.x1, this.y1);
        ctx.lineTo(this.x2,this.y2);
        ctx.stroke();
}


for(let j = 0; j < total; j ++) {
        let line = new Line();
        line.x1 = lineLen;
        line.y1 = lineLen;
        let angle = j* (360 / total);
        line.x2 = rotPos(line.x1,line.y1, lineLen, angle).xx;
        line.y2 = rotPos(line.x1,line.y1, lineLen, angle).yy;
}

(function render() {
        let id = idx;
        if(id <= lines.length - 1) {
                lines.color = '#' + Math.random().toString(16).substr(-6);
                lines.draw();
        }
        idx ++;
        if(idx > lines.length) {
                setTimeout(function() {
                        ctx.clearRect(0,0,canv.width, canv.height);
                        idx = 0;
                        render();
                }, 4000);
        } else {
                setTimeout(render,50);
        }
})();

function rotPos(x,y,r,angle) {
        let xx = x + r * Math.sin(angle * Math.PI / 180);
        let yy = y + r * Math.cos(angle * Math.PI / 180);
        return ({xx, yy});
}
</script>

马黑黑 发表于 2022-8-21 11:02

本帖最后由 马黑黑 于 2022-8-21 21:42 编辑

本帖演示:

一、画布作为帖子的一部分以插入式放置到帖子中;

二、线条组成图案

重点讲讲在画布中画线条(设画笔操作句柄是 ctx):

先把画笔移动到起笔处(moveTo):

ctx.moveTo(10, 50);

然后命令画笔画直线(lineTo):

ctx.lineTo(210, 50);
ctx.sroke();

这就画出一条水平方向(自左向右)的直线,长度为 210 - 10 = 200 像素。

lineTo() 方法需要 4 个参数:x1, y1, x2, y2。x1和y1是线条起步的xy坐标,x2和y2是线条末端xy坐标。lineTo() 设置好后,紧接着要用 ctx.sroke() 方法给线条着色,线条才能显示出来。

线条颜色就是画笔颜色,要在画线之前定义。因为 lineTo() 方法需要 stroke 上色,所以定义线条颜色的语句是:

ctx.strokeStyle = 'red';

要绘制虚线线条,画布有一个命令:ctx.setLineDash([数值数组])。其参数怪异,以后在开帖专讲,这里举个例子:

ctx.setLineDash();

这将令所画线条的点每隔一个像素有一个虚点且重复直至线条画完。

同样的,虚线的设置也应在画线之前做好。

红影 发表于 2022-8-21 11:15

是线条之美,也是对称之美呢{:4_187:}

红影 发表于 2022-8-21 11:17

马黑黑 发表于 2022-8-21 11:02
本帖演示:

一、画布作为帖子的一部分以插入式放置到帖子中;


画布的画线条方式,学习了{:4_187:}

樵歌 发表于 2022-8-21 11:30

把机械美学发挥到极致,太追求完美了。将来讨个老婆一定得是宇宙花才行{:4_189:}

马黑黑 发表于 2022-8-21 11:31

红影 发表于 2022-8-21 11:15
是线条之美,也是对称之美呢

很对称,很美{:5_117:}

马黑黑 发表于 2022-8-21 11:32

樵歌 发表于 2022-8-21 11:30
把机械美学发挥到极致,太追求完美了。将来讨个老婆一定得是宇宙花才行

夸张了。你想让我发起异常特洛伊大战呀

马黑黑 发表于 2022-8-21 11:33

红影 发表于 2022-8-21 11:17
画布的画线条方式,学习了

画线条本身是简单的,画多多的线条且构成图案还要动态去绘制,这才难

加林森 发表于 2022-8-21 11:34

好有立体感哦。太漂亮了。{:4_199:}

马黑黑 发表于 2022-8-21 11:38

加林森 发表于 2022-8-21 11:34
好有立体感哦。太漂亮了。

背景图片有景深效果

加林森 发表于 2022-8-21 11:39

马黑黑 发表于 2022-8-21 11:38
背景图片有景深效果

就是。太厉害了。佩服啊。{:4_190:}

马黑黑 发表于 2022-8-21 12:04

加林森 发表于 2022-8-21 11:39
就是。太厉害了。佩服啊。

你用ps一样可以营造的

加林森 发表于 2022-8-21 12:07

马黑黑 发表于 2022-8-21 12:04
你用ps一样可以营造的

我还在学习呢。

马黑黑 发表于 2022-8-21 12:51

加林森 发表于 2022-8-21 12:07
我还在学习呢。

严格讲是复习

加林森 发表于 2022-8-21 12:57

马黑黑 发表于 2022-8-21 12:51
严格讲是复习

嗯嗯。

醉美水芙蓉 发表于 2022-8-21 20:14

马黑黑 发表于 2022-8-21 20:16

醉美水芙蓉 发表于 2022-8-21 20:14
真没想到原来线条也可以这么美!

嗯嗯,线条是简单的,但它们可以组合出美来

樵歌 发表于 2022-8-21 21:23

马黑黑 发表于 2022-8-21 11:32
夸张了。你想让我发起异常特洛伊大战呀

这个可以有{:4_173:}

青青子衿 发表于 2022-8-21 21:36

谢谢小马黑黑老师,讲的通俗易懂。。。。。看到xx......sin......    yy...cos...俺笑得不行,不看你代码,咱都要忘了。知识运用,无所不在
页: [1] 2 3
查看完整版本: 线条之美