qt 字体旋转90_视觉系编程3——以动态字体设计为主的交互板式

这篇博客介绍了一个结合平面设计的QT项目,灵感来自《反方向的钟》。内容包括字体设计(动态消散文字,音量触发随机文字)、六边形钟的绘制、背景元素(色块和随机小X)以及交互功能(按键切换年代和反向时钟)。项目使用p5js编写,提供了完整的代码实现和演示链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

89b19d1954d952248f315719d9df0b19.png

这次的案例也是与平面设计结合

灵感来源于周杰伦的一首歌《反方向的钟》,太喜欢了所以要为它写代码~

链接在最后

最终动态效果:

一开始是无声的2020年,时钟是顺时针旋转的,这时候可以自己大声说话试试,有随机文字出现的!

分别按a,b,c之后年代会改变为2000,2001,2005,时钟也变成逆时针旋转,这里有周董不同时间的音乐,如果歌曲的音量超出阈值,也有随机文字出现。

不管什么时候,点状的字体都会随时间消散~

知乎视频​www.zhihu.com

这个案例分4部分:字体,背景,钟,交互

注:代码是p5js写的

在所有之前,设置声音的部分

function preload() {
  sound = loadSound('assets/clock.m4a');
  sound2 = loadSound('assets/yequ.m4a');
  sound3 = loadSound('assets/7.m4a');
}

function setup() {
  input = new p5.AudioIn();
  input.start();
}

function draw() {
  let volume = input.getLevel();
  a = map(volume, 0, 1, 3, 10);
}

一· 字体

1.1 会消散的字体

b11027dac692a9773883c273e8d995b6.png
有一点消散

14c89697583e0ca61ca28da0888440eb.png
大面积消散

这里用到了一个“文字转化为点”

textToPoints(tet , x , y , fontSize , [options] );

先在set up中建一个数组

points = font1.textToPoints(play_year, 0, 0, 170, {
    sampleFactor: 10,
    simplifyThreshold: 0
  });

· 然后写画点的函数,用到了上面数组里的数,并用x,y作为位置画了圆

· 这里a与音量有关,所以声音越大移动越大

· i求余数是为了给这些点创造些距离,不要太密~

function textPoints(a) {
  for (let i = 0; i < points.length - 1; i++) {
    let p = points[i];
    if (i % 20 == 0) {
      p.x += random(-0.1, 0.1) * a;
      noStroke();
      fill(255);
      ellipse(p.x, p.y, 2.3);
    }
  }
}

最后在draw中调用就可以了

  push();
  translate(370, 347);
  textPoints(a);
  pop();

1.2 音量超出阈值后,随机出现的文字

太快了,截图无能,大家可以自己玩玩看( ・᷄ὢ・᷅ )

这里同样写一个函数,如果a超过了threshold就随机写字,这里给的是0.15

这里的文字我都选择歌词的一部分,大家可随意更改~

let texts = ["回到过去", "反方向的钟", "return to the past", "shuttle time", " time machine", "go backwards", "I love you"];
let threshold = 0.15;

function randomText(a) {
  if (a > threshold) {
    push();
    fill(255);
    noStroke();
    textFont('font2');
    textSize(18);
    text(texts[int(random(texts.length - 1))], random(width), random(height));
    ellipse(random(width), random(height), a * 50, a * 50);
    pop();
  }
}

同样的在draw中调用这个函数即可。

其他字体很常规啦,都是用text写的,就不多说了~

二· 钟

da0eb923bf4ce894555e2d27b75b0a6a.png

2.1 六边形钟的外形

用beginShape,endShape写出

  //6边形钟
  push();
  translate(185, 92);
  scale(0.75);
  rotate(frameCount / -40 * t);
  stroke(255);
  strokeWeight(2);
  fill(255, 30);
  beginShape();
  vertex(17, -79);
  vertex(78, -25);
  vertex(63, 55);
  vertex(-15, 82);
  vertex(-76, 28);
  vertex(-61, -53);
  endShape(CLOSE);
  pop();

2.2 时针,分针,秒针用map()写出

这里引入了t,是为了后面与鼠标交互,让时钟反方向转起来~

  let hr = hour();
  let mn = minute();
  let sc = second();

  push();
  translate(185, 92);
  strokeWeight(2);
  rotate(-90);
  let secondAngle = map(sc, 0, 60, 0, 360);
  stroke(246, 243, 233);
  let minuteAngle = map(mn, 0, 60, 0, 360);
  stroke(246, 243, 233);
  let hourAngle = map(hr % 12, 0, 12, 0, 360);

  push();
  rotate(t * secondAngle);
  stroke(255);
  line(0, 0, 50, 0);
  pop();

  push();
  rotate(t *minuteAngle);
  stroke(100);
  line(0, 0, 37.5, 0);
  pop();

  push();
  rotate(t *hourAngle);
  stroke(200);
  line(0, 0, 25, 0);
  pop();

  stroke(255);
  point(0, 0);
  pop();

三· 背景

3.1 色块

这个很简单啦,就是画图形

function drawShapes() {
  //浅蓝色五边形
  push();
  fill(92, 205, 245);
  noStroke();
  beginShape();
  vertex(123, 68);
  vertex(249, 68);
  vertex(249, 121);
  vertex(198, 186);
  vertex(28, 186);
  endShape();
  pop();

  //线
  push();
  stroke(92, 205, 245);
  noFill();
  strokeWeight(1);
  for (let e = 0; e < 8; e++) {
    line(323, 131 + 6 * e, 278 + 6 * e, 186);
  }
  pop();

  //红色五边形
  push();
  fill(235, 55, 57);
  noStroke();
  beginShape();
  vertex(244, 41 - h);
  vertex(244, 52 - h);
  vertex(187, 125 - h);
  vertex(129, 125 - h);
  vertex(192, 41 - h);
  endShape();
  pop();

  //深蓝色五边形
  push();
  fill(35, 103, 246);
  noStroke();
  beginShape();
  vertex(250, 90 - h);
  vertex(309, 90 - h);
  vertex(309, 102 - h);
  vertex(244, 186 - h);
  vertex(176, 186 - h);
  endShape();
  pop();
}

3.2 随机生成的小 x

8586fd8351f6130c6108d87d6aea0a93.png

先建一个数组,再写2个函数,最后在draw中调用,搞定!

//数组,随机位置
function setup() {
    for (var i = 1; i < width; i += 75) {
    for (var n = 1; n < height; n += 75) {
      let x = random(width);
      let y = random(height);
      let v = random(20, 50);
      snowlocs.push([x, y, v]);
    }
  }
}
//画出
function draw() {
  for (var i = 0; i < snowlocs.length; i++) {
    var x, y, v;
    [x, y, v] = snowlocs[i];
    drawXDad(x, y, v);
  }
}

//让 x 转起来
function drawXDad(x, y, v) {
  push();
  translate(x, y);
  rotate(frameCount / -v * t);
  drawX();
  pop();
}
//一个 x 的函数
function drawX() {
  let i = 0;
  push();
  strokeWeight(2);
  stroke(35, 103, 246);
  line(i, 10 + i, 10 + i, i);
  line(i, i, 10 + i, 10 + i);
  pop();
}

四· 交互部分

其实就是切歌的部分,跟之前一篇案例【视觉系编程1—在p5js中用磁带播放周董的歌】

是一样的,特别好用,我又使用了这个效果

需要注意的是,会消散的文字的代码,虽然在set up里写过了,但是还需要在这里复制一下,不然年代就不会改变了!

function keyPressed() {

  if (key == 'A' || key == "a") play_song_ids = 1;
  else if (key == 'B' || key == "b") play_song_ids = 2;
  else if (key == 'C' || key == "c") play_song_ids = 3;
 
  firstSong();
  secondSong();
  thirdSong();

//把set up里的复制到这里来
  points = font1.textToPoints(play_year, 0, 0, 170, {
    sampleFactor: 10,
    simplifyThreshold: 0
  });
}

//3首歌,跟上一次几乎一样
function firstSong() {
  let result = false;
  if (play_song_ids == 1) {
    if (!sound.isPlaying()) {
      sound.play();
    }
    t = 1;
    bc = 60;
    i = 5;
    play_year = "2000"
    result = true;
  } else {
    sound.stop();
    result = false;
  }
  return result;
}

function secondSong() {
  let result = false;
  if (play_song_ids == 2) {
    if (!sound2.isPlaying()) {
      sound2.play();
    }
    t = 1;
    bc = 100;
    i = 5;
    play_year = "2001"
    result = true;
  } else {
    sound2.stop();
    result = false;
  }
  return result;
}

function thirdSong() {
  let result = false;
  if (play_song_ids == 3) {
    if (!sound3.isPlaying()) {
      sound3.play();
    }
    t = 1;
    bc = 180;
    i = 5;
    play_year = "2005"
    result = true;
  } else {
    result = false;
    sound3.stop();
  }
  return result;
}

这样就写完了~

按a,b,c一起回到过去吧hhh...(´・ω・`)

链接在这里:https://editor.p5js.org/nancy2721/present/-OIPl5-9a

时间是一个很有意思也很哲学的话题,大家可以以此为主题进行创作~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值