怎么设置canvas动画为背景

怎么设置canvas动画为背景,第1张

使用HTML5画布canvas能够快速实现简单的动画效果,基本原理如下:每隔一定时间绘制图形并且清除图形,用来模拟出一个动画过程,可以使用context.clearRect(0, 0, x, y)方法来刷新需要绘制的图形首先是绘制图形的方法,如下:<pre t="code" l="java">function myAnimation() {

ctx.clearRect(0, 0, canvas_size_x, canvas_size_y)

if (x_icon <0 || x_icon >canvas_size_x - size_x) {

stepX = -stepX

}

if (y_icon <0 || y_icon >canvas_size_y - size_y) {

stepY = -stepY

}

x_icon += stepX

y_icon += stepY

ctx.drawImage(anim_img, x_icon, y_icon)

}以上方法每隔一定时间清除画布内容,并且重新计算绘制图形位置,一旦超过了画布大小,则反转坐标绘制图形。

1、首先,重写控件View,自定义一个展示gif图的GifView,代码如下:

package net.loonggg.gif.view

import net.loonggg.gif.R

import android.annotation.SuppressLint

import android.content.Context

import android.content.res.TypedArray

import android.graphics.Canvas

import android.graphics.Movie

import android.os.Build

import android.util.AttributeSet

import android.view.View

public class GifView extends View {

/**

* 默认为1秒

*/

private static final int DEFAULT_MOVIE_DURATION = 1000

private int mMovieResourceId

private Movie mMovie

private long mMovieStart

private int mCurrentAnimationTime = 0

private float mLeft

private float mTop

private float mScale

private int mMeasuredMovieWidth

private int mMeasuredMovieHeight

private boolean mVisible = true

private volatile boolean mPaused = false

public GifView(Context context) {

this(context, null)

}

public GifView(Context context, AttributeSet attrs) {

this(context, attrs, R.styleable.CustomTheme_gifViewStyle)

}

public GifView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle)

setViewAttributes(context, attrs, defStyle)

}

@SuppressLint("NewApi")

private void setViewAttributes(Context context, AttributeSet attrs,

int defStyle) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

setLayerType(View.LAYER_TYPE_SOFTWARE, null)

}

// 从描述文件中读出gif的值,创建出Movie实例

final TypedArray array = context.obtainStyledAttributes(attrs,

R.styleable.GifView, defStyle, R.style.Widget_GifView)

mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -1)

mPaused = array.getBoolean(R.styleable.GifView_paused, false)

array.recycle()

if (mMovieResourceId != -1) {

mMovie = Movie.decodeStream(getResources().openRawResource(

mMovieResourceId))

}

}

/**

* 设置gif图资源

*

* @param movieResId

*/

public void setMovieResource(int movieResId) {

this.mMovieResourceId = movieResId

mMovie = Movie.decodeStream(getResources().openRawResource(

mMovieResourceId))

requestLayout()

}

public void setMovie(Movie movie) {

this.mMovie = movie

requestLayout()

}

public Movie getMovie() {

return mMovie

}

public void setMovieTime(int time) {

mCurrentAnimationTime = time

invalidate()

}

/**

* 设置暂停

*

* @param paused

*/

public void setPaused(boolean paused) {

this.mPaused = paused

if (!paused) {

mMovieStart = android.os.SystemClock.uptimeMillis()

- mCurrentAnimationTime

}

invalidate()

}

/**

* 判断gif图是否停止了

*

* @return

*/

public boolean isPaused() {

return this.mPaused

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

if (mMovie != null) {

int movieWidth = mMovie.width()

int movieHeight = mMovie.height()

int maximumWidth = MeasureSpec.getSize(widthMeasureSpec)

float scaleW = (float) movieWidth / (float) maximumWidth

mScale = 1f / scaleW

mMeasuredMovieWidth = maximumWidth

mMeasuredMovieHeight = (int) (movieHeight * mScale)

setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight)

} else {

setMeasuredDimension(getSuggestedMinimumWidth(),

getSuggestedMinimumHeight())

}

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b)

mLeft = (getWidth() - mMeasuredMovieWidth) / 2f

mTop = (getHeight() - mMeasuredMovieHeight) / 2f

mVisible = getVisibility() == View.VISIBLE

}

@Override

protected void onDraw(Canvas canvas) {

if (mMovie != null) {

if (!mPaused) {

updateAnimationTime()

drawMovieFrame(canvas)

invalidateView()

} else {

drawMovieFrame(canvas)

}

}

}

@SuppressLint("NewApi")

private void invalidateView() {

if (mVisible) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {

postInvalidateOnAnimation()

} else {

invalidate()

}

}

}

private void updateAnimationTime() {

long now = android.os.SystemClock.uptimeMillis()

// 如果第一帧,记录起始时间

if (mMovieStart == 0) {

mMovieStart = now

}

// 取出动画的时长

int dur = mMovie.duration()

if (dur == 0) {

dur = DEFAULT_MOVIE_DURATION

}

// 算出需要显示第几帧

mCurrentAnimationTime = (int) ((now - mMovieStart) % dur)

}

private void drawMovieFrame(Canvas canvas) {

// 设置要显示的帧,绘制即可

mMovie.setTime(mCurrentAnimationTime)

canvas.save(Canvas.MATRIX_SAVE_FLAG)

canvas.scale(mScale, mScale)

mMovie.draw(canvas, mLeft / mScale, mTop / mScale)

canvas.restore()

}

@SuppressLint("NewApi")

@Override

public void onScreenStateChanged(int screenState) {

super.onScreenStateChanged(screenState)

mVisible = screenState == SCREEN_STATE_ON

invalidateView()

}

@SuppressLint("NewApi")

@Override

protected void onVisibilityChanged(View changedView, int visibility) {

super.onVisibilityChanged(changedView, visibility)

mVisible = visibility == View.VISIBLE

invalidateView()

}

@Override

protected void onWindowVisibilityChanged(int visibility) {

super.onWindowVisibilityChanged(visibility)

mVisible = visibility == View.VISIBLE

invalidateView()

}

}

Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图像。通过当前时间与duration之间的换算关系,是很容易实现GIF动起来的效果。

其次,在xml布局文件中,把这个view定义进去,代码如下:

[html] view plain copy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<net.loonggg.gif.view.GifView

android:id="@+id/gif1"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_gravity="center_horizontal"

android:enabled="false" />

<net.loonggg.gif.view.GifView

android:id="@+id/gif2"

android:layout_width="200dp"

android:layout_height="200dp"

android:layout_gravity="center_horizontal"

android:enabled="false" />

</LinearLayout>

2、最后,在MainActivity中的使用,代码如下:

package net.loonggg.gif

import net.loonggg.gif.view.GifView

import android.app.Activity

import android.os.Bundle

public class Gif extends Activity {

private GifView gif1, gif2

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.main)

gif1 = (GifView) findViewById(R.id.gif1)

// 设置背景gif图片资源

gif1.setMovieResource(R.raw.kitty)

gif2 = (GifView) findViewById(R.id.gif2)

gif2.setMovieResource(R.raw.b)

// 设置暂停

// gif2.setPaused(true)

}

}

html5 canvas首屏自适应背景动画循环效果的插入方法:

1、demo.html代码如下:

<html lang="en" class="no-js"><head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>html5 canvas首屏自适应背景动画循环效果代码</title>

<link rel="stylesheet" type="text/css" href="css/normalize.css">

<link rel="stylesheet" type="text/css" href="css/demo.css">

<!--必要样式-->

<link rel="stylesheet" type="text/css" href="css/component.css">

<!--[if IE]>

<script src="js/html5.js"></script>

<![endif]-->

</head>

<body>

<div class="container demo-1">

<div class="content">

<div id="large-header" class="large-header" style="height: 185px">

<canvas id="demo-canvas" width="1304" height="185"></canvas>

<h1 class="main-title">Connect <span class="thin">Three</span></h1>

</div>

<nav class="codrops-demos">

<a class="current-demo" href="index.html">Demo 1</a>

</nav>

</div>

</div><!-- /container -->

<script src="js/TweenLite.min.js"></script>

<script src="js/EasePack.min.js"></script>

<script src="js/rAF.js"></script>

<script src="js/demo-1.js"></script>

<div class="sogoutip" style="z-index: 2147483645visibility: hiddendisplay: none"></div><div class="sogoubottom" id="sougou_bottom" style="display: none"></div><div id="ext_stophi" style="z-index: 2147483647"><div class="extnoticebg"></div><div class="extnotice"><h2>关闭提示 <a href="#" title="关闭提示" id="closenotice" class="closenotice">关闭</a></h2><p id="sogouconfirmtxt"></p> <a id="sogouconfirm" href="#" class="extconfirm">确 认</a><a id="sogoucancel" href="#" class="extconfirm">取 消</a></div></div><div id="ext_overlay" class="ext_overlayBG" style="display: nonez-index: 2147483646"></div><iframe class="sogou_sugg_feedbackquan" frameborder="0" scrolling="no" src="http://ht.www.sogou.com/websearch/features/yun6.jsp?pid=sogou-brse-d2a452edff079ca6&w=1366&v=7400&st=1465483516429&od=6612&ls=1465482970132&lc=&lk=1463925952631&sd=72&cd=0&kd=0&u=1450532590172818&y=EC8B5B0919EDD514D2F1263AA4A58EF6&query=html5%20canvas%E9%A6%96%E5%B1%8F%E8%87%AA%E9%80%82%E5%BA%94%E8%83%8C%E6%99%AF%E5%8A%A8%E7%94%BB%E5%BE%AA%E7%8E%AF%E6%95%88%E6%9E%9C%E4%BB%A3%E7%A0%81|http%3A%2F%2Fwww.777moban.com%2FPreview%2F35_196%2Findex.html&r=http%3A%2F%2Fwww.777moban.com%2FPreview%2F35_196%2Findex2.html" style="border: nonedisplay: nonez-index: 2147483645background: transparent"></iframe><script src="http://pb.sogou.com/pv.gif?hintbl=-1&uigs_productid=webext&type=ext_sugg&uigs_t=1465483517392&lt=212&ie=0&v=7400&y=EC8B5B0919EDD514D2F1263AA4A58EF6&query=html5%20canvas%E9%A6%96%E5%B1%8F%E8%87%AA%E9%80%82%E5%BA%94%E8%83%8C%E6%99%AF%E5%8A%A8%E7%94%BB%E5%BE%AA%E7%8E%AF%E6%95%88%E6%9E%9C%E4%BB%A3%E7%A0%81|http%3A%2F%2Fwww.777moban.com%2FPreview%2F35_196%2Findex.html"></script>

</body>

</html>

2、css样式如下:

article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:noneheight:0}[hidden]{display:none}html{font-family:sans-serif-ms-text-size-adjust:100%-webkit-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2emmargin:0.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-boxbox-sizing:content-boxheight:0}mark{background:#ff0color:#000}code,kbd,pre,samp{font-family:monospace,seriffont-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%line-height:0position:relativevertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid #c0c0c0margin:0 2pxpadding:0.35em 0.625em 0.75em}legend{border:0padding:0}button,input,select,textarea{font-family:inheritfont-size:100%margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:buttoncursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-boxpadding:0}input[type="search"]{-webkit-appearance:textfield-moz-box-sizing:content-box-webkit-box-sizing:content-boxbox-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0padding:0}textarea{overflow:autovertical-align:top}table{border-collapse:collapseborder-spacing:0}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11825731.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-19
下一篇2023-05-19

发表评论

登录后才能评论

评论列表(0条)

    保存