最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create a WoW-like cooldown effect? - Stack Overflow

programmeradmin3浏览0评论

I am currently trying to make a cooldown effect similar to the ones you can see in World of Warcraft. (See the square with the 2m text on it? The idea is to have the square ''lighten'' in a circular manner, also illustrated in at 0:23.). I am using GWT, so I am mainly looking for a means to do this using pure CSS and/or javascript.

To achieve this, I only need to be able to create a square image similar to the dark area in 1. I could then apply this image in overlay to my main image, and use a timer to make the illusion of mouvement.

However I am at a loss as to how to create such an image. It seems possible to create shapes using CSS only, but I could not understand if, and how, creating what I needed was possible.

I also found something that uses Silverlight, but it is not an option for me.

I am not sure I have expressed my need clearly enough. If that were the case, I'd be more than happy to add clarifications.

Thanks in advance for any hint,
Sébastien Tromp

I am currently trying to make a cooldown effect similar to the ones you can see in World of Warcraft. (See the square with the 2m text on it? The idea is to have the square ''lighten'' in a circular manner, also illustrated in http://www.youtube./watch?v=R51QXmkyelQ at 0:23.). I am using GWT, so I am mainly looking for a means to do this using pure CSS and/or javascript.

To achieve this, I only need to be able to create a square image similar to the dark area in 1. I could then apply this image in overlay to my main image, and use a timer to make the illusion of mouvement.

However I am at a loss as to how to create such an image. It seems possible to create shapes using CSS only, but I could not understand if, and how, creating what I needed was possible.

I also found something that uses Silverlight, but it is not an option for me.

I am not sure I have expressed my need clearly enough. If that were the case, I'd be more than happy to add clarifications.

Thanks in advance for any hint,
Sébastien Tromp

Share Improve this question edited Aug 12, 2011 at 18:47 L84 46.3k59 gold badges181 silver badges259 bronze badges asked Aug 12, 2011 at 16:49 Sébastien TrompSébastien Tromp 6121 gold badge16 silver badges30 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6

This is what I came up with. Basically what it does is, it encapsulates an image and a 0.5 opacity canvas on top of each other in a posite widget. The animation draws lines on the canvas from the center towards the edges in a circular fashion in a given time interval. Canvas has a clickHandler to start the animation. Hope it helps. It uses GWT Canvas so this widget may not be supported on all browsers.

Class CoolDownAnimation :

    public class CoolDownAnimation extends Animation {

    Canvas canvas;
    Context2d context;
    int centerX;
    int centerY;
    static final CssColor BLACK = CssColor.make("rgba(0,0,0,0.6)");
    static final CssColor WHITE = CssColor.make("rgba(255,255,255,0.6)");

    public CoolDownAnimation(Canvas canvas) {
        this.canvas = canvas;
        canvas.setCoordinateSpaceHeight(20);
        canvas.setCoordinateSpaceWidth(20);
        canvas.getElement().getStyle().setOpacity(0.5);
        this.context = canvas.getContext2d();
        centerX = canvas.getCoordinateSpaceWidth() / 2;
        centerY = canvas.getCoordinateSpaceHeight() / 2;
    }
    @Override
    protected void onStart() {
        context.beginPath();
        context.setStrokeStyle(BLACK);
        context.fillRect(0, 0, centerX * 2, centerY * 2);
        context.setStrokeStyle(WHITE);
        super.onStart();
    }
    @Override
    protected void onUpdate(double progress) {
        context.moveTo(centerX, centerY);
        context.lineTo(
                centerX + 2 * centerX * Math.cos((progress * Math.PI * 2)-Math.PI/2),
                centerY + 2 * centerY * Math.sin((progress * Math.PI * 2)-Math.PI/2));
        context.stroke();
    }   
    @Override
    protected void onComplete() {
        super.onComplete();
        context.closePath();
        context.clearRect(0, 0, centerX*2, centerY*2);
    }
}

Class CoolDownWidget :

    public class CoolDownWidget extends Composite {

    private CoolDownAnimation coolDown;
    private AbsolutePanel wrapper;
    private Image image;
    private Canvas canvas;
    private int sizeX = 50;
    private int sizeY = 50;
    private int coolDownDuration = 5000;

    public CoolDownWidget(){
        canvas = Canvas.createIfSupported();
        if (canvas==null){
            Window.alert("Fail! You dont have canvas support");
        }
        canvas.getElement().getStyle().setOpacity(0.5);
        canvas.setPixelSize(sizeX,sizeY);
        coolDown = new CoolDownAnimation(canvas);
        image = new Image("images/icon.png");
        image.setPixelSize(sizeX, sizeY);
        canvas.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                coolDown.cancel();
                coolDown.run(coolDownDuration);
            }
        });
        wrapper = new AbsolutePanel();
        wrapper.setPixelSize(sizeX, sizeY);
        wrapper.add(image, 0, 0);
        wrapper.add(canvas,0,0);
        initWidget(wrapper);
    }
}

finally onModuleLoad to wrap things up :

    public void onModuleLoad() {
    RootPanel.get().add(new CoolDownWidget());
}

This is a javascript/css version that uses jquery.

Find the live version http://codepen.io/anon/pen/aZzNbY.

    <html>
      <head>
          <script src="https://code.jquery./jquery-2.2.4.min.js"></script>
          <style type="text/css">
            .box{
                width:128px;
                height:128px;
                background-color:black;
                overflow:hidden;
                padding:5px;
                border:4px solid #ddd;
                border-radius:12px;
                position:relative;
            }

            input[type="submit"] {
                width: 100%;
                height: 100%;
                border: 0;
                background: url('http://icons.iconseeker./png/fullsize/smoothicons-12/warcraft-1.png') no-repeat ;
            }

            .cooldown{
                position:absolute;
                top:5%;
                left:5%;
                width:90%;
                height:90%;
                overflow:hidden;
                opacity:0;
            }   

            .cooldown-half{
                width:50%;
                height:100%;
                overflow:hidden;
                position:relative;
                float:left;
            }

            .cooldown-half-rotator{
                width:200%;
                height:200%;
                top:-50%;
                position:absolute;
                background-color:rgba(1,1,1,0.5);
            }

            .cooldown-half-rotator-right{
                transform-origin:left center;
            }

            .cooldown-half-rotator-left{
                right:0;
                transform-origin:right center;
            }


          </style>
      </head>
      <body>
          <div class='box'>
              <input   type="submit" value="" ><div></div></input>
              <div class='cooldown'>

                  <div class='cooldown-half'>
                      <div class='cooldown-half-rotator cooldown-half-rotator-left'>
                      </div>                         
                  </div>            
                  <div class='cooldown-half'>
                      <div class='cooldown-half-rotator cooldown-half-rotator-right'>           
                      </div>                              
                  </div>            

              </div>
          </div>
          Click me

          <script>
              function setCooldown( time, stopper ){
                    $(".cooldown").css({"opacity":1});
                        $(".cooldown-half-rotator-right").css({
                            "transform":"rotate(180deg)",
                            "transition":"transform "+(time/2000)+"s",
                            "transition-timing-function":"linear"
                        });
                        setTimeout( function(){
                            $(".cooldown-half-rotator-left").css({
                                "transform":"rotate(180deg)",
                                "transition":"transform "+(time/2000)+"s",
                                "transition-timing-function":"linear"
                            });
                            setTimeout( function(){
                                $(".cooldown-half-rotator-right").css({"transform":"rotate(0deg)","transition":"transform 0s"});
                                $(".cooldown-half-rotator-left").css({"transform":"rotate(0deg)","transition":"transform 0s"});
                                $(".cooldown").css({"opacity":0});
                            }, time/2 );
                        }, time/2 );
              }
              window.onload = function(){
                  $(".box").click(function(){                        
                      setCooldown( 3000 );
                  });
              }
          </script>
      </body>
    </html>

you could use Jquery rotate

Look at example 3

Alternatively: you could divide the square into little pie-slices (a bit hard to see, but like this pizza). Make a transparant image for each one, and just show/hide them in order one by one using jquery. This is probably the easiest and fastest solution.

Another variation on the solution proposed by pistolPanties for the onUpdate() method:

this.context.clearRect(0, 0, this.width, this.height);

// Black background
this.context.setFillStyle(BLACK);
this.context.fillRect(0, 0, this.width, this.height);

// White to show the progress
this.context.setFillStyle(WHITE);
this.context.beginPath();
this.context.moveTo(this.centerX, this.centerY);
this.context.arc(this.centerX, this.centerY, this.width, -Math.PI / 2, 2 * Math.PI * progress - Math.PI / 2, false);
this.context.lineTo(this.centerX, this.centerY);
this.context.fill();
this.context.closePath();

The advantage it has is that it delimitates the full portion to render as White, and fills it. This ensures that the area is always properly colored - and thus more resilient to browser slow downs.

发布评论

评论列表(0)

  1. 暂无评论