[Help] Hỏi về lập trình animation bằng html

Thảo luận trong 'Thư giãn' bắt đầu bởi BadPlayBoy, 1/2/17.

  1. BadPlayBoy

    BadPlayBoy Dante, the strongest Demon Slayer Lão Làng GVN

    Tham gia ngày:
    7/4/05
    Bài viết:
    14,041
    Xin lưu ý trước là tôi hoàn toàn không biết gì về lập trình, chỉ lên mạng copy mấy cái code về:
    Cụ thể là tôi có một cái sprite như thế này:
    [​IMG]
    Tôi muốn lập trình cho nó thành animation chạy trên web, nhưng không tìm thấy đoạn code dùng cho tấm ảnh gốc này, mà chỉ có code dùng cho ảnh cuộn từ trái qua phải, câu hỏi thứ nhất là phải dùng code gì để dùng luôn tấm ảnh gốc này mà không cần chỉnh sửa gì.

    Vì không tìm được nên thế tôi phải chuyển nó thành như thế này:
    [​IMG]
    Rồi copy trên mạng 1 đoạn code dài vcl thế này:
    (function() {

    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
    || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
    var currTime = new Date().getTime();
    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    var id = window.setTimeout(function() { callback(currTime + timeToCall); },
    timeToCall);
    lastTime = currTime + timeToCall;
    return id;
    };

    if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
    clearTimeout(id);
    };
    }());

    (function () {

    var coin,
    coinImage,
    canvas;

    function gameLoop () {

    window.requestAnimationFrame(gameLoop);

    coin.update();
    coin.render();
    }

    function sprite (options) {

    var that = {},
    frameIndex = 0,
    tickCount = 0,
    ticksPerFrame = options.ticksPerFrame || 0,
    numberOfFrames = options.numberOfFrames || 1;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;

    that.update = function () {

    tickCount += 1;

    if (tickCount > ticksPerFrame) {

    tickCount = 0;

    // If the current frame index is in range
    if (frameIndex < numberOfFrames - 1) {
    // Go to the next frame
    frameIndex += 1;
    } else {
    frameIndex = 0;
    }
    }
    };

    that.render = function () {

    // Clear the canvas
    that.context.clearRect(0, 0, that.width, that.height);

    // Draw the animation
    that.context.drawImage(
    that.image,
    frameIndex * that.width / numberOfFrames,
    0,
    that.width / numberOfFrames,
    that.height,
    0,
    0,
    that.width / numberOfFrames,
    that.height);
    };

    return that;
    }

    // Get canvas
    canvas = document.getElementById("animated");
    canvas.width = 154;
    canvas.height = 105;

    // Create sprite sheet
    coinImage = new Image();

    // Create sprite
    coin = sprite({
    context: canvas.getContext("2d"),
    width: 2309,
    height: 105,
    image: coinImage,
    numberOfFrames: 15,
    ticksPerFrame: 1 });

    // Load sprite sheet
    coinImage.addEventListener("load", gameLoop);
    coinImage.src = "images/001.PNG";

    } ());
    Câu hỏi thứ hai là đoạn trên có phần nào thừa bỏ đi được hay không, vì nhiều quá nhìn rối mắt vcl.
    Nhưng mà đoạn code trên kia chỉ có thể cuộn từ trái qua phải (1 row, nhiều column), có những sprite xếp theo chiều dọc (nhiều row, 1 column), câu hỏi thứ ba là nếu nó xếp theo chiều dọc thì phải làm thế nào?
    Câu hỏi cuối cùng là muốn xoay tấm hình 270 độ thì dùng code gì? Tìm trên mạng được đoạn này:
    var canvas = document.getElementById('animated');
    var context = canvas.getContext('2d');

    // translate context to center of canvas
    context.translate(canvas.width / 1000, canvas.height / 1);

    // rotate 270 degrees clockwise
    context.rotate(Math.PI*3/2);
    Thật ra code gốc nó là canvas.width / 2, canvas.height / 2 (vị trí center hay sao đó), tôi chỉnh sửa bậy bạ thành canvas.width / 1000, canvas.height / 1 cho nó phù hợp với tấm hình. Kết quả là xoay được nhưng mà nó lại bị chậm nếu dùng ảnh lớn.

    Mẫu sau khi hoàn thành (xoay 270 độ):
    html:
    <canvas id="animated" width="154" height="105"></canvas>
    <script src="./Animated_files/animated.js"></script>
    animated.js
    (function() {

    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
    || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
    var currTime = new Date().getTime();
    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    var id = window.setTimeout(function() { callback(currTime + timeToCall); },
    timeToCall);
    lastTime = currTime + timeToCall;
    return id;
    };

    if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
    clearTimeout(id);
    };
    }());

    (function () {

    var coin,
    coinImage,
    canvas;

    function gameLoop () {

    window.requestAnimationFrame(gameLoop);

    coin.update();
    coin.render();
    }

    function sprite (options) {

    var that = {},
    frameIndex = 0,
    tickCount = 0,
    ticksPerFrame = options.ticksPerFrame || 0,
    numberOfFrames = options.numberOfFrames || 1;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;

    that.update = function () {

    tickCount += 1;

    if (tickCount > ticksPerFrame) {

    tickCount = 0;

    // If the current frame index is in range
    if (frameIndex < numberOfFrames - 1) {
    // Go to the next frame
    frameIndex += 1;
    } else {
    frameIndex = 0;
    }
    }
    };

    that.render = function () {

    // Clear the canvas
    that.context.clearRect(0, 0, that.width, that.height);

    // Draw the animation
    that.context.drawImage(
    that.image,
    frameIndex * that.width / numberOfFrames,
    0,
    that.width / numberOfFrames,
    that.height,
    0,
    0,
    that.width / numberOfFrames,
    that.height);
    };

    return that;
    }

    // Get canvas
    canvas = document.getElementById("animated");
    canvas.width = 105;
    canvas.height = 154;

    var canvas = document.getElementById('animated');
    var context = canvas.getContext('2d');

    // translate context to center of canvas
    context.translate(canvas.width / 1000, canvas.height / 1);

    // rotate 270 degrees clockwise
    context.rotate(Math.PI*3/2);

    // Create sprite sheet
    coinImage = new Image();

    // Create sprite
    coin = sprite({
    context: canvas.getContext("2d"),
    width: 2309,
    height: 105,
    image: coinImage,
    numberOfFrames: 15,
    ticksPerFrame: 1 });

    // Load sprite sheet
    coinImage.addEventListener("load", gameLoop);
    coinImage.src = "http://i.imgur.com/YV2kdhZ.png";

    } ());
     
  2. asm65816

    asm65816 Mega Man

    Tham gia ngày:
    23/5/09
    Bài viết:
    3,320
    Nơi ở:
    El Sallia
    30 phút để nó chạy trên máy Snes :3
     
  3. hanhnn13

    hanhnn13 Mr & Ms Pac-Man

    Tham gia ngày:
    5/8/09
    Bài viết:
    235
    Chả hiểu
    Sao ko dùng gif?
     
  4. BadPlayBoy

    BadPlayBoy Dante, the strongest Demon Slayer Lão Làng GVN

    Tham gia ngày:
    7/4/05
    Bài viết:
    14,041
    Tức là khi tìm được nguồn sprite (có 3 dạng, một là xếp theo nhiều hàng nhiều cột, hai là xếp theo 1 hàng nhiều cột, ba là xếp theo nhiều hàng 1 cột), dùng html code thì chỉ cần down ảnh về, sửa sử kích thước trong source, sửa tên file, xong là có thể preview animation ngay lập tức (mất chưa đầy 1 phút). Còn nếu tạo ảnh gif thì phải down ảnh về, cắt ra thành từng ảnh nhỏ, ráp lại thành gif, sẽ mất rất nhiều thời gian trong khi không phải lúc nào cũng có sprite đẹp (nhiều khi nhìn sprite thấy được nhưng đến lúc tạo thành ảnh động mới thấy nó xấu). Ở đây tôi đang phải xử lý số lượng rất lớn, tới mấy ngàn ảnh, không thể ngồi tạo gif được. Đặc biệt nhất là với những ảnh kích thước lớn 600x800 mà chuyển thành gif thì sẽ rất nặng đồng thời chất lượng ảnh sẽ bị giảm, còn chạy trên html nó vẫn giữ nguyên chất lượng ảnh gốc.
     
  5. mashimuro

    mashimuro Glory to Mankind Lão Làng GVN

    Tham gia ngày:
    16/11/04
    Bài viết:
    21,313
    Làm biếng coi, để hiểu đoạn code làm gì thì trong function để chữ "debugger;" trước đoạn code đó, xong vào chrome bật trình duyệt bấm f12 rồi chạy, nó sẽ dừng ngay chỗ debugger rồi nghiền ngẫm :5cool_big_smile:
    Ta nghĩ cái chỗ nhiều row 1 column nó nằm ở đây

    và ở đây
     
    BadPlayBoy thích bài này.
  6. JinKaz

    JinKaz Youtube Master Race GameOver

    Tham gia ngày:
    13/11/16
    Bài viết:
    0
    Js này còn dễ đọc chán, ngâm tý là ra mà.
    Đọc js của bọn jap viết mới to đầu.
    Rảnh thì sẽ ngồi giúp, cơ mà méo rảnh :v
     
  7. silipden1102

    silipden1102 SỊP ở đây rồi Lão Làng GVN

    Tham gia ngày:
    2/4/09
    Bài viết:
    6,634
    Cái này ko thư giãn, vote tế !
     
  8. BadPlayBoy

    BadPlayBoy Dante, the strongest Demon Slayer Lão Làng GVN

    Tham gia ngày:
    7/4/05
    Bài viết:
    14,041
    Phần trên đ hiểu gì nhưng có vẻ là đ chỉnh sửa gì được.
    Còn cái dưới, width/height là kích thước file gốc. number of frame là số khung hình (15 hình nhỏ), ticksperframe là thời gian (ở đây là 1 tick chuyển 1 hình nhưng không rõ chính xác 1 tick là bao lâu).
    Tất nhiên cái đoạn code trên kia chỉ là ví dụ cho biết cái mục đích đang làm thôi, chứ không nhất thiết phải chỉnh sửa cái code đó là gì cả, nếu tự viết code mới thì sẽ dễ dàng hơn. Yêu cầu là 3 câu hỏi màu đỏ ấy.
    1) Chuyển animation từ sprite gốc mà không cần chỉnh sửa.
    [​IMG]
    2) Chuyển hướng cuộn sprite (từ trái qua phải, từ phải qua trái, từ trên xuống dưới, từ dưới lên trên).
    [​IMG]
    3) Lật hình, vì một số sprite nó để nằm ngang nên phải lật cho nó đứng lên.
    [​IMG]
    Như cái clip này nó viết code rất đơn giản (xem từ 9:50), chỉ có vài chục dòng thôi, nhưng mà do đ có kiến thức lập trình nên đ hiểu nó nói gì cả, còn viết lại y chang nó thì không hoạt động (có thể do tự gõ nên gõ sai).
     
    Chỉnh sửa cuối: 1/2/17
  9. quadan

    quadan The Legend of Zelda Lão Làng GVN

    Tham gia ngày:
    1/8/09
    Bài viết:
    4,143
    BadPlayBoy thích bài này.
  10. BadPlayBoy

    BadPlayBoy Dante, the strongest Demon Slayer Lão Làng GVN

    Tham gia ngày:
    7/4/05
    Bài viết:
    14,041
    Tranh thủ vừa làm vừa học luôn mà, chứ cái gì cũng nhờ plugin hỗ trợ thì cuối cùng chẳng biết gì cả. Ngoài ra còn có một số kiểu sprite nó tách nhiều phần, có thể dùng code để ráp lại, cái này chắc plugin không làm được (hoặc phải có programer lập trình cái plugin đó). Ví dụ:
    [​IMG]
    Nhưng mà cái này có vẻ khó nên để sau tính.
     
  11. haiduong87

    haiduong87 Κράτος - Ragnarok Lão Làng GVN

    Tham gia ngày:
    20/5/04
    Bài viết:
    24,355
    Nơi ở:
    TP HCM
    xem thử sticker của tụi fb nhé
     
  12. haiduong87

    haiduong87 Κράτος - Ragnarok Lão Làng GVN

    Tham gia ngày:
    20/5/04
    Bài viết:
    24,355
    Nơi ở:
    TP HCM
    thấy nó chỉ chạy timer thay background position là xong
    [​IMG]
     
  13. trần_hà_anh

    trần_hà_anh Tàu ngầm Lão Làng GameVN Lão Làng GVN

    Tham gia ngày:
    18/1/07
    Bài viết:
    363
    code trong clip kia chạy được ok mà , chắc chủ thớt chưa thay thông số ảnh của mình vào.
    Chỉ cần thay dòng thứ 10 thành: row = 5; col = 3;
    dòng 21 thành: ctx.drawImage(sprite,sX, sY, w, h, 154,106, w*2, h*2);
    là chạy ngon.
     
  14. mashimuro

    mashimuro Glory to Mankind Lão Làng GVN

    Tham gia ngày:
    16/11/04
    Bài viết:
    21,313
    Sửa được hết, ta chỉ gợi ý, mi từ từ nghiên cứu. Mấy cái đó cộng trừ nhân chia thôi, đọc kỹ mấy cái biến là biết nó đang làm gì.
     
  15. ren_momo

    ren_momo Mayor of SimCity Lão Làng GVN

    Tham gia ngày:
    19/8/08
    Bài viết:
    4,043
    Nơi ở:
    CLGT?
    Có nhiều cách, hình có thể dùng css webkit animation để làm gif, code kia nhìn ngu học quá bỏ đi dùm =))
     
  16. BadPlayBoy

    BadPlayBoy Dante, the strongest Demon Slayer Lão Làng GVN

    Tham gia ngày:
    7/4/05
    Bài viết:
    14,041
    Có thay mà không chạy, sợ lúc gõ code sai chính tả thôi: :2cool_sad:
    [​IMG]

    Đ có tí kiến thức gì về lập trình thì đọc hiểu rồi sửa mấy cái đó bằng niềm tin à? :9cool_too_sad:
     
  17. trần_hà_anh

    trần_hà_anh Tàu ngầm Lão Làng GameVN Lão Làng GVN

    Tham gia ngày:
    18/1/07
    Bài viết:
    363
    oạch, ở dưới bác chưa tạo thằng canvas kìa
    nhét đoạn sau vào giữa </head></html>

    <body onload='init()'>
    <canvas id='animated' width='500' height='500'></canvas>
    </body>

    hình như bác chưa có kiến thức cơ bản về html, js với css thì phải? Chưa học bò đã lo học chạy thế thì sao học được '@^@|||:-ss
     
  18. hgvuttcl

    hgvuttcl The Pride of Hiigara Lão Làng GVN

    Tham gia ngày:
    11/12/13
    Bài viết:
    9,238
    Hồi trước cũng tính copy mấy cái emo động này về forum, inspect mới thấy nó nguyên 1 đống thế này, bối rối vl. =))
     
    haiduong87 thích bài này.
  19. mashimuro

    mashimuro Glory to Mankind Lão Làng GVN

    Tham gia ngày:
    16/11/04
    Bài viết:
    21,313
    Ta đang hướng dẫn mi mà, có thằng nào sinh ra đã có kiến thức sẵn, cũng tập tọe từng dòng code mà biết thôi :5cool_ops:
     
  20. Mr.(Easy)

    Mr.(Easy) Mr & Ms Pac-Man

    Tham gia ngày:
    17/1/09
    Bài viết:
    129
    ông dùng chrome đi nhìn debug sẽ dễ hơn :v
    P/s: còn code không chạy do ông dùng trình duyệt thấp quá, k xài đc html5
     

Chia sẻ trang này