人性化的绘画界面设计-屁民科普

写在前面:感觉对于这次的绘画系统,我和其他同学不同,他们比较专注于不同笔的效果的比较,我在这里是更专注于用户进行绘画时的交互体验,绘画的娱乐性和创新性体验较少。这里面的面板控件都是自己画的233.

设计思路

(1)由动态和交互,我想把第二次的作业结合进去,作为我这次大作业的UI开始界面。相当于将绘画系统,当作适合人们玩的小游戏的样式。
(2)根据老师上课讲的内容,忽然想到可以做成一个像素风的绘画形式。可以自己选择颜色,有颜色面板。
(3)在完成第(2)步以后,我在想要做点更有意思的东西,能够将自己的绘制完成的图画让他有某种效果。因为前几天下雪,所以想做一圣诞特别版。
(4)之前看同学做了有点萌的开关还有音乐可视化的下雪的季节,自己也想让界面变的更可爱一点,所以自己也尝试了一下这两种我比较喜欢的作品,放入我的绘画界面中。

创作步骤

绘制画布

首先,我要有一个网格作为画纸,相当于画布的界面。
部分代码:
声明部分:

int bar_num=5;//bar color num
float bar_length=width;//bar width and length
float box_length=bar_length/bar_num;//box length and width
PVector p[]=new PVector[1000];
float p_y[]=new float[1000];

在setup()当中初始化:

  for (int i=0;i<=1000-1;i++){p[i]=new PVector(box_length*i+box_length/2,box_length);}for (int i=0;i<=1000-1;i++){p_y[i]=p[i].y*i;}

绘制画布部分:

//set a canva
void drawcanva()
{for (int j=0;j<=1000-1;j++){ for (int i=0;i<=1000-1;i++){fill(255,255,255);stroke(157,170,173,30);rect(p[i].x,p_y[j],box_length,box_length);}}
}

效果:

绘制调色板

第二步就是要有调色板了,为了好看,我在调色板下画了一个半透明的矩形,生成调色板也非常简单,定好了画板板面的位置也就是选好了第一个格子的位置,定好了画板的大小,花瓣中的格子的宽度就和画布的格子大小一样。写一个循环,将所有的格子位置在setup中存储起来,将格子要填充的颜色也存储起来。格子的位置和填充的颜色都在数组中。
于是就形成了下面这种效果,值得一说的就是文字,我这里找了几种好看的文字,选定与主题最相符的格式就?了。

PFont myfont;//create font

setup()函数中选择了一种字体

 // Herculanum  HiraginoSans-W0 MarkerFelt-Thinmyfont=createFont("NanumBrush",20);//set fonttextFont(myfont);
 fill(0,0,0);//text colortextSize(20);text("Palette",35,22);//add context and pos

那我是怎么选择这种字体的呢,那字体有什么属性可以通过代码调节呢
可以参考:processing字体

核心部分:增加调色板交互效果

获取调色板的颜色

第三步:也是这里最核心的,就是点击调色板,获取调色板的颜色,再点击画布,在画布上显示我选择的颜色,并且绘制。
首先先说说怎么获取颜色,processing自带了获取颜色的函数,非常简单也非常方便。
当然这些要建立在点击事件当中,我在编写的时候,想过用什么样的交互方式会更加便于用户去选取颜色并且绘制,而且代码还比较容易编写。
那就选择不同的按键来代表不同的操作!
这里鼠标左键选取颜色,右键绘制,有点类似于blender的操作。
以下代码在mousePressed()中

if (mouseButton==LEFT){if (mo==0){ mo=1;}int imgC=get(mouseX,mouseY);//get rightnow posR=(imgC>>16)&0xFF;G=(imgC>>8)&0xFF;B=imgC&0xFF;}

特别的意外创新点
这里的rgb获取到了左键取到的颜色,而且这也带来一个特别方便的地方,也是在我编写之后发现的。因为画布是白色的,所以我如果画到了错误的地方,左键空白处,再右键错误的地方,就可以实现橡皮擦的功能,我觉得我这里是创新点!哈哈

将获取到的颜色绘制到调色板上鼠标点击的指定位置

我这里判断了mouseX mouseY所处的位置,以一个方格为范围,如果鼠标位于该方格内,则将这个方格用刚获取的颜色填充。
而这里面的难点在于哪里呢?
我如何保存方格所在的位置,来绘制方格。因为鼠标可能点击方格内部的任何区域,而我要保存的仅仅是方格的左上角点的坐标,至于方格的大小我们已经在setup的时候确定好了。
解决的方法是,首先做一步判断,鼠标点击的位置位于哪个方格内,那我返回该方格的坐标就好了。因为之前在绘制画布的时候,我们已经存储了所有格子的坐标,放在了p[]数组里。
那就直接暴力遍历,我们就能找到目标格子索引及坐标。
在右键操作中添加如下代码:其中fill()填充的颜色就是我们刚才获取到的颜色。

 if(mouseButton==RIGHT){noStroke();fill(R,G,B);int k=0;for(int i=0;i<=1000-1;i++){ for(int j=0;j<=1000-1;j++){if (mouseX>=p[i].x&&mouseX<=p[i].x+box_length&&mouseY>=p_y[j]&&mouseY<=p_y[j]+box_length&&k<=1000-1){rect(p[i].x,p_y[j],box_length,box_length);index_cx[k]=p[i].x;index_cy[k]=p_y[j];k=k+1;}}}}

尝试有点萌的开关挑战

我这里看了其他同学的博文,根据上面的提示自己编写了一下,但是对于刷新变成椭圆的那个地方并没有去实现。
我这里也为了配合整体效果,选择了半透明的样式,比较淡一点的颜色。

开关的绘制这里就不放了。
因为要每一帧都绘制,所以开关的动画要写在draw当中,开关的移动我没有用到鼠标的点击,这里是如果鼠标放置在这个圆形区域以内,则判定为要进行开关操作。

在on时的眨眼,在off时的眨眼

//OFF
void animation()
{for (int i=1;i<=80;i++){pushMatrix();translate(i,0);fill(255,255,255);//draw buttomellipse(25,width/5+10,25,25);fill(173,158,157,90);ellipse(25-5,width/5+10,8,3+7*abs(sin(second()*8)));ellipse(25+5,width/5+10,8,3+7*abs(sin(second()*8)));popMatrix();}
}
//ON
void animation1()
{for (int i=1;i<=80;i++){pushMatrix();translate(-i,0);fill(255,255,255);//draw buttomellipse(105,width/5+10,25,25);fill(173,158,157,90);ellipse(105-5,width/5+10,8,3+7*abs(sin(second()*8)));ellipse(105+5,width/5+10,8,3+7*abs(sin(second()*8)));popMatrix();}
}

因为是截图所以大小会有点问题,看上去怪怪得,实际上我这个开关有两种眨眼睛的方式,一种是完全闭上,然后睁开,另一种是半闭然后睁开。不论开关在左边还是在右边都有眨眼睛的效果,有点呼吸的活的感觉。

 //switch animation OFF wink eyesif ((mouseX-25)*(mouseX-25)+(mouseY-width/5-10)*(mouseY-width/5-10)<=25*25&&tag==0){animation();tag=1;//  changeclr();}// move();//switch animation ON wink eyesif ((mouseX-105)*(mouseX-105)+(mouseY-width/5-10)*(mouseY-width/5-10)<=25*25&&tag==1){animation1();clearcanva();tag=0;// move();}

添加开关操作

这里我刚开始编写的时候,一直都没太想好让我的图像有什么样子的动态的效果,后来想到了要加入音乐,于是我就增加了透明度和下雪的效果。

因此在此之前先说说音乐可视化

音乐可视化

做一个类似于cd的播放器,网上有很多音乐可视化的例子,我想做成的效果图,和我实际做出来的还是有差距的。
想做个这个,结果做成了另外一种样子233

import processing.sound.*;
float ampvalue=0;//this will be our height's parameter
float lucency;
SoundFile file;
AudioIn in; //   AudioIn let's you grab the audio input from your soundcard
Amplitude amp;// anaylis the sounds

在文件夹下建立一个data文件,将音频放入。
在网易云上2块钱买的音乐有8分钟,是mp4格式,有几百兆,因为文件太大了,所以无法导入,一直报错,一开始不知道是因为音频文件过大的原因,后来我用苹果的iTunes按照网上的步骤截取了一部分,就能读取了,并且查阅了processing官方文档,发现wav格式的音频格式加载会更快,于是转换了格式。这里为road.wav
苹果剪辑音乐并保存为其他格式方法:
https://jingyan.baidu.com/album/ce4366494223ff3773afd391.html?picindex=5
初始化:

  //cd playerfile = new SoundFile(this, "road.wav");//file pathin = new AudioIn(this,0); //   Starts the input streamamp = new Amplitude(this); in.start();  //   Starts the input streamamp.input(in);  //  Defines the audio input source of the amplitude analyzefor (int i=0;i<=120-1;i++){cd_angle=cd_angle+3;cd_bar[i]=new PVector(cd_x+(cd_r-65)*cos(PI*cd_angle/180),cd_y+(cd_r-65 )*sin(PI*cd_angle/180));}

我将cd周围画出细小的竖线,他可以根据声卡中音量来调节自身的透明度值。
绘制竖线:

void drawstring()
{ampvalue = amp.analyze();//this value will be between 0~1strokeWeight(1);lucency = ampvalue*100000;stroke(255,226,229,lucency);
//  stroke(172,123,255,lucency);// stroke(172,123,255,90);cd_angle=0;for (int i=0;i<=120-1;i++){cd_angle=cd_angle+3;line(cd_bar[i].x,cd_bar[i].y,cd_bar[i].x+random(20)*noise(ampvalue*500)*cos(PI*cd_angle/180),cd_bar[i].y+random(20)*noise(ampvalue*500)*sin(PI*cd_angle/180));//line(cd_bar[i].x,cd_bar[i].y,cd_bar[i].x+10*noise(ampvalue*100)*cos(PI*cd_angle/180),cd_bar[i].y+ampvalue*100*sin(PI*cd_angle/180));// line(cd_bar[i].x,cd_bar[i].y,cd_bar[i].x+15*cos(PI*cd_angle/180),cd_bar[i].y+15*sin(PI*cd_angle/180));}
}
void playmusic()
{file.play();
}


另外值得一提的是,在processing帮助文档当中,有介绍音乐的播放,如果鼠标点击按钮,则音乐暂停,重新点击,则音乐会接着刚才暂停的地方继续播放。

开关开启之后增加效果

(1)添加雪花效果:
代码如下,雪花效果就非常简单了,其实我觉得这里面最麻烦的就是要进行判断,还有把代码放在哪个地方是符合我的想法的。
https://blog.csdn.net/qq_39097425/article/details/85016837

//when press OFF buttom get snow
void snowdown()
{int i=0;while (i<=snow_identity-1){noStroke();fill(255,211,235);ellipse(snow_x[i],snow_y[i],snow_r[i],snow_r[i]);snow_y[i]=snow_y[i]+snow_speed[i];if (snow_y[i]>=570)// if out of boundary{snow_y[i]=105;//get to the start edge}i=i+1;}
}

雪花效果: 什么都不添加,画布会呈现白色,并且有粉色的雪球效果

(2)改变填充色块的颜色
细心的朋友可能会注意到,我并不是把整张屏幕size全部作为我的画布,而是自己又框选了边界,重新设置了一下画布:

那我这样做的道理是什么呢?
因为我要获取用户绘制的点的位置,以及他们的颜色,所以我要找画布中颜色不为255的点。但这样有个问题,如果我的画布是全部界面,我在开始绘制的面板,cd,开关,他们都是有颜色的。这样会影响我的判断,所以我在这里选取了一块空白的区域。
接着对这个区域进行遍历:
寻找画布中颜色不是255的点,我这里寻找的点是位于格子中心位置,因为考虑到边界处会有画布的边界线,会影响颜色的判断。所以我这里选取的格子中心。
下面这个代码是遍历画布:

//collect the fill box index
//width 24 length 24
//150,100  630,580   box_length=20
//width*3/5+150,100+height*4/5
void searchfill()
{int index=0;for (int i=0;i<=1000-1;i++){for (int j=0;j<=1000-1;j++){ if ((p[i].x>150)&&(p[i].x<=630)&&(p_y[j]>=100)&&(p_y[j]<=570)){     temp_x=int(p[i].x+box_length/2);temp_y=int(p_y[j]+box_length/2);// println(temp_x,temp_y);temp_img=get(temp_x,temp_y);temp_R=(temp_img>>16)&0xFF;temp_G=(temp_img>>8)&0xFF;temp_B=temp_img&0xFF;if((temp_R!=255)&&(temp_G!=255)&&(temp_B!=255)&&index<=575){fillimg[index]=new PVector(temp_x-box_length/2,temp_y-box_length/2);R_tmp[index]=temp_R;G_tmp[index]=temp_G;B_tmp[index]=temp_B;index=index+1;}}}}
}
//change the fill image color through the music
void changeclr()
{fill(255,255,255);rect(150,100,width*3/5,height*4/5);ampvalue = amp.analyze();//this value will be between 0~1lucency = ampvalue*100000;for (int k=0;k<=575;k++){    fill(R_tmp[k],G_tmp[k],B_tmp[k],lucency);rect(fillimg[k].x,fillimg[k].y,box_length,box_length);}   }

最后结合我之前做的ui界面

我在这之后还做了改动,让他有景深的效果:
前面深颜色的树移动的速度快,后面浅颜色的因为距离远,所以要稍微小一些,移动的速度我也调节到了最慢。
下面其实是路但是很多人都说这个看起来像云,这些是由四个椭圆组成的。想要做出来的效果就是一直往前奔跑的感觉。
在做界面跳转的时候,有点懵,因为我一开始把画布,paintUI中要用东西都写到了setup中,setup只能显示一次,所以不知道要怎么实现跳转。后来把绘制的部分单独拿出来,写个函数。
这是看了这个例子后才后知后觉。
开始界面的UI绘制:

void startUI()
{background(238,239,255);noStroke();draw_tree();draw_leaf();draw_leaves();draw_hill();draw_road();draw_wind();fill(#E3E3E3);textAlign(CENTER);textSize(44);fill(#EE6AA7);// fill( 255,255,255);text("START",0.5*width,height-50);//add context and pos
}

draw()界面跳转的标签设置,以及更新动画眨眼睛,更新cd中的string等主要操作。

void draw()
{//the start UIif (mo==0){startUI(); //switch buttom// tag=0 OFF }if(mo==1){ paintUI();mo=2;}if (mo==2){  if(tag==0){ fill(255,255,255);//draw buttomellipse(25,width/5+10,25,25);fill(173,158,157,90);ellipse(25-5,width/5+10,8,3+7*abs(sin(second()*8)));ellipse(25+5,width/5+10,8,3+7*abs(sin(second()*8)));searchfill();}//tag=1 ONif(tag==1){ fill(255,255,255);//draw buttomellipse(105,width/5+10,25,25);fill(173,158,157,90);ellipse(105-5,width/5+10,8,3+7*abs(sin(second()*8)));ellipse(105+5,width/5+10,8,3+7*abs(sin(second()*8)));changeclr();snowdown();}//switch animation OFF wink eyesif ((mouseX-25)*(mouseX-25)+(mouseY-width/5-10)*(mouseY-width/5-10)<=25*25&&tag==0){animation();tag=1;//  changeclr();}// move();//switch animation ON wink eyesif ((mouseX-105)*(mouseX-105)+(mouseY-width/5-10)*(mouseY-width/5-10)<=25*25&&tag==1){animation1();clearcanva();tag=0;// move();}  drawcdall();/* for (int i=0;i<=3;i++){println(fillimg[i].x,fillimg[i].y);}*/ }
}

绘图部分的效果展示

我画了几张丑图,给你们看看~


看一下效果动图:
没有音乐就非常可惜了,配合着音乐在这样的氛围中,绘制属于你自己的图画,岂不是一件美事233
![在这里插入图片描述](https://img-blog.csdnimg.cn/2018123012362385.gif

人性化的绘画界面设计-屁民科普相关推荐

  1. processing实现动态和交互-屁民科普

    processing实现动态和交互-屁民科普 先来说说手绘和码绘的区别 手绘作品:很久之前画的了(我大索隆 手绘与码绘技法的比较 手绘:先绘制出大体的轮廓草稿,然后再细致的绘制,如果在绘画的时候 码绘 ...

  2. UI设计/GUI开发-入门界面设计

    概述 从几个概念谈起,GUI(图形用户界面).UI开发.前端.Web开发,这些个耳熟的词语,是否想过它们正真的含义!一款使用体验极好的软件,好看.好用,必然不是凭空想出来的,而是有理论依据.多方配合设 ...

  3. 对WEB前端的几段思考(一)——界面设计和性能优化(整理中)

    尽管我并非艺术出生,既没有任何设计基础,又没有较高艺术涵养,也深谙在短时间内创造一定艺术造诣并非易事,但是既然当初选择从事网站前端开发,我的目光不能仅停留在前端代码上.作为一名志向在前端领域发展的人员 ...

  4. 软件工程结对作业 四则运算界面设计

    软件工程结对作业 四则运算器界面设计 康鑫  PB16060203 娄雨禛  PB16060356 项目内容链接:http://www.cnblogs.com/silent-zlv/p/8684979 ...

  5. 人机交互界面设计大作业_为什么说大多数UI设计、大数据、人工智能等培训班不靠谱?...

    搜索框中输入UI设计.大数据.人工智能等字,排在最前面的往往是培训班广告,各类网页中更是层出不穷,我要说的是这玩意不靠谱,你说你培训个Javaphthon等还说得过去,这些刚开设不久的新兴热门专业你就 ...

  6. 游戏UI界面设计视频教程全套

    库(UI插画漫画开发建模美术教程大全) 2014-11-28 16:54:21 1.全面系统(从基础到进阶,涵盖所有细节,特别是没有受过特别专业培训的亲们,更加需要) 2.有序排列(按照教程属性与绘画 ...

  7. 【Qt设计开发】GUI界面设计开发

    文章目录 一.Qt简介和下载安装 二.Qt入门 2.1 创建第一个项目 2.2 快捷键和命名规范 2.3 Qt项目和VS2022项目相互转换 三.Qt基础 3.1 Qt对象树和窗口坐标系概念 3.2 ...

  8. 浅析网站 APP 登录界面设计

    无论网页或是移动APP的设计,很重要的一点是如何能在小而美和功能复杂性之间找到平衡点.本文就移动APP表单设计进行浅析,看设计师是如何在设计与交互体验之间做到小而美的平衡. 一.极致的减法 这是一个异 ...

  9. UI界面设计八大原则

    很多人说自己设计不好UI界面,其实很多时候不是你学习的技术不到位,内里存的东西不够多,而是你不清楚做UI设计的内里原则,规则.只有在规则下创新,才会规整又有趣,整体也能给人好的感受.今天阿多比设计学院 ...

  10. ui界面颜色设计_界面设计ui的颜色基础

    ui界面颜色设计 重点 (Top highlight) Color is a sensory impression that the eyes perceive from the light, tra ...

最新文章

  1. Web应用开发技术(3)-html
  2. 测试人员提高业务掌握度的方案
  3. oracle存储过程中update不成功的一个原因
  4. Android 可以输入的下拉框
  5. and/or(||)的理解
  6. 这个时代,开发简单多了
  7. c语言小程序跑马灯,小程序横向跑马灯效果(3种方式)
  8. linux编译so库
  9. 几种图片去水印方法的效果对比
  10. 【Python】TX云服务器下CentOS+Python3+Nginx+uwsgi+Bottle搭建Web服务
  11. hashcat破解WiFi显示No hashes loaded的解决方法
  12. 程序员小说 Out Of Memory (三)
  13. 去处word红色波浪线
  14. 植树节种树-第12届蓝桥杯Scratch选拔赛真题精选
  15. 如何及时汇报反馈工作
  16. pytorch自学教程(一)
  17. pathlib.Path模块下的glob、rglob,glob模块下的glob、iglob
  18. win7自带的便笺桌面工具快捷键.
  19. SpringBoot JAVA 动态设置定时任务执行时间
  20. Spring之底层架构核心概念解析

热门文章

  1. TX2--Building OpenCV for Tegra with CUDA
  2. 基于EPON+EOC技术构建广电综合业务宽带接入网
  3. 【网络流24题】火星探险问题 题解
  4. Best Android Remote Desktop Apps?
  5. 查看linux下eclipse进程,Linux环境安装Eclipse工具开发
  6. 【云速建站】域名配置指导
  7. POJ 1129 Channel Allocation(四色定理)
  8. 微信支付服务器sdk升级,微信支付接口上手指引附微信SDK更新说明.PDF
  9. 微软拼音 快捷输入 自定义格式的时间和日期
  10. IBM识别癌变细胞技术取得重大突破,用深度学习与神经网络重塑病理学