zoukankan      html  css  js  c++  java
  • 用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 );



  • 相关阅读:
    MVP模式与MVVM模式
    webpack的配置处理
    leetcode 287 Find the Duplicate Number
    leetcode 152 Maximum Product Subarray
    leetcode 76 Minimum Window Substring
    感知器算法初探
    leetcode 179 Largest Number
    leetcode 33 Search in Rotated Sorted Array
    leetcode 334 Increasing Triplet Subsequence
    朴素贝叶斯分类器初探
  • 原文地址:https://www.cnblogs.com/litao229/p/2434300.html
Copyright © 2011-2022 走看看