• 用canvas 来实现一个菊花


    关于canvas的save()和restore(),前面一直以为canvas的画面也会保存,然后restore后把画面恢复,那么就这样把自己给绕进去了,那么save和restore之间的操作还有何意义???  

    摸爬滚打后理解了save 保存的是画布的坐标旋转缩放 以及fillstyle 和 其他等等的相关属性,已经画好了的图画不在之列。

    做了个菊花 和 前面做的图片旋转移动 的 demo 来巩固下。

    依然先看效果


    ---------------------代码分割线-----------------------------------------------------------------------------------------

      1 var $=function(id){
    2
    3 return document.getElementById(id);
    4
    5 }
    6
    7 var isinit=false;
    8
    9 /** Canvas 类
    10
    11 *
    12
    13 * @param {Object} height
    14
    15 */
    16
    17 var g_loadings = [];
    18
    19 function Canvas(height, con){
    20
    21 if (height == null) {
    22
    23 height = 24;
    24
    25 }
    26
    27 this.obj = document.createElement("canvas");
    28
    29 var width = height;
    30
    31 if(con != null){
    32
    33 width += 82;
    34
    35 }
    36
    37 this.obj.setAttribute("width", width+500);
    38
    39 this.obj.setAttribute("height", height+500);
    40
    41 this.height = height;
    42
    43 this.ctx = this.obj.getContext("2d");
    44
    45 // RGB
    46
    47 this.color = [51, 51, 51];
    48
    49 var fsize = "14px";
    50
    51 if(height>24){
    52
    53 fsize = "16px";
    54
    55 }
    56
    57 this.ctx.save();
    58
    59 this.ctx.fillStyle = "#646464";
    60
    61 this.ctx.font = fsize+" \"Microsoft YaHei\",Helvetica";
    62
    63 this.ctx.textBaseline = "middle";
    64
    65 this.ctx.fillText(con, height+5, height/2);
    66
    67 this.ctx.restore();
    68
    69 }
    70
    71 // 记录转动的度数,分8步
    72
    73 Canvas.prototype.rotation = 0;
    74
    75 // 每隔125ms会调用一次,绘制一个loading圆
    76
    77 Canvas.prototype.draw = function(){
    78
    79 var h = this.height, ctx = this.ctx, c = h / 16, d = h / 5, degree = -Math.PI * 2 / 10;
    80
    81
    82
    83 //ctx.save();
    84
    85 // clearRect(x,y,width,height) : Clears the specified area and makes it fully transparent
    86
    87 ctx.clearRect(-200, -200, 500, 500);
    88
    89
    90
    91 // 移到中点
    92
    93 if (!isinit){
    94
    95 ctx.translate(h / 2, h / 2);
    96
    97 isinit=true;
    98
    99 }
    100
    101
    102
    103
    104
    105
    106
    107 // 把一个圆分成8段,分别绘制
    108
    109 for (var i = 0; i < 10; i++) {
    110
    111
    112
    113 ctx.save();
    114
    115 // 旋转一段的度数
    116
    117 ctx.rotate(i * degree);
    118
    119 // 根据旋转的角度设置颜色与透明度,eg:
    120
    121 // rotation=0 的时候, alpha的值 1, 0.875 ... 0.125
    122
    123 // rotation=1 的时候, alpha的值 0.875, 0.75 ... 1
    124
    125 ctx.fillStyle = "rgba(" + this.color[0] + "," + this.color[1] + "," + this.color[2] + "," + (10 - (i + this.rotation) % 10) / 10 + ")";
    126
    127 // 绘制 fillRect(x,y,width,height) : Draws a filled rectangle
    128
    129 ctx.fillRect(-c / 2, d, c, d);
    130
    131 ctx.restore();
    132
    133 }
    134
    135 //ctx.restore();
    136
    137
    138
    139 this.rotation++;
    140
    141 this.rotation %= 10;
    142
    143 var load_canvas=this;
    144
    145 load_canvas.running = window.setTimeout(function(){load_canvas.draw();load_canvas=null;}, 100); // 由于分成10段,所以时间为100ms
    146
    147 };
    148
    149
    150
    151 /**
    152
    153 * 创建Canvas
    154
    155 *
    156
    157 * @param {Object} parent 父节点,之前必须要至少一个子节点存在
    158
    159 * 如 <a ><span>取消</span></a>
    160
    161 * @param {Object} height 长/高
    162
    163 */
    164
    165 function initCanvas(parent, height, con){
    166
    167 // 如果是有子节点,说明需要做 loading 动画
    168
    169 if (parent && parent.firstChild && parent.firstChild.id != "sp") {
    170
    171 // 创建 Canvas
    172
    173 var canvas = new Canvas(height, con);
    174
    175 canvas.obj.id = "sp";
    176
    177 // 放进数组
    178
    179 g_loadings.push(canvas);
    180
    181 parent.insertBefore(canvas.obj, parent.firstChild);
    182
    183 if (!canvas.running) {
    184
    185
    186
    187 canvas.draw();
    188
    189 }
    190
    191 }
    192
    193 }
    194
    195
    196
    197 /**
    198
    199 * 删除 Canvas
    200
    201 * @param {Object} parent 父节点
    202
    203 * @param 返回 1 说明成功删除了一个正在loading状态的canvas
    204
    205 */
    206
    207 function removeCanvas(parent){
    208
    209 if (parent && parent.firstChild && parent.firstChild.id == "sp") {
    210
    211 // loop整个数组中的 canvas
    212
    213 for (var i = g_loadings.length; --i >= 0;) {
    214
    215 var canvas = g_loadings[i];
    216
    217 if (canvas.obj == parent.firstChild) {
    218
    219 //从 Dom 移除
    220
    221 parent.removeChild(parent.firstChild);
    222
    223 // remove interval
    224
    225 window.clearInterval(canvas.running);
    226
    227 canvas.running = null;
    228
    229 // 去掉
    230
    231 g_loadings.splice(i, 1);
    232
    233 return 1;
    234
    235 }
    236
    237 }
    238
    239 }
    240
    241 return 0;
    242
    243 }
    244
    245 function getOuterHeight(obj){
    246
    247 var mtop = obj.style.marginTop;
    248
    249 if(mtop==""){
    250
    251 mtop = 0;
    252
    253 }
    254
    255 var mbottom = obj.style.marginBottom;
    256
    257 if(mbottom==""){
    258
    259 mbottom = 0;
    260
    261 }
    262
    263 return obj.offsetHeight+parseInt(mtop)+parseInt(mbottom);
    264
    265 }
    266
    267 /**
    268
    269 * 页面统一 loading
    270
    271 * @param btnObj 如果有,则只给这个按钮加,否则整个页面
    272
    273 */
    274
    275 function loading(btnObj, height, con){
    276
    277
    278
    279 if(con == null){
    280
    281 con = "正在载入...";
    282
    283 }
    284
    285 if(btnObj){
    286
    287 if(height == null){
    288
    289 height = 24;
    290
    291 }
    292
    293 //给按钮加上loading
    294
    295 btnObj.setAttribute("selected", "progress");
    296
    297 btnObj.style.display = "block";
    298
    299 try{
    300
    301 initCanvas(btnObj, height, con);
    302
    303 }catch(ex){}
    304
    305 }else{
    306
    307 if(height == null){
    308
    309 height = 32;
    310
    311 }
    312
    313 //全局的
    314
    315 if(!$("preloader")){
    316
    317 var oDiv = document.createElement("div");
    318
    319 oDiv.id = "preloader";
    320
    321 oDiv.style.textAlign = "center";
    322
    323 //oDiv.style.position = "relative";
    324
    325 var oSpan = document.createElement("span");
    326
    327 oDiv.appendChild(oSpan);
    328
    329 document.getElementsByTagName("body")[0].appendChild(oDiv);
    330
    331 }
    332
    333 var overlay = $("preloader");
    334
    335 //var oHeight = getOuterHeight(overlay);
    336
    337 //定位到中间
    338
    339 //var top = parseInt(Math.max((getClientHeight() - oHeight) / 2, 0) + getScrollTop());
    340
    341 //overlay.style.top = (top-height)+"px";
    342
    343 overlay.style.marginTop = "150px";
    344
    345 overlay.style.display = "block";
    346
    347 try{
    348
    349 initCanvas(overlay, height, con);
    350
    351 }catch(ex){}
    352
    353 }
    354
    355 }
    356
    357
    358
    359 /**
    360
    361 * 停止页面统一loading
    362
    363 * @param btnObj 如果有,则只给这个按钮,否则整个页面
    364
    365 * @return 1/0 如果返回1说明已经有对应的实例在loading状态,此时要根据情况判断是否继续
    366
    367 */
    368
    369 function unloading(btnObj){
    370
    371 var result = 0;
    372
    373 if(btnObj){
    374
    375 //给按钮加上loading
    376
    377 result = removeCanvas(btnObj);
    378
    379 btnObj.removeAttribute("selected");
    380
    381 btnObj.style.display = "none";
    382
    383 return result;
    384
    385 }else{
    386
    387 //全局的
    388
    389 var overlay = $("preloader");
    390
    391 result = removeCanvas(overlay);
    392
    393 overlay.style.display = "none";
    394
    395 overlay.style.marginTop = "";
    396
    397 return result;
    398
    399 }
    400
    401 }
    402
    403
    404
    405 loading(null , 110 );



  • 相关阅读:
    [java] 怎么去掉小数点后面不需要的0
    [SoapUI] 在SoapUI script里获取Response(Json格式)某个节点值
    nacos启动不停打印日志[com.alibaba.nacos.client.naming.updater] INFO com.alibaba.nacos.client.naming:192
    sppringcloud应用启动 访问gateway无法path无法路由到目标应用,404
    springcloud项目启动gateway报错org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found
    nacos 01
    微服务spring-cloud day2
    springcloud本地启动指定profile后错误If you are using the git profile, you need to set a Git URI in your configuration.
    微服务spring-cloud day1
    金融云部署sofaboot应用指定了项目路径健康检查无法通过,windows格式/unix格式/mac格式的坑
  • 原文地址:https://www.cnblogs.com/litao229/p/2434300.html
Copyright © 2020-2023  润新知